These are interesting ideas. I really like the idea of using @ as an analog to Ruby's splat. After thinking about it for a few minutes I think I like (string:@map ...) too, though I think it's starting to look like line noise.
If you compose a function with a value what does that mean? Something like ((fn (y) (prn y) y) x)? In the example you gave I would still expect to wrap prn:x is parens to execute the resulting procedure.
you are correct about the parens on prn:x... I thought I had a clever trick from making them unecessary, but it didn't pan out when I sat down to work out the necessary transformations... creating decent language primitives is hard...
...your "line noise" comment also is a good point...
This stuff is hard. I looked into implementing general splicing functionality but it is not trivial. Reading @bar and translating it to (splice 'bar) is easy enough, but then you would have to examine the arguments of every sexp before evaluating it to handle the splice. I guess it's not particularly difficult but it would likely be a performance hit. Perhaps there is a clever trick to do general splicing.
prn:x should mean [prn (x _)] because x is no different from prn, and may very well be a function. Unless you can statically know the value of x, but statical analysis of variable content does not sound very lispy to me. While it's ok for optimization it is not ok for semantics!
I'm all for something like this, but it's tricky. SRFI 49 looks pretty good but I have not tried it.
There are some thoughts here[1], though I don't like how he's moved the procedure outside the parens to match algol-like languages and I don't like the curly braces stuff either.
Using = to test for equality is confusing in an Arc forum. :)
1. This could be added without introducing a new reserved word. I have a git branch on my machine here where < and > return their first argument if the comparison succeeds.
2. Seems handy. I would put the operator before the number to compare just because it reads better, though I realize the op varies the least. The default of testing (is (len lst) 1) seems arbitrary, but I guess (no lst) takes care of the most common length test so maybe it's useful. Also, (is 1 (len lst)) is only 3 chars longer than (length? lst). Personally I like the ? suffix to denote predicate fns but I don't think pg does (or he would use them). For Arc I would suggest (len? ...).
I'm not sure about 3 and 4.
4. It seems backwards to put the (< n (len lst)) case first, no? I would put (< (len lst) n) first, then (is (len lst) n), then (> (len lst) n).
If you think of the . here as Haskell's cons (:) then it makes sense. All the same, (x y . zs) can mean the exact same thing, not to mention it is shorter and familiar.
Arc uses the PLT Scheme reader. The PLT Scheme reader has a non-standard (as compared to RnRS) extension, namely the double-dot notation. The double-dot notation is used to write "infix expressions".
Consider:
(x . < . y) is turned into (< x y)
(integer? boolean? . -> . void?) is turned into (-> integer? boolean? void?)
This reader extension can be turned off, but setting the appropriate parameter.
That is strange, and probably a bug. You can use up to 2 dots and the last dot is handled first, consing x and (z . nil) then consing y and (x (z . nil)). '(w x . y . z) gives (y w x z).
I can almost see how this bug appeared. Searching for the first part of a dotted expression yields (w x), and then searching for the 2nd part yields z. For some reason the expression becomes '(y . (w x z)); that I cannot explain without looking at the code.
good point, I should have thought that one through. Perhaps we should consider changing the return value of ">" so I'm correct? :P
It seems more useful to have the return value be the greater number if it is true, and since all non-nil values are true, it wont break any existing code. For a > b, consider the following:
Makes sense to me. It's a trivial change in ac.scm for < and >. What about (<= 1 2 3) and (>= 3 2 1)? The easiest way to do the same for those two is to return the last value compared, which would be 3 and 1 respectively. That doesn't exactly jibe with < and > though so I hesitate to make such a change. Thoughts?
It seems logical that <= and >= should also return some meaningful value if < and > do. If we come up with something good I'll push it to the anarki repo (git wiki). Although, we could always just ignore <= and >= for now.
I should have been clearer. I agree the semantics should be the same, I just didn't see an immediately clean way to add that to the current, recursive <= and >= functions. A thin wrapper would work just fine.
I would just use this first form below. A macro you may be able to adapt for your purposes follows.
(let a2 (+ a c)
(if (> a2 b) (= a a2)))
(mac =if (var expr test)
(w/uniq result
`(let ,result ,expr
(if (,test ,result) (= ,var ,result))
,var)))
(=if a (+ a c) [> _ b])