1

I need to write the lisp macro in scheme (please on hygienic macros and syntax-rules etc) that will have function call and Alist as argument

I want function and macro that call that function to have syntax like this:

(foo '(10 (a (lambda () (display "10")) b (lambda () (display "20"))))

or macro without quotes.

My last code is working, but not sure if this is how you suppose to write function/macro like this. It seems that I need double backquote but don't know how to write it. (I'm right now reading On Lips by Paul Graham and he said that double backquote is very hard and only need by macros defining macros, but It seems that this is what I need).

(define (foo expr)
    `(list ,(car expr)
           (,(string->symbol "quasiquote") ,(pair-map (lambda (a b)
                                                        (cons (symbol->string a)
                                                              (list 'unquote b)))
                                                      (cadr expr)))))

(define-macro (bar expr)
   (foo expr))

(define xx (bar (10 (a 20 b (lambda () (display "x") (newline))))))
;; (list 10 `((a . ,20) (b . ,(lambda () (display "x") (newline))))
(define bfn (cdr (assoc "b" (cadr xx)))))
(bfn)
;; "x"

and here is definition of pair-map

(define (pair-map fn seq-list)
  "(seq-map fn list)

   Function call fn argument for pairs in a list and return combined list with
   values returned from function fn. It work like the map but take two items from list"
  (let iter ((seq-list seq-list) (result '()))
    (if (null? seq-list)
        result
        (if (and (pair? seq-list) (pair? (cdr seq-list)))
            (let* ((first (car seq-list))
                   (second (cadr seq-list))
                   (value (fn first second)))
              (if (null? value)
                  (iter (cddr seq-list) result)
                  (iter (cddr seq-list) (cons value result))))))))

with (string->symbol "quasiquote") I was able not to use double backquote, can this be written with double backquote/quasiquote? How this should look like?

I'm asking if this can be written different way so I can fix few issues in my own lisp interpreter (not sure if is working correctly but it seems that this final version works the same in guile).

7
  • 1
    map-pair has a one armed if. Thus pair-map might return "BaNaNa" since the behaviour of one armed if is underspecified. What is the code (bar (10 (a 20 b (lambda () (display "x") (newline))))) suppose to expand to? Commented May 27, 2019 at 21:34
  • @Sylwester it suppose to be list with car and Alist as second item, it should expand into (list 10 ((a . 20) (b . (lambda () (display "x") (newline))) Commented May 30, 2019 at 6:37
  • I think I understand. You mean it expands to (list 10 `((a . ,20) (b . ,(lambda () (display "x") (newline))) so that the lambda becomes a function? Commented May 30, 2019 at 7:22
  • @Sylwester yes, I've edited the question. Commented May 30, 2019 at 12:25
  • I'm not sure if I understand the question, but if you want to make alist of procedures, you can simply use quasiquote instead of using a macro. Commented May 31, 2019 at 6:53

1 Answer 1

0

I came up with shorter quasiquote version, but still it require inserting symbols:

(define (foo expr)
    `(list ,(car expr)
           (,'quasiquote ,(pair-map (lambda (a b)
                                      `(,(symbol->string a) . (,'unquote ,b)))
                                    (cadr expr)))))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.