zepto icon indicating copy to clipboard operation
zepto copied to clipboard

RFC: Module definition language

Open hellerve opened this issue 8 years ago • 6 comments

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

hellerve avatar Nov 21 '16 17:11 hellerve

A reference implementation can be found in zepto-lang/module#1.

hellerve avatar Nov 21 '16 17:11 hellerve

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)

Tobsic avatar Nov 22 '16 07:11 Tobsic

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.

hellerve avatar Nov 22 '16 07:11 hellerve

True, the first one is easier to read.

Tobsic avatar Nov 22 '16 07:11 Tobsic

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?

4www avatar Nov 22 '16 14:11 4www

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.

hellerve avatar Nov 22 '16 14:11 hellerve