Arc Forumnew | comments | leaders | submitlogin
2 points by evanrmurphy 5221 days ago | link | parent

> (((((a!b 4) 'c) 'd) 'e) 'f) is currently compiling to:

  get('f')(get('e')(get('d')(get('c')(get(4)(get('b')(a))))));
I wrestled with this disambiguation problem for some time and finally settled (for now ;) on a simple inference system based on the most common use cases. The algorithm is:

1. If the form has a single quoted arg, as in (x 'y), it's compiled to x['y']. This allows object access chains like document!body!innerHTML to be compiled correctly by default.

2. If the form has 0 or 2+ args, or 1 arg that isn't quoted, then it's considered a function call:

  (x) => x()
  (x y) => x(y)
  (x y z) => x(y,z)
I'm still looking into the least kludgy way to pass a single quoted arg to a function. Here are some options:

  (x "y")
  (x `y)        ; quasiquote isn't currently used for anything else
  (x 'y nil)    ; the function can just ignore the nil arg
  (fncall x 'y)


2 points by rocketnia 5221 days ago | link

What about something like this?

  callget!y.x
I don't know. If it comes up often enough, I think I'd rather have a special (fncall x 'y) ssyntax. Maybe x!y could expand to (fncall x 'y) and x.`y could expand to (x 'y).

-----

1 point by evanrmurphy 5220 days ago | link

I had assumed that since x.'y was read as two distinct symbols, x.`y would be too, but it's not the case:

  arc> 'x.'y
  x.
  arc> y   ; still evaluating previous expr
  arc> 'x.`y
  |x.`y|
Any idea why these are treated differently? Whatever the reason, it means I can use x.`y without hacking the reader. So, thanks for pointing this out to me! ^_^

I'm currently torn about whether to do

  x!y => (x 'y) => (fncall x 'y) => x('y')
  x.`y => (x `y) => (objref x 'y) => x['y']
as you suggested, or the reverse. Leaning toward your way so that functions are totally normal and objects special, rather than having functions with a single quoted arg be some exception.

-----

1 point by evanrmurphy 5219 days ago | link

So I went ahead and implemented it your way. ^_^ For an example of it in action, check out the following from the Hello JQuery tutorial at http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery:

  $(document).ready(function() {
     $("a").click(function() {
       alert("Hello world!");
     });
   });
To reproduce this now using my arc-to-js compiler:

  ($.document.`ready (fn ()
    ($!a.`click (fn ()
      (alert "Hello world!")))))
"write much less, do more" ^_^

This example works particularly well because the $("a") jQuery selector can be compiled from $!a. A challenge arises with more complex selectors, as in this snippet from the Find Me: Using Selectors and Events tutorial:

  $(document).ready(function() {
     $("#orderedlist").addClass("red");
   });
Since $("#ordered list") has the special character #, we're unable to compile it from $!#orderedlist. Either most of the ssyntax has to be sacrificed for parens, as in

  ($.document.`ready (fn ()
    ((($ "#orderedlist") `addClass) "red")))
or Arc's get ssyntax must be used:

  ($.document.`ready (fn ()
    (.`addClass!red ($ "#orderedlist"))))
I hope to post updated source for js.arc and arc.js soon so that people who are interested can start trying out the compiler.

-----

1 point by evanrmurphy 5217 days ago | link

Does anyone know why the reader interprets x.'y as two symbols but x.`y as only one?

-----

2 points by fallintothis 5217 days ago | link

Not quite sure (I suspect it's a bug), but it seems like it has to do with the implementation of make-readtable (which brackets.scm uses).

  $ mzscheme
  Welcome to MzScheme v4.2.1 [3m], Copyright (c) 2004-2009 PLT Scheme Inc.
  > (parameterize ((current-readtable #f)) (read))
  x`y ; read in as two items
  x
  > y
  > (parameterize ((current-readtable (make-readtable #f))) (read))
  x`y ; read in as one symbol
  |x`y|
For braver people than me, you might check the source at http://github.com/plt/racket/blob/master/src/racket/src/read....

-----