One feature I really love in arc is one that many people may not have noticed yet- It has a great feature for debugging an arbitrary form. For Instance, suppose you are worried about a bug in the form handling the first division in the following example: (let x 4
(+ 1 2
(/ x 3)
(/ 7 6)))
What you can do in arc that I think is awesome is "inline" a prn statement like so: (let x 4
(+ 1 2
(prn:/ x 3)
(/ 7 6)))
If you're a long time lisper, you'll see the value of this immediately, because intrumenting in a debugging statement usually requires 2 edits, since the intrumenting code will be in parens and will require you to write that annoying terminating paren, which the colon operator avoids. Adding/removing the terminating paren during debugging is a common causee of Lisp paren screwups.Unfortunately, the colon operator is not very general... Why, for instance, can't I inspect the "x" variable, like so: arc> (let x 4
(+ 1 2
(/ prn:x 3)
(/ 7 6)))
Error: "/: expects type <number> as 1st argument, given: #<procedure>; other arguments were: 3"
Surely, it would be easy to make allow composition on literal numbers/strings/conses and make this possible?Another wart in the colon operator is that I can't do this: (let x 4
(+ 1 2
(/:prn x 3)
(/ 7 6)))
If you run this (the prn and division have been flipped- we'll see the value of this later) the program will print the wrong anser, because the prn loses the "3" and doesn't pass it on. I would argue "prn", when called with multiple values, should return a list of all values- Which brings me to the issue of multiple values...Suppose prn DID return a list of args, how would those args get fed into "/" properly? By a strange coincidence, I was going to post about the use of "@" outside of quasiquotes today, but someone else had the exact same idea today: http://arclanguage.org/item?id=1920 Here's what that feature would allow us to do: (let x 4
(+ 1 2
(/ @(prn x 3))
(/ 7 6)))
In this case, prn would return a list of '(4 3) and then they would be divided properly... Then, we could use the colon syntax as follows: (let x 4
(+ 1 2
(/:@prn x 3))
(/ 7 6)))
The colon here would tell the arc compiler "treat the returned list from prn as multiple values to compose into the division function"If we had a feature like this, it would allow us to elegantly handle multiple return values (without the arguably ugly "values" system from scheme) And would greatly generalize the colon operator! For instance, imagine being able to do this: arc> (string:@map [+ "/" _] '("3" "4" "5"))
"/3/4/5" (imagined answer)
To take this further, imagine we change "withs" to work like this: (withs (x y z ;note all variable names are at the beginning
1 2 3)
(+ x y z))
Then, maybe, we could write stuff like: (def foo ()
'(1 2 3))
(with (x y z @(foo))
(+ x y z))
Note how we could basically get "multiple-value-bind" as a freebee with support for an "@" operator!Another feature that would greatly synergize with this line of thinking would be partial application support, already discussed previously on the forum: arc> (= g (map [+ _ 1]))
<function> ;this currently doesnt work :(
arc> (g '(4 5 6))
(5 6 7)
There may be problems I'm not seeing that would prevent this kind of stuff from working well... But if not, wouldn't an improved colon operator like this (along with the other ideas I've mentioned) open up all kinds of possibilities for briefer/cleaner code? I might even not miss Haskell's point free style all that much any more :)-Conrad Barski |