Here is a code for adding local scope to arc,
it can be used for writing in procedural style. (= *binding-function-list* '(let with w/table))
(def split@ (lst (o acc))
(if (empty lst)
(if (empty acc)
nil
(list (rev acc)))
(caris lst '@) (cons (rev acc)
(split@ (cdr lst)))
(split@ (cdr lst) (cons (car lst) acc))))
(def span_let (lst)
(if (empty lst) ()
(mem (caar lst) *binding-function-list*)
(list (append (car lst) (span_let
(cdr lst))))
(and (is (type (caar lst)) 'cons)
(is (car (caar lst)) 'scope)) ;scope
(if (is (cdr (car lst)) nil)
(cons (caar lst) (span_let
(cdr lst)))
(cons (caar lst) (span_let
(cons (cdr (car lst)) (cdr lst)))))
;forget @ after scope
(if (and (is (cdr (car lst)) nil)
(~is (caar lst) 'fn))
(cons (caar lst) (span_let
(cdr lst))) ;not function call
(cons (car lst)
(span_let (cdr lst))) ) ))
(mac scope lst (cons 'do (span_let (split@ lst))))Here is an example of a use of this macro: (def shuffle_numbers (min max)
;Get a minimum and maximum numbers
;Return a shuffle array of numbers from the
;minimum number to the maximum
(scope
let temp 0 @
w/table arr @
for i 0 (- max min)
(= arr.i (+ i min)) @ ;init arr
loop (= i (- max min)) (> i 0) (-- i)
(swap arr.i (arr (rand (+ 1 i)))) @
;shuffle array elements
arr ))
I think that the scope macro make the code more readable.
What do you think? |