Схема: сопоставление пусть и установлено!на списки - PullRequest
2 голосов
/ 14 марта 2011

Я пытаюсь сопоставить пусть и установить!в списках что-то вроде этого:

(map (lambda (x) (let ((x #f)))) <list>)

и

(map set! <list1> <list2>)

Но, конечно, ни то, ни другое не работает.

Есть ли способ сделать это?Любой совет приветствуется.

Спасибо.


Настоящая проблема в том, что я пытаюсь найти способ сопоставления с образцом letrec.Мне нужно иметь возможность сопоставить шаблон:

(letrec ((var val) ...) expr0 expr1 ...)

и преобразовать его - используя match-lambda - в эквивалентный вызов, используя только let и set!Это шаблон, который я пытаюсь эмулировать:

(letrec ((var val) ...) expr0 expr1 ...)

==>

(let ((var #f) ...)
(let ((temp val) ...)
(set! var temp) ...
(let () expr0 expr1 ...)))

Проблема заключается в переводе этого в синтаксис, который принимает match-lambda.Вот то, над чем я работал, предполагая, что был способ решить исходный вопрос:

(match-rewriter (`(letrec((,<var> ,<val>) ...) ,<expr> ...)
                   `((map (λ (x) (let ((x #f)))) ,<var>)
                      (let ((temp ,<val>)))
                        (map set! ,<var> temp)
                        (let () ,@<expr>))))

Любой совет приветствуется.

Спасибо.

Ответы [ 2 ]

1 голос
/ 14 марта 2011

Вы не можете этого сделать. За исключением использования eval, имена переменных, как правило, не могут быть динамическими (в основном все, что не является символьным литералом). Это по замыслу.

Если ваши имена переменных действительно являются литералами, и вы просто хотите связать несколько переменных одновременно, вы можете использовать let-values ( SRFI 11 ) или расширенный let ( SRFI 71 ).


Редактировать, чтобы соответствовать редактированию OP: То, что вы хотите сделать, звучит как определение letrec, данное здесь . Однако этот макрос использует syntax-case, а не match-lambda или тому подобное. Вы можете использовать его в качестве отправной точки.

0 голосов
/ 16 марта 2011

Это код, который вы хотите:

(define (rewrite-letrec l)
  (match l
    [(list 'letrec (list (list vars rhss) ...)
           exprs ...)
     (let ([tmps (map (λ _ (gensym)) vars)])
       `(let (,(map (λ (v) `(,v #f)) vars))
          (let (,(map (λ (tmp rhs) `(,tmp ,rhs)) tmps rhss))
            ,@(map (λ (v t) `(set! ,v ,t)))
            (let () ,@exprs))))]))

Здесь есть несколько отличий.Во-первых, let являются вложенными.Во-вторых, мы создаем код, а не пытаемся его запустить.

...