Arc Forumnew | comments | leaders | submitlogin
1 point by evanrmurphy 3110 days ago | link | parent

infix is my favorite. Unfortunately, it has been the hardest to implement as well. ^_^ (Maybe I'm just going about it the wrong way.) Implementing the other options, however, was quick and painless.

pedantic prefix is the more technically correct prefix option, but it's so cumbersome to read and write that I've pretty much ruled it out already.

prefix gets you fewer parens and dots than its pedantic counterpart, but its grouping misleads by suggesting that "foo" is passed to a function getElementById. ("foo" is really passed to a function document.getElementById.)

infix-prefix hybrid corrects the grouping problem prefix has, but it's kludgy to have the two different forms of dot notation mixed together.

2 points by rocketnia 3110 days ago | link

("foo" is really passed to a function document.getElementById.)

Right... but I wonder if you understand what I understand by that. If you allow for (document.getElementById "foo"), then document.getElementById will need to have a different meaning in functional position than in non-functional position, just like "foo.x()" and "(true && foo.x)()" have different meanings in JavaScript. (The first one uses foo as this in x, and the second one uses the window or whatever as this. The "foo.x()" form amounts to one syntax, even though the "foo.x" part can be wrapped in grouping parentheses without changing the meaning.)

The only example you give that doesn't require this kind of treatment, and in that way is the least misleading, is prefix, 'cause the \. form could be a simple macro.

On the other hand, the treatment isn't especially outlandish, 'cause Arc does the same thing; (a:b c) is different from ((and t a:b) c), thanks to the fact that a (compose ...) form is given special treatment in functional position (where it's the head of a metafn call). So with the right programmer-bewares in your documentation, you could use all-new ssyntax and metafn rules and mimic JavaScript's quirky invocation in a way that still works somewhat like Arc.

With that approach in mind, selected parts of the expansion might go like this (except probably depth-first, rather than breadth-first):

  (= document.body.innerHTML (.value:document.getElementById "foo"))
  ...expanding the : ssyntax...
  (= document.body.innerHTML
     ((compose .value document.getElementById) "foo"))
  ...expanding the compose metafn...
  (= document.body.innerHTML (.value (document.getElementById "foo")))
  ...expanding the . ssyntaxes...
  (= (jsindex (jsindex document "body") "innerHTML")
     ((jsget "value") ((jsindex document "getElementById") "foo")))
  ...expanding the jsget and jsindex metafns...
  (= (jsindex (jsindex document "body") "innerHTML")
     (jsindex (jscall document "getElementById" "foo") "value"))
Note that Arc's 'get doesn't expand as a metafn that way; 'get only gets special treatment in setforms. Here, I've treated 'jsget so that "foo.a(1).b(2).c(3)" can be expressed as ((.c ((.b (foo.a 1)) 2)) 3), as opposed to something even more ridiculous. (Er, but (jscall (jscall (foo.a 1) "b" 2) "c" 3) is more readable IMO, and sooner or later you'll probably want to define a macro for (dots foo (a 1) (b 2) (c 3)) like the prefix option anyway, so maybe the whole 'jsget issue is pointless. :-p )

So yeah, I hope these complications help show you the way. If they lead you screaming in another direction, that's progress too, eh? ^_^