Common Lisp学习之九:使用包

Common Lisp 学习书目 书籍 1、《Common Lisp: A Gentle Introduction to Symbolic Computation》 English Version:http://www.cs.cmu.edu/~dst/LispBook/ 中文版:无 适用于无编程基础人士 2、《Common Lisp the Language, 2nd Edition》 English Vers 阅读详情
1 读取器如何处理包
每个包都有名字,(find-package name)可以通过包名来找到一个包。解释器当前使用包存储于全局变量*package*中。包的字面形式为#<Package "pkg-name">。
(package-name pkg)可以返回一个包的名称。

包可看作一个字符串和符号的映射表,读取器使用(find-symbol name)和intern通过名字来查找特定包中的某个符号。二者的区分是后者会在符号不存在时,在包中创建这个新的符号。反向的(symbol-name symb)将反查一个符号的名字字符串表示。

通常我们使用的名字大多是非限定的,即名字里不带冒号。读取器遇到这种名字时,会将名字中所有未转义的字母转换为大写形式,然后将其传递给Intern,为名字返回一个符号对象。

含有单冒号的名字指向外部符号,即这些符号被包导出为外部可见的符号。当读取器遇到这类名字中,将名字在:号外拆分,前一部分作为包名,后一部分作为符号名,读取器查找适当的包并用它来将名称转换成符号对象。如果命名的包中不存在对应名称的符号或符号并不是外部可见,则读取器会出错。

关键字符号是另外一种含有单冒号的名字,这类符号在包为KEYWORD的包中创建并自动导出。

含有双冒号的名字可指向包中的任何符号,这通常不是好作法-因为这样可以访问到本意保留为私有的符号。

可以在REPL中,输入cl:和cl::后按tab,能看到包中的符号名称。

以#:开始的名字为unintern符号,即符号不属于任何包,每当读取器遇到这样的名字时,都会重新为此名字创建一个符号。gensym返回的就是这种名字。


2 符号与包相关术语

可访问符号:在一个给定包中,可通过find-symbol找到的符号

有两种方式使得一个符号在包中可访问。
一种是符号归属于一个包,称这个包是符号的home-package,这样包的"名称-符号"表中存在此符号的项。(package-name (symbol-package 'sym-name))可以查找一个符号最初来源于哪个包。
另一种方式是当一个包通过use使用另一个包时,前者便继承了后者导出的外部符号,从而可访问继承的符号,使得这些符号进入前者的"名称-符号"表中,称为导入。这样一个符号可以同时存在于多个包中。

包系统只允许每个名字在给定的包中指向单个符号。这样如果继承自多个包中有重名符号,或者自身定义有和使用的包中重名的符号是不允许的。必须将冲突的名称之一进行屏蔽(shadow)。每个包都维护了一个屏蔽符号表。

一个已有的符号可以从包中unintern,这会导致其被清除出"名称-符号"表,如果它是一个隐蔽符号,其也会被清除出隐蔽符号列表。

3 标准包
COMMON-LISP-USER包,也叫CL-USER包,是Lisp环境的默认载入包。所有用户自定义的符号会被导入其中。
COMMON-LISP包,这个包导出了语言标准定义的所有名字,其被CL-USER包所使用。
KEYWORD包,这个包被Lisp读取器用来创建以冒号开始的名字。

4 使用包
与Java的包机制不同,CL的包无法提供诸如谁可以调用什么函数或访问什么变量的直接控制。其只是通过控制如何将文本名转换为称号对象来提供对于名字空间的基本控制。

自定义包通过defpackge来完成:
(defpackage :cn.edu.bupt.some-name
    (:use :common-lisp ...:other-package)
    (:import-from :the-package :the-oper1 ..)
    (:shadow :op :op ...)
    (:export :oper1 :oper2 ... :opern))

包的命名类似于Java世界的作法,采用URI的反转形式。
use指定需要继承的包,系统默认继承COMMON-LISP包。包的写法可以是关键字法,这时允许使用小写字符。如果为字符串,则需要使用大写形式,如”COMMON-LISP"。

如果只需要导入特定包中的某些符号,则使用import-from的形式。可以有多个子句以从不同的包中导入。有时只需要屏蔽包中的少数符号,此时可以直接使用整个包,但把不需要的符号通过:shadow进行屏蔽。

有时从多个包继承时会遇到名字冲突,但我们需要其中的一个符号,此时使用:shoadow-import-from来导入一个冲突的符号。

需要导出符号的可以使用:export来进行说明。这样在其使用者包中,可以直接访问,而无需采用限定名的方式访问。

(in-package :name) 可以切换到指定包的上下文中,直到另一个in-package调用来改变它。其是一个宏。

此外函数或宏,如(use-package),其反转操作为(unuse-package)。(export ),其反转操作为(unexport )。(import )等,均可defpackage完成,不建议使用这些东西。

5 包定义的组织
系统要求包在它们被用到之前总是存在。最佳方式是把包定义与使用它们的源代码放到分开的文件里。
一种方式是每个包定义一个文件,另一种是把一系列包定义放在一个文件中。前者对文件的加载顺序提出了要求。
编译时,必须先加载包定义,再编译从包里读取符号的文件。对于大型项目,需要使用项目组织工具如ASDF来处理加载顺序这一问题。

另一个问题是每个文件只应该含有一个in-package形式,并且其为除注释以外的第一行。含有包定义的文件,应当以(in-package :common-lisp-user)的形式开始。

最后要注意的是包名也有冲突的可能性。

6 一些难题
第一个难题由于不经意的intern导致名字冲突的问题。例如未导入包时访问一个符号,由于此符号未定义,因而读取器会创建之,并调用求值器,求值器会导致系统会进入再启动,恢复之后导入包时,再调用同名符号时会遇到名称冲突的问题。此时需要清除先前引入的符号定义。

第二个难题是使用一个包后,新定义的符号和使用包的名称冲突,此时编译时会提示重定义,需要对其进行解决。

第三个难题是切换到其他包里工作,但未切换回CL-USER包,此时quit指令失效。

最后牢记的是:包是读取器的一部分,不是求值器的部分。

7 更多关于符号
符号是Lisp中的一种原子数据类型,每个符号都是一个对象。和数一样,符号的含义依赖于如何解释它。通常符号不对自身求值,因此对于符号需要用'引用它。读取器会将其转换为大写形式。符号可以使用字符串来当作其名字,通过symbol-name可以获取符号的名字。

每个符号都有一个属性列表,称为plist。其实际上是一个键值对,可以用get来访问其中的键值。
(get symbol 'key)
可以使用setf来设置键值。属性列表。例如可以为color键设置为red。
(setf (get symbol 'color) red)

结合包的名称-符号表,符号有如下的结构:

一个令人困惑的事情是,符号与变量从两个不同的层面上存在关联。
当符号是special variable的名字时,变量的值存在于value槽,可以用symbol-value引用。
当符号是词法变量时,其只是个占位符,编译器会将其转为一个寄存器引用或内存的地址。在编译出的代码中无法追踪这个符号(除非使用调试器外加符号表才能进行追踪),只要一有值,符号就消失了。

8 更多与包相关的概念
Package 
     这个相当于 C++ 里的 namespace,它对应的是符号所处的命名空间,并不对应到文件。package 是在代码运行时才产生的,CL 报错说某个 package 找不到并不是说哪个文件找不到,而是 CL 运行环境 
里找不到这个包的定义。  
  
System 
     一堆文件加一个 CL 版的 Makefile,组合在一起称为一个 system。这里的 "Makefile" 常见的就是 .asd 文件,"make" 对应到 ASDF。这种 "make" 还有 mk:defsystem。 
  
Module 
     一个代码集合,用 (require 'module-name) or (require :module-name) or (require "module-name") 加载此 CL 实现相关的库,具体哪种形式可行取决于 CL 实现。 有的 CL 实现可以用这个方式加载 ASDF 类型的库。 
  
Library 
     提供某功能的代码库。  

学习 Lisp 语言的相关书籍 Lisp语言难以推广的原因有很多,而相对来说,比较高额的学习成本便是这众多原因的其中之一 ...... 阅读详情

相关推荐

Common Lisp学习资源:练习与解决方案大全

本文还有配套的精品资源,点击获取 简介:Common Lisp是一种历史悠久且应用广泛的编程语言,以其独特的语法、灵活性和强大的宏系统而知名。这个项目“learninglisp”提供了丰富的练习和解决方案,帮助学习者逐步掌握Lisp编程。项目内容包括S表达式的使用,符号计算的能力,以及一系列教程、练习题目、解决方案、测试脚本、代码片段和阅读材料。通过这些资源,学习者可以深入...

weixin_36369848的博客 1364

Common Lisp包系统完全指南

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34367257的博客 511

Lisp打包下载(四本关于lisp的书)

1.Common Lisp the Language 2nd Edition 2.Editor Guide 3.LispWorks for User Guide 4.Quick reference for Common Lisp

lisp语言代替python_Reddit 为什么放弃 Common Lisp 用 Python?

无所谓开端,倘若只看结局的话,可以侧面说明:Python(Pylons) 大法好。那么简单说下 Pylons 的思想好在哪里吧,其实就是在 web 领域充分利用了 Python 的语言特性(所谓的胶水语言),ORM 有 SQLAlchemy,模板有 Mako,WSGI 这边有 WebOb,配置管理这边有 paste.deploy,表单验证有 FormEncode,会话机制有 Beaker,etc....

weixin_42539414的博客 278

《实用Common Lisp编程》

Common Lisp,缩写为 CL(不要和缩写同为CL的组合逻辑混淆),是Lisp的众多方言之一,标准由ANSI X3.226-1994定义。它是为了标准化此前众多的Lisp分支而开发的,它本身并不是一个具体的实现而是各个Lisp实现所遵循的规范。它操作的数据是动态数据类型,但也可用的类型声明来提高效率和增强安全性。

字符串查找与替换程序 文件

字符串替换函数:用于将指定字符串中指定的字符串替换为新的字符串

lisp初体验-Practical Common Lisp笔记-10.自定义宏

一般来说,凡是带有自定义的东东都会显得很专业,不过在lisp中,这才算刚刚开始。至于你信不信,反正我是信了。就让我们开始吧。 说来有些不可理喻,宏之所以难以理解,是因为它在lisp中太过自然(天生的阿),运用起来毫不费力。以至于很容易被误解为一个有意思的函数。事实上,虽然宏真的很像函数,但仅仅是像而已。他们完全不在一个层面上,抽象的层次也大不相同。 一旦理解了宏和函数的区别,恭喜你,晋...

风吹鸡蛋壳 267

Python-用CommonLisp实现的NES模拟器

用Common Lisp实现的NES模拟器

LISP 学习笔记 (二)-自定义函数

第二笔——自定义函数如果你想定义自己的函数,可以通过使用“defun” 函数,defun 函数的格式是:(defun a1 (a2) (a3))。其中: a1 是你要定义的函数标识符,通常是用字符串来表示的一个函数名称; a2 是所要定义函数的参数列表(一个或多个参数),括号是必须的; a3 是用来计算所要定义函数的表达式,也就是函数体。括号不是必须的。

xiejianming的专栏 2695

names:Emacs-Lisp 的命名空间实现

姓名 Names被设计为一种实用、完整、健壮且可调试的工具,可为您编写命名空间。 它是 Emacs 的一部分,可通过,因此每个运行至少 24.1 的 Emacs 用户都可以访问它。 使用 Names 命名 emacs-lisp 函数的示例用法。 Emacs-Lisp 的命名空间实现 Names包旨在通过四个指导原则在 Emacs 中提供命名空间的实现: 实际的 实际上有用且易于掌握。 完全的 支持 emacs-lisp 中可用的任何宏、函数或特殊形式,甚至是您或第三方定义的。 强壮的 毫无意外,经过充分测试,并有明确规定的限制。 可调试 支持edebug和eval-defun defun ,以及任何其他包开发工具。 请参阅 有关为什么需的说明,请参阅以获取对以前尝试类似事物的软件包的描述和比较。 版本兼容性 目前,整个 Emacs 24 系列 (24.1–24.4) 都支

从零到一:手把手教你用Python搭建医学影像识别CNN模型(附完整代码)

本文详细介绍了如何使用Python和TensorFlow/Keras从零开始构建一个医学影像识别的CNN模型,涵盖数据预处理、模型架构设计、训练调优及部署全流程。通过实战案例和完整代码,帮助开发者快速掌握深度学习在医学影像识别中的应用,特别适合医疗AI领域的初学者和研究者。

spark7igniter的博客 200

初识common lisp

学习任何语言都需要一个编译器,common lisp 也不例外,编写common lisp的常用工具是emacs + slime +(任意一种CL实现,常用的有SBCL,cmucl)作为初学这的我们为了方便我直接使用的lispbox,lispbox实际是是emacs+slime+ccl极大的方便了我们这些初学者,大家可以到这里下载http://common-lisp.net/project/lis

暗夜精灵 1135

RV1126平台JD9366触摸屏驱动移植实战:从源码到烧录的完整指南

本文详细介绍了在RV1126平台上移植JD9366触摸屏驱动的完整流程,从环境准备、源码获取到驱动配置、内核编译、设备树设置以及固件烧录与测试验证。通过实战经验分享和常见问题排查,帮助开发者高效完成触摸屏驱动移植,适用于嵌入式Linux开发场景。

weixin_30872337的博客 408

探索Common Lisp学习宝库:Awesome Common Lisp Learning

探索Common Lisp学习宝库:Awesome Common Lisp Learning 项目介绍 欢迎来到Awesome Common Lisp Learning,这是一个专注于Common Lisp学习资源的精选列表。无论你是初学者还是经验丰富的Lisp程序员,这里都有丰富的资料帮助你深化对这一强大编程语言的理解。项目不仅提供了从基础到高级的学习路径,还包括了各种环境设置、在线参考、书籍推...

gitblog_00450的博客 418

R语言pls包实战:手把手教你用偏最小二乘(PLS)搞定高维数据回归(附完整代码与数据标准化避坑指南)

本文详细介绍了如何使用R语言的pls包进行偏最小二乘(PLS)回归分析,特别针对高维数据回归问题。通过完整的代码示例和数据标准化避坑指南,帮助读者掌握从数据预处理到模型优化的全流程,解决实际应用中的常见问题。

weixin_42662605的博客 350

薛定谔虚拟筛选实战:如何用PDB文件快速构建受体格点(避坑指南)

本文提供了薛定谔虚拟筛选实战指南,聚焦于如何从PDB文件快速、精准地构建受体格点。文章详细解析了可变残基的理性处理策略、基于配体尺寸的盒子量化设置方法,并分享了高级约束与排除体积的实战技巧,旨在帮助用户避开常见陷阱,提升虚拟筛选的成功率与效率。

weixin_28419039的博客 252

如何通过Lisp Koans快速掌握Common Lisp:终极学习指南

Common Lisp Koans是一个语言学习练习项目,它以有序的单元测试组形式,引导学习者逐步掌握Common Lisp的众多语言特性。本文将详细介绍如何利用这个项目高效学习Common Lisp,从环境搭建到进阶练习,让你快速踏上Lisp编程之旅。 ## 什么是Lisp Koans? Lisp Koans是一种基于测试驱动的学习方法,类似于Ruby Koans和Python Koans。

gitblog_00693的博客 913

青岛鼎信Java开发面试题及参考答案(3万字长文,多张原理图)

MySQL 的事务特性有哪些? MySQL 事务具有四个重要特性,被称为 ACID 特性。 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么全部执行,要么全部不执行。例如,在银行转账场景中,从账户 A 转账到账户 B,包括扣减账户 A 的金额和增加账户 B 的金额这两个操作必须作为一个整体来完成。如果在执行过程中发生错误,比如系统崩溃或者数据库出现故障,那么已经执行的部分必须全部回滚,就好像整个转账操作从未发生过一样。 一致性(Consistency):事务必须

大模型大数据攻城狮的专栏 1088

CLX:开源的Common Lisp X11客户端库

CLX:开源的Common Lisp X11客户端库 项目介绍 CLX 是一个面向 Common Lisp 的 X11 客户端库。它起源于 CMUCL 分发版本,经过修改以适应 SBCL 编译和运行,同时还整合了网络上其他 CLX 版本的精选补丁。CLX 为 Common Lisp 开发者提供了一个与 X11 系统交互的接口,使得图形界面编程在 Lisp 中变得更加可行。 项目技术分析 CLX 的...

gitblog_00451的博客 930

《PCI Express体系结构导读1》-- PCI简介

请先阅读完一遍此书再来看文章哦,这样效率更高~

HoneyIC的博客 151

让 ABAP BAPI_COSTACTPLN_POSTPRIMCOST 不再沉默:一套可落地的参数一致性校验与排错打法

SAP BAPI_COSTACTPLN_POSTPRIMCOST 沉默失败分析与解决方案 问题现象 使用 BAPI_COSTACTPLN_POSTPRIMCOST 上传计划数据时,接口执行不报错但数据未写入 COSP 等计划表,呈现"沉默失败"现象。 根本原因 索引关联断裂:INDEXSTRUCTURE 中 OBJECT_INDEX 和 VALUE_INDEX 未正确关联 COOBJECT 和 PERVALUE/TOTVALUE 表的数据 对象定义冲突:COOBJECT 中同一行填写了多

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 108

推荐项目:Emacs for Common Lisp(Emacs4CL)

推荐项目:Emacs for Common Lisp(Emacs4CL) 在众多编程环境之中,Emacs因其可塑性和强大的扩展性,成为许多程序员的首选。特别是对于Common Lisp这一历史悠久且充满智慧的语言,有一个名为Emacs for Common Lisp (Emacs4CL) 的项目,它简化了在Emacs中设置Common Lisp开发环境的过程,使得初学者能更快地跨过入门的门槛,让...

gitblog_00125的博客 1064

098、C3k2_Ghost:用 GhostConv 替代 C3k2 内标准卷积的轻量化改造代码

本文介绍了用GhostConv轻量化改造YOLOv11中C3k2模块的实践。作者通过线上部署案例引出问题,详细解析了GhostConv的核心实现逻辑,指出直接替换标准卷积会导致的两个关键问题:通道数不匹配和kernel_size冲突。文章提供了完整的C3k2_Ghost实现代码,包含注意事项和调试技巧。消融实验显示,该方法在小模型上可减少27%-28%参数量、34%-35%FLOPs,仅损失0.8mAP。作者总结了适用场景:小模型效果显著,大模型需谨慎;检测小目标任务不推荐;训练时需调整学习率。最后强调sh

sundong_81的博客 62

Common Lisp 编程语言深度解析

CommonLisp是Lisp家族的主要方言,作为世界上第二古老的高级编程语言,以其强大的功能和灵活性著称。它采用S-表达式和"代码即数据"的哲学,支持REPL驱动的交互式开发,并拥有独特的宏系统,可实现元编程和语言扩展。CommonLisp融合了函数式、面向对象(通过CLOS)等多种编程范式,提供高性能和动态类型检查,适合人工智能、符号计算和复杂系统开发。尽管学习曲线陡峭,但其卓越的表达力和生产力使其在特定领域保持独特价值。

bulita great world 1422

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Steel Bank Common Lisp (SBCL) 开源项目教程

Steel Bank Common Lisp (SBCL) 是一个高性能的 Common Lisp 编译器和运行时环境。它是一个开源项目,旨在提供一个高质量、高性能的 Common Lisp 实现。SBCL 不仅支持标准的 Common Lisp 语言特性,还提供了许多扩展功能,如垃圾回收、多线程支持、调试工具等。 SBCL 的核心优势在于其高性能和稳定性,使其成为许多开发者和研究者的首选 Co...

gitblog_00614的博客 1428

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

NumCL实战案例:用Common Lisp实现机器学习算法的基础步骤

NumCL是一个在Common Lisp中实现的Numpy克隆库,为开发者提供了强大的数组操作和数值计算能力。本文将通过实战案例,详细介绍如何使用NumCL构建机器学习算法的基础组件,包括数据准备、矩阵运算和模型训练等关键步骤。 ## 📊 准备工作:安装与环境配置 要开始使用NumCL进行机器学习开发,首先需要克隆项目仓库并配置Common Lisp环境: ```bash git clon

gitblog_00186的博客 796
上一篇: Common Lisp学习之八:异常状况处理
下一篇: Common Lisp学习之十:输出格式化控制与高级循环控制
zzulp
博客等级 码龄19年 464粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值