I've mentioned before[1] that wart uses a @ operator instead of apply. Until now I considered the benefit to be syntactic uniformity with unquote-splice, the ability to splice anywhere in a call and not just right at the end, and the ability to make splice work in many macros[2]. (foo x y @rest) ; same as (apply foo x y rest)
(foo @(list x y) z) ; same as..?
Today I just realized a new benefit: the ability to splice in code into a call. For example, news.arc has a function called markdown with the following structure[3] for formatting asterisks as italics: (if
... ; lots of complicated cases
(and (is (s i) #\*)
(or ital
(atend i s)
(and (~whitec (s (+ i 1)))
(pos #\* s (+ i 1)))))
; then
(do (pr (if ital "</i>" "<i>"))
(zap no ital))
... ; lots more complicated cases
)
The hubski codebase[4] wanted similar formatting for pluses into bold text. I'd like to extract out the repeated code into a function or macro but I can't, since it would have to return two expressions that are spliced into the caller. But in wart I could. def (format open close char|between s|at i flag)
`((and (is (,s ,i) ,char)
(or ,flag
(atend ,i ,s)
(and (~whitec (,s (+ ,i 1)))
(pos ,char ,s (+ ,i 1)))))
; then
(do (pr (if ,flag ,close ,open))
(zap no ,flag)))
(Not actually working wart code because I'm sacrificing correctness to keep the same vocabulary as the above arc fragment.)Now the original structure becomes: (if
... ; lots of complicated cases
@(format "<i>" "</i>" :between #\* :at s i ital)
@(format "<b>" "</b>" :between #\+ :at s i bold)
... ; lots more complicated cases
)
Can anyone think of a nice[5] way to use the code-generate the case without the @ operator? Here's a simpler working example you can try in wart: $ git clone git@github.com:akkartik/wart
$ cd wart
$ git checkout 43d9f79dc9
$ ./wart
ready! type in an expression, then hit enter twice. ctrl-d exits.
<- x nil y 1
(if x 34 y 35)
=> 35
(if @`(,x ,34) y 35)
=> 35
Or is this example too contrived, and splicing multiple exprs into an if just weird? Why has lisp never felt the need for splicing somewhere other than the end of a call?[1] http://www.arclanguage.org/item?id=15154 [2] As long as they're implemented using backquote: http://arclanguage.org/item?id=16378 [3] https://github.com/nex3/arc/blob/cb907aaea4/lib/app.arc#L433 [4] http://hubski.com; http://arclanguage.org/submitted?id=markkat [5] Backquoting the entire outer if is the other option I can think of, but it doesn't seem very nice ^_^ |