Taoufik Dachraoui
5/20/2015 8:22:00 AM
On Wednesday, May 20, 2015 at 10:18:03 AM UTC+2, Taoufik Dachraoui wrote:
> Hi
>
> I want to share a macro for the parallel let that I wrote for fun,
> I used the pattern matching macro that I wrote a long time ago and
> that I am using for all my lisp developments:
>
> ;;; parallel let
> ; (let ((a va) (b vb) (c vc)) e)
> ; => ((fn a ((fn b ((fn c e) vc)) vb)) va)
> ; => ((fn xc
> ; ((fn xb
> ; ((fn a ((fn b ((fn c e) xc)) xb)) va)
> ; ) vb)
> ; ) vc)
>
> (defmacro let (&rest e)
> (match `(let . ,e)
> ((let (:and ?args (:match (:or nil ((:or (:type symbol) ((:type symbol) _)) . :self))))
> (:lone (declare . _)) . ?s)
> (loop
> for i in args
> for j = (if (atom i) i (car i))
> for xj = (gensym)
> for k = (if (atom i) nil (cadr i))
> for x = `(progn . ,s)
> then `(funcall (lambda (,j) ,x) ,xj)
> collect xj into rj
> collect k into rk
> finally (return
> (loop
> for xj in rj
> for k in rk
> for xr = (if (atom (car args))
> `(funcall (lambda (,(car args)) ,x) nil)
> `(funcall (lambda (,(caar args)) ,x) ,(cadar args)))
> then `(funcall (lambda (,xj) ,xr) ,k)
> finally (return xr)))))
> (_ (error "invalid let expression"))))
>
>
> -Taoufik
I forgot to pur the macro for let*:
(defmacro let* (&rest e)
(match `(let* . ,e)
((let* (:and ?args (:match (:or nil ((:or (:type symbol) ((:type symbol) _)) . :self)))) (:lone (declare . _)) . ?s)
(let ((r (if (null s) nil `(begin . ,s))))
(if (null rest)
`(funcall (lambda (,x) ,r) ,e0)
`(funcall (lambda (,x) (let* ,rest ,r)) ,e0))))
(_ (error "invalid let* expression"))))
-Taoufik