[ a b c :
(/ (+ (- b) (sqrt (+ (* b b) (* 4 a c))))
(* 2 a))]
[: (thunk this)]
[ a b c ->
(/ (+ (- b) (sqrt (+ (* b b) (* 4 a c))))
(* 2 a))]
[-> (thunk this)]
[ a b c =>
(/ (+ (- b) (sqrt (+ (* b b) (* 4 a c))))
(* 2 a))]
[=> (thunk this)]
Nesting doesn't seem impossible: the reader, I think, will handle nesting as:
[foo [bar]]
(make-br-fn (foo (make-br-fn (bar))))
As for implementation, it's easy:
(given ; this gives us access to the old
; implementation of [] syntax; it
; is used when we don't find the
; separator
old (rep make-br-fn)
; use a variable to easily change
; the separator
separator ': ;for experimentation
(= make-br-fn
; a macro is just a function that has
; been tagged (or annotated) with the
; symbol 'mac
(annotate 'mac
; the reader reads [...] as
; (make-br-fn (...))
(fn (rest)
; find the separator
(if (some separator rest)
; note the use of the s-variant givens
; the "s" at the end of the name of givens
; means that the variables are specifically
; bound in order, and that succeeding variables
; may refer to earlier ones
(givens ; scans through the list, returning
; an index for use with split
; (no built-in function does this)
scan
(fn (l)
((afn (l i)
(if (caris l separator)
i
(self (cdr l) (+ i 1))))
l 0))
; now do the scan
i (scan rest)
; this part destructures a two-element
; list
(params body)
; used to get around a bug in split
(if (isnt i 0)
(split rest i)
(list nil rest))
; it just becomes an ordinary function
; body includes the separator,
; so we also cut it out
`(fn ,params ,@(cut body 1)))
; pass it to the old version of make-br-fn
; if a separator was not found
(old rest))))))
Edit: tested. Also reveals a bug in split: (split valid_list 0) == (split valid_list 1)
(= foo [ i :
[ : i]])
((foo 42))
edit2: p.s. probably not really easy much after all^^. As a suggestion, (help "stuff") is good at finding stuff.