gpt4 book ai didi

lisp - Lisp 如何让您重新定义语言本身?

转载 作者:行者123 更新时间:2023-12-03 05:42:11 29 4
gpt4 key购买 nike

我听说 Lisp 可以让你重新定义语言本身,我也试图研究它,但没有任何地方明确的解释。有人有一个简单的例子吗?

最佳答案

Lisp 用户将 Lisp 称为 可编程编程语言 .用于符号计算 - 用符号计算。

宏只是利用符号计算范式的一种方式。更广泛的愿景是 Lisp 提供了描述符号表达式的简单方法:数学术语、逻辑表达式、迭代语句、规则、约束描述等等。宏(Lisp 源代码形式的转换)只是符号计算的一种应用。

这有某些方面:如果您询问“重新定义”语言,那么严格重新定义将意味着重新定义一些现有的语言机制(语法、语义、语用学)。但也有语言特征的扩展、嵌入、移除。

在 Lisp 传统中,有许多尝试提供这些特性。 Lisp 方言和某个实现可能只提供其中的一个子集。

一些主要 Common Lisp 实现提供的重新定义/更改/扩展功能的方法:

  • s 表达式语法 . s 表达式的语法不是固定的。阅读器(函数 READ)使用所谓的 读表指定读取字符时将执行的函数。可以修改和创建读取表。例如,这允许您更改列表、符号或其他数据对象的语法。还可以为新的或现有的数据类型(如哈希表)引入新的语法。也可以完全替换 s-expression 语法并使用不同的解析机制。如果新的解析器返回 Lisp 形式,则解释器或编译器不需要更改。一个典型的例子是可以读取中缀表达式的读取宏。在这样的读取宏中,使用了中缀表达式和运算符的优先规则。读取宏与普通宏不同:读取宏在 Lisp 数据语法的字符级别上工作。
  • 替换功能 .顶级函数绑定(bind)到符号。用户可以更改此绑定(bind)。大多数实现都有一种机制,即使对于许多内置函数也允许这样做。如果你想为内置函数 ROOM 提供一个替代方案,你可以替换它的定义。某些实现会引发错误,然后提供继续更改的选项。有时需要解锁包裹。这意味着通常可以用新定义替换函数。有限制。一是编译器可以在代码中内联函数。要查看效果,则需要重新编译使用更改后的代码的代码。
  • 咨询职能 .人们常常想为函数添加一些行为。这在 Lisp 世界中被称为“建议”。许多 Common Lisp 实现将提供这样的功能。
  • 定制包 .包在 namespace 中对符号进行分组。 COMMON-LISP 包是所有属于 ANSI Common Lisp 标准的符号的所在地。程序员可以创建新包并导入现有符号。因此,您可以在程序中使用提供更多或不同功能的 EXTENDED-COMMON-LISP 包。只需添加 (IN-PACKAGE "EXTENDED-COMMON-LISP"),您就可以开始使用您自己的 Common Lisp 扩展版本进行开发。根据使用的命名空间,您使用的 Lisp 方言可能看起来略有不同,甚至完全不同。在 Lisp 机器上的 Genera 中,有几种 Lisp 方言以这种方式并列:ZetaLisp、CLtL1、ANSI Common Lisp 和 Symbolics Common Lisp。
  • CLOS 和动态对象。 Common Lisp 对象系统带有内置的更改。元对象协议(protocol)扩展了这些功能。 CLOS 本身可以在 CLOS 中扩展/重新定义。你想要不同的继承。写一个方法。您需要不同的方式来存储实例。写一个方法。插槽应该有更多的信息。为此提供一个类。 CLOS 本身的设计使其能够实现不同面向对象编程语言的整个“区域”。典型的例子是添加原型(prototype)之类的东西,与外部对象系统(如目标 C)的集成,添加持久性,......
  • Lisp 表单 . Lisp 形式的解释可以用宏重新定义。宏可以解析它所包含的源代码并对其进行更改。有多种方法可以控制转换过程。复杂的宏使用 code walker,它理解 Lisp 形式的语法并可以应用转换。宏可以是微不足道的,但也可以像 LOOP 或 ITERATE 宏一样变得非常复杂。其他典型示例是用于嵌入式 SQL 和嵌入式 HTML 生成的宏。宏还可用于将计算移动到编译时。由于编译器本身就是一个 Lisp 程序,因此可以在编译期间进行任意计算。例如,如果在编译期间已知某些参数,Lisp 宏可以计算公式的优化版本。
  • 符号 . Common Lisp 提供了符号宏。符号宏允许更改源代码中符号的含义。一个典型的例子是这样的: (with-slots (foo) bar (+ foo 17)) 这里用 WITH-SLOTS 包围的源代码中的符号 FOO 将被替换为调用(插槽值 bar 'foo)。
  • 优化 ,使用所谓的编译器宏可以提供某些功能的更有效版本。编译器将使用这些编译器宏。这是用户进行程序优化的有效方式。
  • 条件处理 - 处理以某种方式使用编程语言所导致的条件。 Common Lisp 提供了一种处理错误的高级方法。条件系统还可用于重新定义语言特征。例如,可以使用自写的自动加载机制处理未定义的函数错误。当 Lisp 看到一个未定义的函数时,错误处理程序可以尝试自动加载函数并在加载必要的代码后重试操作,而不是在调试器中登陆。
  • 特殊变量 - 将变量绑定(bind)注入(inject)现有代码。许多 Lisp 方言,如 Common Lisp,提供特殊/动态变量。它们的值在运行时在堆栈上查找。这允许封闭代码在不更改现有代码的情况下添加影响现有代码的变量绑定(bind)。一个典型的例子是像 *standard-output* 这样的变量。可以重新绑定(bind)该变量,并且在新绑定(bind)的动态范围内使用该变量的所有输出都将走向新的方向。 Richard Stallman 认为这对他来说非常重要,因为它在 Emacs Lisp 中被默认了(尽管 Stallman 知道 Scheme 和 Common Lisp 中的词法绑定(bind))。

  • Lisp 具有这些和更多的功能,因为它已被用于实现许多不同的语言和编程范式。一个典型的例子是一种逻辑语言的嵌入式实现,比如 Prolog。 Lisp 允许用 s 表达式和特殊的编译器来描述 Prolog 术语,Prolog 术语可以编译成 Lisp 代码。有时需要通常的 Prolog 语法,然后解析器会将典型的 Prolog 术语解析为 Lisp 形式,然后将其编译。嵌入式语言的其他示例是基于规则的语言、数学表达式、SQL 术语、内联 Lisp 汇编程序、HTML、XML 等等。

    关于lisp - Lisp 如何让您重新定义语言本身?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2307562/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com