zepto
zepto copied to clipboard
RFC: Module definition language
Writing modules is an essential part of organizing zepto code. However, modules soon get cluttered.
This RFC proposes a language for structuring modules by files. I believe it is best if we look at the old way of defining modules and a proposed syntactic alternative side by side.
(module "example"
(export
`("exp-fn" fn)
`("fn2" fn2))
(internal (lambda (x) (write x)))
(fn (lambda (x) (internal x)))
(fn2 (lambda () (internal 1))))
This is fairly contrived, but relatively simple. It defined three functions internal
, fn
, and fn2
and exports the latter two as exp-fn
and fn2
, respectively.
Leveraging the proposed language, that action would look like this:
#lang module example
(export
fn2
[fn :as exp-fn])
(define (internal x)
(write x))
; or even: (define internal write)
(define (fn x)
(internal x))
; or even: (define fn internal)
(define (fn2)
(internal 1))
; or even: (define fn2 (curry internal 1))
To me, that looks cleaner, simpler, and less cluttered. It also has the advantage that module extension could be simplified by detecting at load time whether the module should be created or extended instead of doing it explicitly through module-extend
.
The syntax can be toyed around with and changed until we reach consensus reality.
Cheers
A reference implementation can be found in zepto-lang/module#1.
To me it looks good. Is it also possible to remove the list brackets around the export as? so you could write
(export
fn2
fn :as exp-fn)
or is that not enough connected syntax? (not sure)
We could do that, but I am not sure whether it's not a bit cluttered. Imagine someone is malicious and does not use linebreaks between the exports:
(export fn fn1 [fn2 :as exp-fn2] fn3 [fn4 :as exp-fn4])
; vs
(export fn fn1 fn2 :as exp-fn2 fn3 fn4 :as exp-fn4)
I would argue the one above is more readable.
As per your question: all of the syntax proposed is completely arbitrary and can be changed on a whim should someone have a better idea.
True, the first one is easier to read.
What's this syntax from :as
? Where does the :
comes from? And is the as
explicit wording used somewhere else?
(export fn fn1 fn2:exp-fn2 fn3 fn4:exp-fn4)
(export
fn2
fn:exp-fn)
Also, why the module
in: #lang module exemple
?
Can it be something else than a module?
Yes, there is a wide array of languages. This is zepto's version of the reader macro pattern, except it's not really a macro. But basically you can hook into the reader and define your own language in front of zepto.
The problem with the colon is that it is ambiguous, as colon is a valid character in a zepto identifier. In fact, modules are prefixed with it (e.g. string:split
or list:join
). I also think it does not lend itself well to readability.