Гигиенические макро r7rs: Возвращает второе значение выражения

голоса
0

Я в настоящее время обучения некоторых r7 и я пытаюсь выполнить макрос «начать» как следующее:

(begin0 expr0 expr1 ... expr2)

С выраж быть регулярным выражением (как (набор! Х (+ х 1)))

И begin0 как макрос, который оценивает все выражение, но возвращать только результат Expr1.

Например :

(let ((year 2017))
(begin1 (set! year (+ year 1))
  year
  (set! year (+ year 1))
  year)) 

Она сусло вернуться в 2018 году

Я создал начать функцию первой:

(define-syntax begin0
 (syntax-rules ()
  ((begin-0 body-expr-0 body-expr-1 ...)
   (let ((tmp body-expr-0)) body-expr-1 ... tmp))))

А теперь, я пытаюсь понять, как я могу сделать, чтобы вернуть значение «тело-выраж-1»? Я сделал следующий код, но он говорит, что я не хватает какой-то многоточие, и я не понимаю, как это сделать.

(define-syntax begin1
  (syntax-rules ()
    ((begin1 body-expr-0 body-expr-1 ... body-expr-2)
     (let ((tmp body-expr-0) body-expr-1 ... tmp)
       (cond (eq? tmp body-expr-1)
              (begin . tmp))))))

Я надеюсь, что это достаточно понятно, спасибо за ответы.

Задан 27/11/2018 в 15:14
источник пользователем
На других языках...                            


2 ответов

голоса
2

Это может быть сделано, но макрос будет мешать, что вы не можете сделать все, что с , begin1как с begin.

(define-syntax begin1
   (syntax-rules ()
     ((_ expr0 expr1 exprn ...)
      (begin
        expr0
        (let ((result expr1))
          exprn ...
          result)))))

Код, который не работает, состоит в следующем:

(begin1
  (define global1 10)
  test3
  (define global2 20))

Причина очевидна. Он расширяется:

(begin1
  (define global1 10)
  (let ((result~1 test3))
    (define global2 20)
    result~1))

Второй defineбудет изменен на letrecтакое , что переменная global2доступна только для продолжительности let. У меня нет исправления для этого , так как она требует , чтобы вы могли сделать глобальный defineот закрытия.

begin1довольно странная особенность. В Ракетка и , возможно , других диалектов Scheme мы имеем , begin0что возвращает результат первого выражения. Это очень полезно. например. вот счетчик:

(define (get-counter from)
  (lambda ()
    (let ((tmp from))
      (set! from (+ from 1))
      tmp)))

И с begin0:

(define (get-counter from)
  (lambda ()
    (begin0 
      from
      (set! from (+ from 1)))))

В Ракетка begin0является примитивным. Таким образом , это форма поддерживается в полностью расширенной программе и , таким образом , осуществляется в C, так же , как begin..

Ответил 27/11/2018 в 22:22
источник пользователем

голоса
-1

Итак, я нашел возможный способ сделать это, я не хотя мы могли бы просто задать условие на непосредственное значение:

(define-syntax begin1
  (syntax-rules ()
    ((begin1 body-expr-0 body-expr-1 body-expr-2 ...)
       (if body-expr-1
          (write body-expr-1)))))
Ответил 27/11/2018 в 16:12
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more