简体   繁体   English

如何从输入模式中插入文字标识符作为语法规则宏中的符号

[英]How to insert literal identifier from input pattern as symbol in syntax-rules macro

I have code like this:我有这样的代码:

(define-syntax macron
  (syntax-rules ()
    ((_ name)
     (lambda (x)
       (eval (cons 'name x) (interaction-environment))))))

(define x (map (macron lambda)
               '(((x) (display x)) ((a b) (+ a b)))))

(let ((square (car x)) 
      (sum (cadr x))) 
  (display (square 10)) 
  (newline) 
  (display (sum 1 2 3)) 
  (newline))

the code is working it use macro as value by wrapping it with lambda.代码通过使用 lambda 包装它使用宏作为值。 My question is how can I put inside syntax-rule macro literal symbol 'name instead of (cons 'lambda...) so the output code is:我的问题是如何将语法规则宏文字符号'name而不是(cons 'lambda...)放入其中,所以 output 代码是:

(lambda (x)
  (eval (cons 'name x) (interaction-environment)))

so it work with code like this:所以它可以使用这样的代码:

(define (name x)
  (display x)
  (newline))

(for-each (macron lambda) ;; lambda can be anything
          '((1) (2) (3)))

and it print all the numbers.它打印所有的数字。

I know that I can change the name in pattern into something else, but I want to know more about syntax-rules and it's edge cases.我知道我可以将模式中的名称更改为其他名称,但我想了解更多关于语法规则及其边缘情况的信息。 So is it possible to have name if I use it as input pattern?那么,如果我将其用作输入模式,是否可以有名称?

I'm looking for answers with R7RS, that have more of this type of edge cases covered.我正在寻找 R7RS 的答案,它涵盖了更多此类边缘情况。

All macros happens in compile time so runtime stuff might not exist.所有宏都发生在编译时,因此运行时的东西可能不存在。 That means that you should think of it as syntax sugar and use it as susch.这意味着您应该将其视为语法糖并将其用作 susch。 eg.例如。

(for-each (macron something) '((1) (2) (3)))

Should then have an expansion based on that.然后应该在此基础上进行扩展。 Your current expansion is that it turns into this:您当前的扩展是它变成了这样:

(for-each (lambda (x)
            (eval (cons 'someting x) (interaction-environment))
          '((1) (2) (3)))

For something being a macro this will apply the macro in runtime.对于宏, something将在运行时应用宏。 It is bad.这是坏的。 It also removes the need for the macro in the first place.它还首先消除了对宏的需求。 You could do this instead:你可以这样做:

(define (macron-proc name)
  (lambda (x)
    (eval (cons name x) (interaction-environment))))

(for-each (macron-proc 'something) '((1) (2) (3)))

I made a programming language that had passable macros:我制作了一种具有可通过宏的编程语言:

(define xor (flambda (a b) `(if ,a (not ,b) ,b)))
(define (fold comb init lst)
  (if (null? lst)
      init
      (fold comb (comb (car lst) init) (cdr lst))))
(fold xor #f '(#t #t)) ; ==> #f

It's not a very good approach if you are targeting an efficient compiled end product.如果您的目标是高效编译的最终产品,这不是一个很好的方法。 The first macros were indeed like this and they removed it in LISP 1.5 before Common Lisp.第一个宏确实是这样的,他们在 Common Lisp 之前的 LISP 1.5 中删除了它。 Scheme avoided macros for many years and opted for syntax-rules in R4RS as an optional feature. Scheme 多年来一直避免使用宏,并选择 R4RS 中的syntax-rules作为可选功能。 R6RS is the only version that has full power macros. R6RS 是唯一具有完整功能宏的版本。

With a procedure instead of macros this is actually the same as the following code with the bad eval removed:使用过程而不是宏,这实际上与删除了错误eval的以下代码相同:

(for-each (lambda (x)
            (apply something x))
          '((1) (2) (3)))

Which means you can implement macron much easier:这意味着您可以更轻松地实现macron

(define-syntax macron
  (syntax-rules ()
    ((_ name)
     (lambda (x)
       (apply name x)))))

But from looking at this now you don't need a macro at all.但是从现在来看,您根本不需要宏。 This is partial application.这是部分应用。

(define (partial proc arg)
  (lambda (lst)
    (apply proc arh lst)))

(map (partial + 3) '((1 2) (3 4) (4 5)))
; ==> (6 10 12)

There is actually a SRFI-26 called cut / cute which allows us to do something similar where it wraps it in a lambda:实际上有一个名为cut / cuteSRFI-26 ,它允许我们做类似的事情,它将它包装在 lambda 中:

(map (cut apply + 3 <>) '((1 2) (3 4) (4 5)))

The syntax-rules are the macros with the least power. syntax-rules是功率最小的宏。 You cannot do anything unhygienic and you cannot make new identifiers based on other ones.您不能做任何不卫生的事情,也不能根据其他标识符制作新的标识符。 Eg.例如。 it' impossible to implement a racket style struct where you can do (struct complex [real imag]) and have the macro create complex?不可能在你可以做的地方实现球拍式struct (struct complex [real imag])并让宏创建complex? , complex-real , and complex-imag as procedures. complex-realcomplex-imag作为过程。 You need to do as SRFI-57 does and require th euser to specify all the names such that you don't need to concatenate to new identifiers.您需要像SRFI-57那样做,并要求用户指定所有名称,这样您就不需要连接到新的标识符。

Right now R7RS-small only has syntax-rules .现在 R7RS-small 只有syntax-rules I think it was a mistake not to have a more powerful macro as an alternative since now the R7RS-large cannot be implemented with R7RS-small.我认为没有更强大的宏作为替代方案是错误的,因为现在 R7RS-large 不能用 R7RS-small 实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM