Lisp 非平凡的fexpr用法示例

Lisp 非平凡的fexpr用法示例,lisp,Lisp,我正在寻找FEXPR的(真实世界)用途,它们的使用方式与惰性评估不同 我能找到的大多数示例都只使用FEXPR来实现条件求值,比如短路和操作(求值第一个参数,如果为false,则不求值第二个参数,直接返回false) 我在寻找“有用”的用法,也就是说,使用fexpr可以得到比没有fexpr更好(更干净)的代码。使用fexpr有两个主要原因 第一个是因为它们允许您对参数进行任意次数的求值。这使得实现像您建议的那样惰性地评估其参数的运算符成为可能。以这种方式构建的构造也能够多次评估其参数。这使得通过F

我正在寻找FEXPR的(真实世界)用途,它们的使用方式与惰性评估不同

我能找到的大多数示例都只使用FEXPR来实现条件求值,比如短路和操作(求值第一个参数,如果为false,则不求值第二个参数,直接返回false)


我在寻找“有用”的用法,也就是说,使用fexpr可以得到比没有fexpr更好(更干净)的代码。

使用fexpr有两个主要原因

第一个是因为它们允许您对参数进行任意次数的求值。这使得实现像您建议的那样惰性地评估其参数的运算符成为可能。以这种方式构建的构造也能够多次评估其参数。这使得通过FEXPR实现循环成为可能


另一种情况是转型。转换代码基本上是在现有Lisp之上编写编译器的一种方法。虽然它使用宏而不是Fexpr,但这是一个可以进行转换的很好的例子。

Fexpr与惰性/急切求值有点正交

通常的函数方法是对函数的参数求值,然后对结果调用它。Lazy eval的行为仍然是这样的,它只是将求值延迟到使用参数之前

通常的宏方法是将未赋值的参数传递到一个模板中,该模板对任何未引用的参数进行求值。生成的AST片段被注入调用站点,在那里它通常被再次评估。这与lazy eval的工作原理大致相同

历史上疯狂的fexpr方法是将未赋值的参数传递给函数,函数可以随意处理这些参数。结果直接注入调用站点,通常不会自动评估

fexpr非常接近于任意变换。因此,您可以使用它们实现宏和lambda。您还可以实现任何您希望的渴望/懒惰评估的混合。同样,您也可以在不同的地方实现fexpr,并在给定默认的lazy eval和对eval()的显式调用的情况下强制执行急切行为


我不认为我会将fexpr描述为实现懒惰评估的一个简单解决方案,尽管在某种意义上,治疗比疾病更糟糕

通过fexprs,您指的是实际的还是实际的?我这样问是因为绝大多数现代Lisp使用宏而不是FEXPR。FEXPR在80年代在主流Lisp中消亡,并被宏所取代。宏用于抽象语法。通过延迟求值,所有特殊形式都可以是函数,因此您可以使用函数实现语法,因为在需要计算某些内容之前,求值是不会发生的。通常这两种语言是不同的,所以当它们可能从未在一种语言中相遇时,我看不出这两种语言是如何进行比较的。@malisper是的,我指的是实际的FEXPR,或者如果你愿意的话是“文本呼叫”。@Sylvester我知道,但据我所知(当时我甚至都不活着,所以这纯粹是基于我听到/读到的)这更多地与动态范围引入的问题有关,而不是fexpr本身。我正在寻找FIEPRS的使用,不能用懒惰的评价(容易地)来实现,例如考虑一个FEXPR,它将汽车的每一个事件都改变为CDR。我对语言设计很感兴趣,所以尽管这两个“特性”在一种语言中可能直到现在才相遇,但这并不一定要保持这种状态。