Hi Everyone- I did a little hacking inside of arc2.tar to implement a cool new syntax feature... As you probably know, an original feature planned for arc was implicit local variables. This was abandoned because of difficulties with the macro system. The new syntax feature I've implemented is an alternative idea that fills a similar need... Semi-implicit local variables! The syntax is similar to the bracket syntax for anonymous local functions. Let's say you have the following code: (def foo ()
(let x (+ 1 2)
(cons x x)))
With my patches you can now write: (def foo ()
{+ 1 2}
(cons ^ ^))
In order for it to work, you need to be inside of a progn, whether implicit or explicit. (If you don't know what this means, basically you need to be in a "do" or in a function)When one of the statements in the progn is surrounded by curly brackets, subsequent statements in the progn will have a local variable declared named "^". It will be set to the value of the statement. Multiple bracketed statements are allowed in a single progn. This also makes it useful for "piping" values along in a chain, allowing you to "flatten" deeply nested code: (do {+ 1 5}
{* ^ 7}
(- ^ 88))
This bracketed anonymous variable notation reduces the cost for creating a single local variable. It is philosophically a cousin of the bracketed function notation. I believe it is easy to understand and in my own personal code I can simplify maybe 2/3 of my functions by using this new feature.Many functions in arc.arc could be simplified with this feature. To give one example: BEFORE (mac complement (f)
(let g (uniq)
`(fn ,g (no (apply ,f ,g)))))
AFTER (mac complement (f)
{uniq}
`(fn ,^ (no (apply ,f ,^))))
AFAIK, my implementation is 100% working and handles the expected use cases appropriately. It also has no impact on the performance of code that does not use this feature. It is, however, ugly and has poor error handling. That's why I'm not going to mess with anarki in this case, but I don't mind if anyone else wants to make such a change...To add this feature to your own arc system, replace the function "ac-body" in ac.scm: (define (ac-body body env)
(if (null? body)
'()
(if (and (list? (car body)) (eq? 'curly (car (car body))))
`((let ((_^ (begin ,@(ac-body (cdr (car body)) env))))
,@(ac-body (cdr body) env)))
(cons (ac (car body) env) (ac-body (cdr body) env)))))
Next, you'll need to download a new copy of brackets.arc from here: www.lisperati.com/brackets.scmLet me know what you think- If anyone else has already implemented something like this I'd love to know about that, as well. |