You can find it at http://ycombinator.com/arc/arc1.tar
Please let me know if there are any new glitches.
There are a bunch of changes, many of them fixing bugs reported here. The most dramatic change is probably the ability to use x.y and x!y as abbreviations for (x y) and (x 'y) respectively.
I like that "subseq" was renamed to "cut" and that it now takes negative indices.
However, I wish we could say (x 1 -1) instead of (cut x 1 -1). And since x.0.0 expands to (x 0 0) then that would let us say x.1.-1 which is what languages such as Python and Ruby already allow.
I hope that this is coming; I image that Arc's creators don't want to introduce too many changes all at once, so maybe they'll add this after they see how the x.y syntax works out.
Hmm, yes, so would I. I should fix that. I just did what Emmett suggested, which must have been based on Ruby, but it doesn't actually seem like a good idea.
Agreed. Ruby does it the other way ("abcde"[1..-1] is "bcd"), but that's only because there's no other way to specify "until the end." But that's the default in Arc; the following are equivalent right now:
Both nil and (len str) work. I see both sides of the argument as counting from -1 eliminates the 0 corner case.
I like indices that are intuitive with literal numbers. Counting from 0 at one end and from 1 at the other is jarring. When -1 points to the end of string rather than before the last char (cut str 0 (- (len str))) returns the first char instead of the empty string.
With -1 -> before last char:
(def chop ((o str "abcdef"))
(pr "Chop how many chars off the end of \"" str "\"? ")
(= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
(prn "Chopped: \"" (if (is n 0) str (cut str 0 (- n))) "\"")) ; handle corner case
With -1 -> end of string:
(def chop ((o str "abcdef"))
(pr "Chop how many chars off the end of \"" str "\"? ")
(= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
(prn "Chopped: \"" (cut str 0 (- -1 n)) "\"")) ; no corner case, but there's this -1 there
I probably made a stronger argument for -1 pointing to the end of string as it leads to shorter code.
While I agree that this shouldn't be abused, I'm not actually proposing this syntax; Arc already lets you say cut.x.1.3 as an alternative to (cut x 1 3).
I suspect that the only time I'd ever want to chain together several different things with . is when I'm doing list slices. Which is why I'd like the x.1.3 syntax to work, since in my opinion cut.x.1.3 is a lot uglier, perhaps enough that I'd rather not do it.
Is this actually the way the first expression is being expanded? I can think of situations where I would want (foo:bar.arg) to be expanded to (foo (bar arg)) not (foo ((bar arg))). Just a thought.
The plan with intrasymbol syntax is (a) not to break traditional Lisp read and (b) to expand in place. If you have those two constraints, instead of just saying "ok, put any syntax anywhere," you can introduce syntax into Lisp without getting too unLispy.
Right. Maybe it's the traditional Lisp read that's the main factor here because it seems that you could expand in place without issue given even arbitrary expressions.
If a.b expands to (a b) then (f v w).(g x y) would just expand to ((f x y) (g x y)). At first glance, that definitely appears to be a cool way to grab just one of the results from a function return (ala (f x y).2).
Hmm, on the down side, you could have statements like (or worse):
(bst-find tree 45 f<).(if (< 10 42) (/ 4 3)
(> 4 2) x
'r)
That being said, having to change read to get this to work may affect far too much and make arc too ugly.
I've added this as branch "official" of the arc wiki. I've also tried to merge it into the master branch. I resolved everything I knew how, but there might be some regressions and references to renamed/no-longer-existent functions hanging around.
it would be nice if we made specs to test the language, a la Rubinius, while the language is still small. Then, we could say with greater confidence of the merge.
A possible problem is that I can see myself wanting to use this syntax a lot for accessing hash tables with symbols as keys. But ! is a lot more annoying to type than . is.
My alternative suggestion (which I'm sure has worse problems of its own) would be
x.y -> (x 'y) if y is a symbol, (x y) otherwise
x,y -> (x y) (by analogy with , inside backquote)
x!y -> (x 'y) (if there should ever be a need to quote a non-symbol?)
Edit: Also in favour of my proposal, ! looks too much like a letter l:
Yep, thanks. It would be cool if there were an abbreviation for that, since it's fairly common. Eg l.2%1 (% randomly chosen) => ((l 2) 1). Some may say that goes too far toward a parentheses alternative for all sorts of things, but on the other hand data structure access is one of the clumsier parts of Lisp.
I've been trying this syntax on example programs for several weeks. Maybe months, actually. It doesn't yield startling results in compression if you count x.y as 3 nodes, but it does make programs easier to read, particularly when you use it for structure access.
What if x.y!z expanded to ((x y) z)? Then if x were '(1 2 (3 4) 5), x.2!1 would give you 4. If (x 1 3) did work like cut, then you could do x.1.3!1!1, which would also give 4 in this case.
pipe-from is (still?) broken on Windows since it uses /dev/urandom. Maybe use make-temporary-file instead? (pipe-from is not really a pipe; it directs command output into a file, and then reads from the file; having a real pipe would be nice. Also, it does a rm -f, which isn't too good on Windows either.)
It does to new users migrating from mzscheme. Not everyone is going to downgrade mzscheme to 20 revisions old package just to try out new lisp dialect.
Bringing it up to date would probably increase its adoption.
I think he meant that updating Arc didn't make any difference to the requirements, not that using an old mzscheme doesn't make any difference, which it certainly does. I wouldn't be using Arc if there hadn't been a patch to get it working on newer mzschemes; the git "wiki" (http://git.nex-3.com/arc-wiki.git) works on said mzschemes right now. It may not be official, but it might help scratch your itch.
What is c-lisp? Do you mean GNU CLISP, an implementation of the Common Lisp language? Do you mean Common Lisp in general? I think the main reason for using Scheme as a host instead of CL is that Arc is more similar to Scheme than CL.
I like MATLAB syntax best. 1:5 builds a range. 1: should build the infinite range, but MATLAB is crippled and only lets you do x(1:end). In Lisp syntax, (x 1:) would be item 1, 2, etc of x, (x lo:hi) would be lo, ..., hi-1. I'd also find this convenient because I often need to loop from 0 to infinity and 1 to infinity. Although Python's syntax of using negative numbers to index from the end of the list is far more convenient than 'end' in MATLAB, and it goes without saying that MATLAB's 1-based indexing is Satanic.
Using lots of syntax (e.g. Python's range(a, b)) for range construction is completely unacceptable, and using different syntax to index into an array and construct a range is annoying, due to violating fairly basic notions of beauty in mathematics (Equal things can be replaced by each other; Use one abstract syntax to cover lots of ideas, instead of lots of syntax to cover few ideas). Also, if one leaves out sane floating-point range construction methods, then they get added over and over again in 3rd party libraries (e.g. numpy.arange in Python).
Rather bizarrely, on my Linux system at least, make-directory is creating directories with the sticky bit set... and I didn't see anywhere in the MzScheme's manual a way to set the umask. Perhaps someone else will have better luck.
If this can be fixed, the make-directory* function in the MzScheme file.ss library will usefully create intervening directories, like mkdir -p does.
When I look at x.y, I see attribute/method access as in many other languages, so it seems to me that the Arc analog should be (x 'y). Maybe this is a worthwhile abbreviation for pulling out a subitem. For function application though, I don't see why you would want a shortcut for (f x) when f.x or f!x isn't really much shorter.