1. 6
  1.  

  2. 3

    Arc was arguably “Scheme, but with a quasiquoted macro system.” Which is still a very good idea. I wish Racket wouldn’t be so heavy-handed with syntax transformers. But the rigidity has some nice benefits, like Racket’s interactive macro expansion system.

    It’s interesting to diff the evaluation model of Scheme against other dialects of Lisp. I think Scheme got it right with a single shared namespace for both functions and variables, but in Emacs Lisp it’s sort of nice to be able to name a function and a variable the same thing. After all, you usually want to write functionality directly related to the state that it’s manipulating, so it’s a natural fit.

    I managed to port Arc to JS: https://github.com/lumen-language/lumen/blob/f7bfd4dca71ed1e4eb380e7e819a302825d37936/arc.l#L2234-L2245

    The code is mostly a copy-paste from the original arc3.1 sources. It’s kind of amusing to open it in a separate tab and flip between them. https://github.com/arclanguage/anarki/blob/f01d3f9c661eed05511711a0f3388ca2a1d34fa2/news.arc#L400-L411

    In general, Scheme is really easy to implement, especially compared to CL and Elisp. I once wrote a scheme macro in elisp with a couple hours of effort.

    One trouble is that it’s hard to find good, production-grade, quality Lisp codebases. They exist, but you have to go digging for them. Abuse (a game engine) comes to mind: http://abuse.zoy.org/browser/abuse/trunk/data/lisp

    You can also add type inference with relatively little effort, which is just delightful. https://web.archive.org/web/20070610012057/http://www.cs.indiana.edu/classes/c311/

    https://web.archive.org/web/20070615124421fw_/http://www.cs.indiana.edu/classes/c311/a10.html

    (I’ve been studying that for a few weeks off and on and still don’t quite grok it, but that’s only due to my deficiencies rather than lisp’s.)

    1. 1

      Arc was arguably “Scheme, but with a quasiquoted macro system.” Which is still a very good idea. I wish Racket wouldn’t be so heavy-handed with syntax transformers. But the rigidity has some nice benefits, like Racket’s interactive macro expansion system.

      I am not familiar with the different flavors of macro systems (I am still learning Scheme’s); can you elaborate on the difference? By “heavy-handed” do you mean Racket’s macro system is too flexible or too inflexible?

      1. 1

        Whoa, I missed this reply. Sorry!

        Yes, Racket’s macro system is… well, you can do a lot with it, if you’re very smart and you have a lot of time.

        For example, here’s xdef from arc3.2, written in scheme: https://github.com/shawwn/arc3.2/blob/788c41f274116b276206475e521853d22657e195/ac.scm#L573-L579

        (define-syntax xdef
          (syntax-rules ()
            ((xxdef a b)
             (let ((nm (ac-global-name 'a))
                   (a b))
               (namespace-set-variable-value! nm a)
               a))))
        

        Here it is in Lumen:

        (define-macro xdef (name value)
          (let-unique (nm)
            `(with ,nm (ac-global-name ',name)
               (namespace-set-variable-value! ,nm ,value))))
        

        There are a few reasons Scheme-style is longer (all of them valid), but there are effective techniques for sidestepping the problems that Scheme tries to address. Arc uses those techniques well.

        I wrote that xdef macro in Lumen’s interactive docs, if you want to play with it:

        https://docs.ycombinator.lol/tutorial/macros