Arc Forumnew | comments | leaders | submitlogin
Technical Comments on Arc
13 points by fractal 6118 days ago | 9 comments
Hi Paul,

Thanks so much for making Arc available. Along with many others, I have been waiting for this for years. I already prefer Arc over Scheme, even just for its sane booleans. However (and I'm sure you're aware of this), you have a long, very steep climb ahead of you if you want to approach Common Lisp in terms of specification and implementation.

Some concerns:

* I think your let/with will make certain important special cases longer and more cumbersome. Compare:

  CL> (let (a b c)
        ...)
vs

  arc> (with (a nil b nil c nil)
         ...)
Or, even worse:

  CL> `(let ,vars
         ...)
vs

  arc> `(with ,(apply + (map [list _ nil] vars))
          ...)
A possible solution is to have another form, say cl-let. Or (my preference) use CL's let and drop your let/with.

* It seems there is no way to create dynamic bindings. Is this true? All variables seem to be lexical:

  arc> (= tp 'global)
  global
  arc> (= tp2 (let tp 'local
                (fn () tp)))
  #<procedure: tp2>
  arc> (tp2)
  local
Will this valuable feature (dynamic scope) ever be available? If not, is there any reason to append s to global variable names, or is this now an onion? Common Lisp does-this* to remind programmers that the symbol is intended to be used to establish dynamic instead of lexical bindings. All Arc bindings seem to be lexical so I don't see what useful information the earmuffs (I guess half-earmuffs) convey.

* Efficiency. I'm particularly concerned about the efficiency of the combination of generalised variables and Arc's function-position access of sequences, etc. Take this example:

  arc> (def set-0th-element-in-this-vector (q)
         (= (q 0) 9876)) ; If only I could tell
                         ; Arc to assume q is
                         ; a vector. It could
                         ; even open-code it.
vs

  CL> (defun set-an-element-in-a-vector (q)
        (setf (aref q 0) 9876))
From what I can tell, there is no way to avoid type dispatching. This function needs to consider that q can be a hashtable, vector, string, whatever. Of course, lisp does type dispatching all over the place, but assignment seems to me to be a particularly important area to optimise. It isn't clear to me how much type inference will help here either.

* On that note, where are declarations?!

* Where is macrolet?!

* Documentation. As Kenny said in another post, many of the macros are opaquely terse. The only way to currently find out what they do is to read the uncommented code. Docstrings? Describe?

* If you have to have call/cc, please ensure it is possible to implement a non-broken unwind-protect:

http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuations-frame.html

* Where are CL's , ++, /, etc REPL variables? Obviously in a lisp-1 like Arc they will need to be renamed, but I use them all the time and would use them even if they had longish names. Or you could make Arc a lisp-2 -- see next.

Things I very strongly disagree with:

Lisp-1. IMO, lisp isn't best suited to a functional style. This is one of the many lies that Schemers (and apparently Arcers) tell themselves. Make Arc a lisp-2.

* Renaming setf to =. It's just confusing. I suggest ! (roots in Forth and Scheme) or possibly $ (looks like an "S", short for setf).

* No format or loop. These are very useful DSLs missing from Arc.

* Arc compiles to Scheme. It should compile to Common Lisp.

Things I very strongly agree with:

* Arc's if.

* Designing with brevity in mind. I like most of the renaming.

* Dropping CL pathnames. Unix won.

Overall, except for the points above, I think the design is very sensible and well considered. Maybe in a hundred years or so I'll switch from Common Lisp. :)

I for one welcome another lisp. Thank you for sharing your ideas with us and don't let the critics mash you up. Making snippy, contentless comments is easy, coding isn't.

Best wishes to you and to Arc,

Doug Hoyte http://hcsw.org



4 points by randallsquared 6118 days ago | link

Arc does have protect, but I'll leave it to more experienced lispers to tell us if it interacts well with ccc.

It seems to me that format and loop are two of the top 5 worst things about CL, and I can't see any reason why even those who like them would need them in the base language.

-----

4 points by mst 6118 days ago | link

Personally, lisp-2-ness is the thing I most despise about CL - and I'd note that it was originally an implementation detail that seriously consideration was given to changing, stopped primarily by the "but everybody's already implemented it" principle that arc's current refusal of backcompat is designed to avoid.

I do see your point re (with (a nil b nil c nil) but I don't really see why this justifies more than a (with-nil (a b c) macro.

-----

1 point by fab13n 6116 days ago | link

> lisp-2-ness is the thing I most despise about CL

It's conceptually ugly, but that's what makes non-hygienic macros usable.

A macro which uses a global variable is broken when used in a context which shadows this variable; if functions are not "normal" globals, there is much less chances that you'll shadow them accidentally.

-----

4 points by vsingh 6118 days ago | link

"Where is macrolet?!"

Arc has first-class macros.

-----

1 point by wchogg 6117 days ago | link

First class? Really? As in I can pass in a macro anywhere I can pass in a function?

-----

2 points by ryantmulligan 6118 days ago | link

I don't see what your argument is against setf being =, Except to maintain some compatibility with CL, which PG already said was not his intent with Arc.

-----

4 points by gugamilare 6116 days ago | link

I agree with him. The symbol = means "equality", not "definition". This convension is a bad thing the languages have learned from C (or any older one). The = could be a function to test equality of numbers (maybe for speed improvement) or even instead of "is". The name "is" remembers type checking, not comparison (in my opinion, but this is no the real problem, though). If briefness is the target, we should use := (or $) instead.

-----

2 points by icemaze 6117 days ago | link

"Lisp-1. IMO, lisp isn't best suited to a functional style. This is one of the many lies that Schemers (and apparently Arcers) tell themselves."

Why do you think so? Could you provide us with a couple of examples? Not having to use #' is nice.

-----

1 point by fractal 6116 days ago | link

mst - Good point, a with-nil macro will be useful in arc. Another feature of CL's let is that you can do

  (let (a (b) (c nil))
     ...)
to bind them all to nil. This is sometimes useful when writing macros. I'm not strongly opinionated here, but my preference is for a unified basic binding form.

vsingh - Good point, I'm looking forward to exploring Arc's first class macro support. It would help to have a good explanation of how they work. My concern is efficiency. In CL, all macros (including local macrolet ones) are guaranteed to have been expanded before the run-time of a compiled function (ie CLtL2 p685). Does Arc make any such guarantees?

icemaze - The debate re: lisp-1 vs lisp-2 has been going on for a long time. I didn't expect to change anyone's mind with this post, only to make my position on the issue clear. I think it is unquestionably the right modern lisp design decision. For an example, see my post re: REPL vars. In CL, + the variable can coexist with #'+ the function.

-Doug Hoyte

-----