Arc Forumnew | comments | leaders | submitlogin
2 points by rocketnia 3145 days ago | link | parent

Very nice! I have a few bits of feedback in no particular order. ^_^

   function join () {
       var args = list.apply (this, arguments);
       if (no (args)) {
           return nil; }
       else {
  -        (function (a) {
  +        return (function (a) {
               if (no (a)) {
  -                join.apply (this, listarray (cdr (args))); }
  +                return join.apply (this, listarray (cdr (args))); }
  -            else { return cons (car (a), join.apply (this, listarray (cdr (a)), listarray (cdr (args)))); }
  +            else { return cons (car (a), join.apply (this, [ cdr (a) ].concat (listarray (cdr (args))))); }
           }) (car (args)); }}
(I think I prefer the other version of this, though. For one thing, it uses constant stack space.)

Also, note that if you're going to define your own version of falsity (no()), then the JavaScript && and || aren't necessarily going to play along with that. They'll treat "" as false, for instance.

Speaking of which, it seems weird to me that you'd have 'if expand to a statement like this:

  arc> (js '(if a b c d e))
  if(a)b;else if(c)d;else e;
You can have it expand to an expression instead, bringing it closer to the Arc version's functionality:

  (function(){
    if(isnt(nil,a))return b;if(isnt(nil,c))return d;return e;})()
  or simply
  (isnt(nil,a)?b:isnt(nil,c)?d:e)
On another note, it would be nifty if you could use Arc macros (or even functions, with an Arc hack to put enough metadata on them) in the s-expressions sent to the compiler. But since the namespace seen by the (js ...) Arc isn't nearly the same as the namespace seen by the raw Arc, it seems like the sort of undertaking that would completely change the structure of the code.

...but issues with nested strings and dot ssyntax keep this from being possible at the moment.

Well, the Scheme reader is going to parse (a (b c).d) as a three-element list the same way as it parses (a (b c) .d). I'm not even sure what kind of type we might expect '(b c).d to be. Nevertheless, I agree it ought to work. :-p

As far as nested strings go, could you elaborate on that?



2 points by akkartik 3144 days ago | link

"it would be nifty if you could use Arc macros (or even functions, with an Arc hack to put enough metadata on them) in the s-expressions sent to the compiler."

I had the same reaction.

"But since the namespace seen by the (js ...) Arc isn't nearly the same as the namespace seen by the raw Arc, it seems like the sort of undertaking that would completely change the structure of the code."

Perhaps I'm missing something. I imagine you could implement a macro, say jsdef, to store translation functions in a table and then replace (def js-fn..) with (jsdef fn..). js would then replace keywords in car position with functions before eval-ing the whole shebang. This way you wouldn't need to update js everytime you want to implement a new arc function in js. You'd also be able to avoid quoting when you don't need backquotes.

Hmm, perhaps this runs into a similar problem to my yrc (http://arclanguage.org/item?id=11880) -- since you're doing keyword replace, is there a scenario where the keyword won't show up until after the replace step? My mind is getting bent out of shape thinking about this.

"Very nice!"

Seconded!

-----

1 point by rocketnia 3144 days ago | link

Yeah, I think essentially you could compile Arc to JavaScript approximately the same way it's compiled to Scheme. The issue I was referring to when I was talking about "the namespace[s]" is that a function may be defined in Arc proper but not in js.arc, or conversely, a function may exist on the JavaScript side (like alert()) that has no analogue in Arc. Either the library has to manage that or the programmer does, and it seems like the kind of thing a library should do.

...

Whoa, I'm now realizing just how especially intriguing this is to me; I've been getting into the thick of working on namespace organization for Blade, and this is really relevant for that. How might one go about having a language where programs may have access to significantly different core functionality depending on how they're compiled... but where it could be swapped out for a substitute implementation on a mismatched platform...

Oooh, a whole JavaScript primitive operation suite (indexing, +, -, *, certain global variables, JSON syntax, new, and so forth) could come in a parameter. When you call a 'jsdef function in Arc, the JS-runtime parameter can be obtained from some dynamic binding or global variable, and when you compile a 'jsdef function to JavaScript, references to that parameter can be given special treatment by the compiler. As for as Arc primitive operations, the Arc-to-JS compiler may be able to detect uses of those operations and translate them so they refer to some JavaScript-side global variable(s) defined in arc.js. I think this could work. ^_^

It isn't especially novel, I suppose, 'cause it still boils down to special-casing in the compiler, but at least it's limited to special-casing the JS-runtime parameter, which is part of the library itself.

To go on, I'm thinking that the primitive operations would be treated as faithfully as possible rather than approximated by similar operations in the other language. For instance, Arc numbers would be annotated strings or something in JavaScript, rather than being demoted to the width of a JavaScript number, and Arc + may throw an error in JavaScript if a bignum arithmetic library is unavailable. More language-lenient utilities can be built up on top of those. If it's annoying to come up with names for those because they clash with all the Arc-native names, well, that could indeed be a problem....

Thoughts?

-----

1 point by evanrmurphy 3145 days ago | link

Thank you for the feedback and for fixing 'join! ^_^

> Also, note that if you're going to define your own version of falsity (no()), then the JavaScript && and || aren't necessarily going to play along with that. They'll treat "" as false, for instance.

Glad you pointed this out, may save me some debugging time. :)

Speaking of creating new structures vs. using built-in ones, I have considered switching to fake conses. That is, instead of there being a separate cons object as there is now, cons, car, cdr etc. would be array manipulations that make JavaScript arrays act just (or almost) like Arc lists. Do you have an opinion on this?

Re: 'if, the current version might seem more intuitive to a JavaScripter, but your approach may be more consistent with the way I'm expanding 'do. And then there's your point, that the latter has a close 1-to-1 correspondence of expressions with Arc while the former breaks up an expression into several statements. (Is this what you meant, or have I misunderstood?)

> As far as nested strings go, could you elaborate on that?

In the first Arc Challenge attempt I posted is the line,

  (+ |\'you said: \'| foo.value)))))
The |\'you said: \'| from that is manual string escaping I'm doing because 'js naively compiles "you said: " to 'you said: ' without considering the need for backslashes. I think it's important to be able to have JavaScript within HTML within JavaScript within HTML within ... within JavaScript, and I'm not sure it's a particularly difficult string escaping problem - I just haven't gotten it working yet.

-----

2 points by rocketnia 3144 days ago | link

...array manipulations that make JavaScript arrays act just (or almost) like Arc lists. Do you have an opinion on this?

Well, to have cons produce an JavaScript array would be a bit odd. What happens to improper lists? (Well, Arc chokes on improper lists all the time, so maybe it doesn't matter. :-p )

I think it could be a good long-term idea to support both JavaScript arrays and the Arc cons type you already have. Functions like 'all, 'map, and 'join could work for both kinds of lists, and this way people wouldn't necessarily have to change the way they're using conses, and they could work closer to the metal (or whatever JS is ^_^ ) when that was more useful.

...the latter has a close 1-to-1 correspondence of expressions with Arc while the former breaks up an expression into several statements. (Is this what you meant, or have I misunderstood?)

I'm mostly just concerned that you should be able to say things like (let x (if (< foo 2) 0 foo) (* x x)). If (if ...) translates to a statement, that won't work.

|\'you said: \'|

Oh, I see now.

Yeah, the string escaping shouldn't be that difficult. I suppose the trickiest part about string escaping is remembering to do it. ^_^

-----