是否可以定义具有与begin表单相同属性的宏?

时间:2016-12-30 15:07:00

标签: racket

更具体地说,我感兴趣的是begin的一个特定属性,其中正文中的定义添加到周围范围。例如。

(begin (define a 1)
       (define b 2))
(+ a b) ; 3

定义一个转换为标准my-begin的新宏begin会相当简单,但在我的特定用例中,我需要一个在开头绑定的所有标识符的列表,这样我就可以在别处介绍/使用它们了。

更具体地说明我想要实现的目标:我正在弄清楚如何构建一个PAR/AND运算符,同时评估两个分支(或者至少给出印象,给定上下文)。分支可能包含阻塞操作。两个分支返回后PAR/AND本身返回。任何定义都可在外围范围内获得。例如:

(PAR/AND     
  (define a (do-something))       ; branch 1
  (define b (do-something-else))) ; branch 2
(+ a b)

我还不确定如何实现它(因为我需要担心一些额外的东西),但在a范围之外使bpar/and可用是肯定是需要在某些时候发生的事情。

2 个答案:

答案 0 :(得分:3)

我会完全跳过关于define的部分,并确保表达式是并行完成的,然后当线程连接时使用values。在球拍中你有define-values,你可以在其中将多个值绑定到全局名称,它可以用来命名你计算的值:

(define-values (a b)
  (parallel/values (do-something) (do-something-else)))
(+ a b)
; ==> 1337

paralell/values需要在这里使用语法,但由于表达式本身就是thunk,你实际上可以保留一个带有thunk的过程:

(define-values (a b)
  (parallel/values do-something do-something-else))
(+ a b)
; ==> 1337

如您所见,这根本不需要自定义begin。我希望并行的表达式会引入会影响define的闭包,所以这也可以避开蠕虫。如果您在禁用宏隐藏的情况下查看宏扩展器中的完整扩展程序,则define-values 球拍中的实际define原语

答案 1 :(得分:1)

有很复杂的方法可以做到这一点,但看起来还有一个简单的方法:你不能将PAR/AND宏扩展为begin吗?