Macros 我的lisp宏在最新guile中停止工作

Macros 我的lisp宏在最新guile中停止工作,macros,scheme,lisp,guile,lisp-macros,Macros,Scheme,Lisp,Guile,Lisp Macros,我在2010年写了一个宏,它是用来管理结构的,比如使用Alists管理Common Lips(这里是包含函数的整个文件) (定义宏(defstruct name.fields) “基于assoc列表在guile中实现宏结构。” (let((名称(映射(lambda(符号)(gensym))字段)) (结构(gensym)) (字段arg(gensym))) `(如果(不是(每个唯一字段)) (错误“defstruct”字段必须唯一) (开始 (定义(,(生成名称),@names) (映射cons

我在2010年写了一个宏,它是用来管理结构的,比如使用Alists管理Common Lips(这里是包含函数的整个文件)

(定义宏(defstruct name.fields)
“基于assoc列表在guile中实现宏结构。”
(let((名称(映射(lambda(符号)(gensym))字段))
(结构(gensym))
(字段arg(gensym)))
`(如果(不是(每个唯一字段))
(错误“defstruct”字段必须唯一)
(开始
(定义(,(生成名称),@names)
(映射cons',字段(列表,@names)))
,@(图(λ(场)
`(定义(,(生成getter名称字段),结构)
(cdr(assq',field,struct)))字段)
,@(图(λ(场)
`(定义(,(生成setter name字段),结构,字段arg)
(assq集合,结构,字段,字段参数)
,字段arg)字段)
(定义(,(生成谓词名称),结构)
(和(struct?,struct)
(let((结果#t))
(每个(λx y)
(如果(不是(等式x y))(设置!结果#f)))
“,字段
(地图车,结构)
结果(()()()))
它工作得很好。我最近为我的(基于scheme)更新了这个宏,当我调用它时,它返回了
false
,我想知道这是否是guile中的工作方式。但事实证明这根本不起作用。它显示了这个错误:

编译表达式时:错误:语法错误:未知位置: 表达式上下文中的定义,其中不允许定义, 在形式上(定义(制造点#{g746}##{g747}#)(地图图标(引用x y) )(列表{g746}{g747})

为什么我会出现这个错误,以及如何修复它,这样它又能在guile中工作?我很久以前就不记得我是如何测试这段代码的了,但使用load函数打开guile或将代码复制粘贴到解释器中都会产生相同的错误

我在GNU/Linux上使用Guile2.0.14


PS:我更喜欢使用lisp宏,因为它们比奇怪的scheme宏更好。

现代guile scheme似乎不认为if中的begin是启动新定义上下文的有效选项。这可能是一个bug,或者scheme规范的更好对齐方式。但下面的示例代码显示了修复您的错误的技术最近guile的代码(您可能需要创建define value,因为它是guile.P.S.的最新添加。在guile中使用lisps宏是一个难题,如果您计划进行大量规划,它会给您带来麻烦,宏就像parens,如果您习惯了它会觉得很自然

这是密码

(define-macro (defstruct name . fields)
   "Macro implementing structures in guile based on assoc list."
   (let* ((names (map (lambda (symbol) (gensym)) fields))
          (struct    (gensym))
          (field-arg (gensym))
          (sname     (make-name name))
          (predname  (make-predicate name))
          (getnames  (map (lambda (f) (make-getter name f)) fields))
          (setnames  (map (lambda (f) (make-setter name f)) fields)))

      `(define-values (,sname ,predname ,@getnames ,@setnames)
         (if (not (every-unique ',fields))
             (error 'defstruct "Fields must be unique")
             (let ()
               (define (,sname ,@names)
                 (map cons ',fields (list ,@names)))
               ,@(map (lambda (field)
                  `(define (,(make-getter name field) ,struct)
                      (cdr (assq ',field ,struct)))) fields)
               ,@(map (lambda (field)
                  `(define (,(make-setter name field) ,struct ,field-arg)
                      (assq-set! ,struct ',field ,field-arg)
                  ,field-arg)) fields)
               (define (,predname ,struct)
                  (and (struct? ,struct)
                       (let ((result #t))
                          (for-each (lambda (x y)
                             (if (not (eq? x y)) (set! result #f)))
                           ',fields
                          (map car ,struct))
                          result)))

                 (values ,sname ,predname ,@getnames ,@setnames))))))
这是一个版本的
定义值
(查看
#'
后面的代码,了解它的作用)


我认为
if
可能是在编译时完成的(在宏中,而不是结果),因为
字段是给定的。因此结果可能是
(begin…)
而没有
if
(define-syntax define-values
   (lambda (x)
      (syntax-case x ()
        ((_ (f ...) code ...)
         (with-syntax (((ff ...) (generate-temporaries #'(f ...))))
           #'(begin
               (define f #f)
                ...
               (call-with-values (lambda () code ...)
                  (lambda (ff ...)
                     (set! f ff)
                     ...))))))))