Jesscheme, or "Jess"

@markm made the case to me that rather than reimplementing all the stuff that the Agoric folks are doing in scheme, that I should make some scheme-like syntax that transforms into a valid Jessie program. Ok, let’s think about it. (I’m not committing quite yet!)

I was calling this “Jesscheme” but that’s really a mouthful. Since it would have more elegant syntax, maybe a shorter name is acceptable, so I’ll call it “Jess” for now.

  • What to do about symbols? Most lispy hackers will expect them, and that two symbols that “look” the same are the same according to eq? (ie, they share the same pointer). I see that Javascript has Symbols, but Jessie does not provide them, presumably because Javascript does not provide eq? shared uniqueness, and there is no global registry for them (which needs a weakmap). It’s not obvious that there would be a place to coordinate them in Jessie.
  • Mutable by default stuff everywhere still seems to exist in Jessie? It would be nice if we had some clojure-like immutable primitives, but I suppose these could be added later.
  • No tail call elimination, right? I think that Javascript land considered this at some point but it hasn’t been added. This is a major expectation for most lisp’y devs, but I suppose most Clojure folks have managed to get along without it. Could be added possibly by a trampoline but that is highly undesirable and does not result in a “clean mapping” from Jess -> Jessie.
  • Macros are not actually too high of priority initially, but eventually will be wanted (it’s part of the appeal of the syntax). I know @markm pointed me at his ideas for doubly hygenic macros.
  • However, how on earth are macros exported from a module? What about between a Jess -> Jessie -> Jess passing of modules?
  • How should hashmaps be represented? Probably even though a major diversion from scheme syntax, having special curly syntax is worth it.

Just some thoughts for now.

1 Like

It could be that a reasonable start would be to go with https://gozala.io/wisp/ and pair it down from there.

I don’t have a lot to add… you’re mostly on territory that is unfamiliar to me, but here are some thoughts:

  • The symbol implementation can be exported from a module that is importable by the runtime (i.e. as non-Jessie code that Jess rewritten to Jessie can import). Jessie can use weakmaps constructed by the makeWeakMap() helper (which I also intend to provide as an export from, say, @agoric/jessie), but you don’t have to be constrained to the Jessie subset when writing system-level code that would be implemented by the Jessie interpreter (or non-Jessie javascript).
  • Readonly collections are going to be proposed to TC39. Perhaps that would fit your need for immutable primitives?
  • I feel your pain with lack of tail-call optimisation. You’re right, there’s not a convenient way to work around this.
  • Macros could be implemented as plain functions that are registered with a weakmap that allows the rewriter to activate their macro powers when used within Jess, but otherwise isn’t really usable from Jessie (except to pass them to other Jess modules).
  • I agree that curly syntax is probably worth it: perhaps Python rules could be used (i.e. don’t automatically stringify hash keys in the concise syntax, instead require quoting or evaluation of hash keys)?

I’m glad you’re considering this! IMO, the Jessie subset is one that would feel especially comfortable to Scheme/Lisp folks (moreso than Javascript proper), once the impedance mismatches are resolved.