Monday, May 19, 2008

A Groovy-like Syntax for Scheme

In the last few years, I started 3 unfinished projects...

(1) Analyze the 20,000 most common CJK tokens in Unicode, aiming to make them easier for Westerners to use in programs. I've realized they're far more complex than I first thought. The data's entered and the scripts written, but I haven't finished it because there'd be too many special cases and loose ends, just like the existing IME's.

(2) Document the Groovy Language so non-Java programmers can learn it easily. I've realized the Java libraries are quite complex, and a dynamic language on top of it, while easy for existing Java programmers, may be more difficult to learn than Python or Ruby for non-Java programmers.

(3) Write an alternative lexer/parser for the Groovy AST. First, I used JParsec, then my own combinator parsing library. I've grasped the power of closures quite well, but this programming task showed me how powerful syntactic macros would be. I've since been learning Scheme with the aim of seeing how a language for the Groovy AST could support such macros.

Although Scheme is powerful, the parentheses make it quite hard to read. Reading Groovy is easy for Java programmers, but learning to read Scheme is easy for no-one, though given enough practice I'm sure it would become easy. So I'm experimenting with giving Scheme a Groovy-like syntax, called "Ghreme".


Ghreme Syntax

Some of the syntactic features we'd need...

(1) Infix notation. Instead of:
  (+ 3 4 (/ 15 3))
we'd write:
  3 + 4 + (15 / 3)

(2) Method names outside the parentheses. Instead of:
  (print "abcdefg")
we'd write:
  print("abcdefg")

(3) The first parameter of a function to be written as an object. Why not when Groovy has multimethods? Instead of:
  (seq (alt (some (match 'a')) (seq (match 'b') (maybe (match 'c'))))
    (many (match 'd')))
we'd write:
  alt(match('a').some(),
      match('b').seq(match('c').maybe()) ).
  seq(match('d').many())

(4) Simpler notation for lists and maps. Instead of:
  '("a" 2 "c")
we'd write:
  ['a', 2, 'c']

(5) Simpler notation for Lambda functions. Instead of:
  (lambda (a b) (display (+ a b)) (newline))
we'd write:
  {a,b-> display(a + b); newline() }

After creating Ghreme, I hope I'll understand syntactic macros enough to bring them to Groovy via Grerl-Vy. Assuming I'm not blinded by Eric's light and start evangelizing Ghreme to Groovy developers.

P.S. Because my blog's now about more than Groovy, I'm shifting the "Groovy" in its name to its rightful place.

No comments: