Syntax 方案语法转换

Syntax 方案语法转换,syntax,scheme,Syntax,Scheme,我对这个计划还相当陌生,我一直在努力解决我认为应该是一个简单的问题 我正在尝试转换类似的东西 ((数量30)(名称“火腿”)至(三明治“@qty”30)(三明治“@name”“火腿”) 此外,这必须是动态的,以允许额外的条款: ((数量30)(名称为“火腿”)(奶酪编号)) 以下是我到目前为止的情况: (define-syntax (make-sandwiches x) (syntax-case x () [(_ ((col val)...) ) #``(

我对这个计划还相当陌生,我一直在努力解决我认为应该是一个简单的问题

我正在尝试转换类似的东西

((数量30)(名称“火腿”)
(三明治“@qty”30)(三明治“@name”“火腿”)

此外,这必须是动态的,以允许额外的条款:

((数量30)(名称为“火腿”)(奶酪编号))

以下是我到目前为止的情况:

(define-syntax (make-sandwiches x)
        (syntax-case x ()
            [(_ ((col val)...) ) #``(sandwich #,(format "@,~a" (caar #'((col val)...))) #,(cadar #'((col val)...)))] 
            [(_) "make-sandwiches is bad"]))
(制作三明治((数量30)(名称“火腿”)=>(参数“@#(语法数量)”30)

这有点接近,但它只翻译了第一个子句,所以我的想法是使用
map
或类似的东西,但我不确定这是否正确:

(define-syntax (make-sandwiches x)
        (syntax-case x ()
            [(_ ((col val)...)) (map (lambda (cv) #``(sandwich #,(format "@,~a" (caar cv)) #,(cadar cv))) #'((col val)...))] 
            [(_) "make-sandwiches is bad"]))
你真的需要使用宏吗?并返回多个值?一个简单的返回列表的过程可以实现以下目的:

(define (make-sandwiches lst)
  (map (lambda (data)
         (list 'sandwich
               (string-append "@" (symbol->string (car data)))
               (cadr data)))
       lst))
或者稍微短一点(你好像在用球拍):

例如,使用问题中的示例输入:

(make-sandwiches '((qty 30) (name "ham") (cheese 'no)))
=> '((sandwich "@qty" 30) (sandwich "@name" "ham") (sandwich "@cheese" 'no))
你真的需要使用宏吗?并返回多个值?一个简单的返回列表的过程可以实现以下目的:

(define (make-sandwiches lst)
  (map (lambda (data)
         (list 'sandwich
               (string-append "@" (symbol->string (car data)))
               (cadr data)))
       lst))
或者稍微短一点(你好像在用球拍):

例如,使用问题中的示例输入:

(make-sandwiches '((qty 30) (name "ham") (cheese 'no)))
=> '((sandwich "@qty" 30) (sandwich "@name" "ham") (sandwich "@cheese" 'no))

语法将在稍后的某个地方被发现,并期望类似(“客户三明治”(sandwich@“qty”30)(sandwich@“name”“ham”)@MikeB的东西是可以的,但我的观点是:如果您的输入是一个符号列表,而您的输出也是一个符号列表,我认为没有必要使用语法转换,有几个列表程序可以很好地工作。另外,请确保确实要返回多个值,这样的列表可能会更简单:'((sandwich“@qty”30)(sandwich“@name”“ham”)@MikeB,然后返回一个列表。您在过度设计解决方案,请保持简单!我刚刚用一个更通用的解决方案更新了我的答案,用于输入列表中未知数量的elements@MikeB我99%肯定那不是你想要的。在Scheme中,大多数情况下,当您想要返回多个值时,可以将它们打包到一个列表中,然后在调用端处理该列表。虽然可以使用
values
返回多个值,但在调用端这将是一个麻烦-对于初学者,您必须使用
let values
来解压缩它们,然后再次说明,这将不起作用,因为您不知道将有多少个值。相信我,列表是一种方法——只需在列表中重复搜索结果。奥斯卡有很好的建议。Scheme的两个相对特殊的特性是宏和多值。所以,当您学习Scheme时,想要使用它们是可以理解的。然而,这并不意味着它们是每项工作的正确工具。:)语法将在稍后的某个地方被发现,并期望类似(“客户三明治”(sandwich@“qty”30)(sandwich@“name”“ham”)@MikeB的东西是可以的,但我的观点是:如果您的输入是一个符号列表,而您的输出也是一个符号列表,我认为没有必要使用语法转换,有几个列表程序可以很好地工作。另外,请确保确实要返回多个值,这样的列表可能会更简单:'((sandwich“@qty”30)(sandwich“@name”“ham”)@MikeB,然后返回一个列表。您在过度设计解决方案,请保持简单!我刚刚用一个更通用的解决方案更新了我的答案,用于输入列表中未知数量的elements@MikeB我99%肯定那不是你想要的。在Scheme中,大多数情况下,当您想要返回多个值时,可以将它们打包到一个列表中,然后在调用端处理该列表。虽然可以使用
values
返回多个值,但在调用端这将是一个麻烦-对于初学者,您必须使用
let values
来解压缩它们,然后再次说明,这将不起作用,因为您不知道将有多少个值。相信我,列表是一种方法——只需在列表中重复搜索结果。奥斯卡有很好的建议。Scheme的两个相对特殊的特性是宏和多值。所以,当您学习Scheme时,想要使用它们是可以理解的。然而,这并不意味着它们是每项工作的正确工具。:)