multiple-value-bind

Q&A's, tips, howto's

multiple-value-bind

Postby hds1 » Thu Jun 29, 2017 5:53 am

Hello,
i'am trying to emulate "multiple-value-bind" via read time macro. That is translate:

Code: Select all
(mvb '(a b c .... ) '(1 2 3 ....) ...)))
into
(let (a 1 b 2 c 3 ....) ..... ))))


The idea i had is expansion during read time :
Code: Select all
(macro (mvb) nil)
(constant 'mvb (lambda-macro (ALIST BLIST)
       (letex (flat (transpose (list ALIST BLIST))))))

But this fails because i cannot pass a function or variable to 'letex.

What do i miss here ? Or is there another way ?

Thx
Heiko
hds1
 
Posts: 27
Joined: Thu Mar 20, 2014 5:02 pm

Re: multiple-value-bind

Postby ralph.ronnquist » Thu Jun 29, 2017 9:18 am

mmm, you might have meant something like this?
Code: Select all
macro (mvb) nil)
(constant 'mvb (lambda-macro ()
        (extend (list 'let (map list (args 0) (args 1))) (2 (args)))))

I.e., create a let clause with the two first arguments as variable assignments, then the rest forming the body.
It breaks violently on bad syntax input of course, especially if you quote the two first lists. The input with rather be without quotes, such as for instance:
Code: Select all
(mvb (a b c) (1 2 3) (+ a b c))

You can verify the macro result e.g. by quoting the expression, as in
Code: Select all
'(mvb (a b c) (1 2 3) (+ a b c))


In any case, I'm not sure what you mean with
But this fails because i cannot pass a function or variable to 'letex.

The first term of a letex clause is a variable binding term like that of a let clause, and then those variables get replaced by their values in the clause body, which thereafter is evaluated. A simple illustration could be
Code: Select all
(letex ((a 3) (b 4)) (+ a b))

which of course evaluates to 7.
ralph.ronnquist
 
Posts: 178
Joined: Mon Jun 02, 2014 1:40 am
Location: Melbourne, Australia

Re: multiple-value-bind

Postby hds1 » Thu Jun 29, 2017 7:22 pm

Good idea. Looks not too bad:

Code: Select all
(macro (mvb) nil)
(constant 'mvb (lambda-macro ()
       (list 'let
             (flat (transpose (list (args 0) (args 1))))
             (args 2))))
(define (ttt)
  (mvb (a b c) (1 2 3) (println "Killroy: " (+ a b c))))

(ttt)
==>
> Killroy: 6
6

Code: Select all
'(mvb (a b c) (1 2 3) (println "Killroy: " (+ a b c)))
==>
(let (a 1 b 2 c 3)
  (println "Killroy: " (+ a b c)))


But, (args 1) cannot be something like (sequence 1 3) or a result of a function call because it gets not evaluated during read time.
Is there a way to make (args 1) beeing evaluated during read time ?
hds1
 
Posts: 27
Joined: Thu Mar 20, 2014 5:02 pm

Re: multiple-value-bind

Postby hds1 » Thu Jun 29, 2017 7:36 pm

Answering myself ..
Code: Select all
;; @syntax (m-v-b symlist valuelist body)
;;
;; @param  symlist valuelist body
;; symlist: List of var names
;; valuelist: List of values or function call which returns list of values
;; body: Operation with var names
;; @return Expanded 'let with body
;; @example
;; (m-v-b '(a b c) '(1 2 3) (+ a b c)) -> (let (a 1 b 2 c 3) (+ a b c))
;; Supposed to emulate Common Lisp multiple-value-bind macro
;; Expansion is done during Read Time.
;; Evaluation of the returned 'let body during Run Time.
(macro (m-v-b) nil)
(constant 'm-v-b (lambda-macro ()
         ;; Read Time part
        (when (or (not (quote? (args 0)))
             (not (list? (eval (args 0)))))
          (throw-error "m-v-b: first argument must be a quoted list i.e. '(a b c)"))
        (let ((lst1 (eval (args 0)))
         (lst2 (map quote (eval (args 1))))) ; quote elements so that list of lists can be used
          (when (!= (length lst1)
               (length lst2))
            (throw-error
             (append "m-v-b: Argument lists length unequal. " (string lst1) " " (string lst2))))
          ;; Run Time part
          (list 'let
           (flat (transpose (list lst1 lst2)))
           (args 2)))))


Code: Select all
(m-v-b '(a b) (transpose '((1 2)(3 4)))
   (println a b))
==> (1 3)(2 4)
(m-v-b '(a b) '(3 4)
   (println a b))
==> 3 4

Getting better ....
hds1
 
Posts: 27
Joined: Thu Mar 20, 2014 5:02 pm


Return to newLISP in the real world

Who is online

Users browsing this forum: No registered users and 2 guests