老古董Lisp实用主义入门教程(12):白日梦先生的白日梦

白日梦先生的白日梦
白日梦先生已经跟着大家一起学Lisp长达两个月零五天!
- 001 粗鲁先生Lisp再出发
- 002 懒惰先生的Lisp开发流程
- 003 颠倒先生的数学表达式
- 004 完美先生的完美Lisp
- 005 好奇先生用Lisp来探索Lisp
- 006 好奇先生在Lisp的花园里挖呀挖呀挖
- 007 挑剔先生给出终止迭代的条件
- 008 挠痒痒先生建网站记
- 009 小小先生学习Lisp表达式
- 010 聪明先生拒(ji)绝(xu)造轮子
- 011 没人先生学习Lisp函数
他已经能够:
- 安装库文件、探索库函数、调用库函数
- 定义函数、调用函数
- 操纵列表
- 递归、迭代
- 表达式替换,表达式求值
- 判断相等
- 建立一个网站!!!
白日梦先生自觉天下无敌,接下来呢?他想得很简单,那就是编一个quicklisp排名第一的库给大家用!
梦想还是要有,万一实现了呢?
这就是白日梦先生秉持的信念!
头号敌人
白日梦先生考虑好自己的目标,花了大概三个小时详细体验实现之后自己在知乎论坛、CSDN、博客园、大型交友网站上获得大量反馈的情景,再详细设计自己面对网友如潮的点赞、收藏、关注和评论之后的表情、语气、回复。
然后,就没有然后了,因为白日梦先生他毕竟是白日梦先生,他只需要梦想,不需要现实。
白日梦先生的头号敌人,名叫不可能先生。
他哈哈大笑(他总是先哈哈大笑),对着白日梦先生说:做梦吧你,这不可能!

白日梦先生和不可能先生打开了quicklisp收录库链接
Quicklisp收录库链接
这个排名是按照#'string<函数的结果排序的,也就是按照字母顺序排序的。
白日梦先生脸微微发热,心怦怦跳,难道,这一次的梦想真的额能够实现?

那么很简单,只需要编一个库,取名为0xxxx,那么就可以排在目前排第一名的1am之前了!
那么这个1am是什么呢?好奇先生已经停不住了。
排名第一的1am
不管三七二十一,好奇先生先在REPL中输入命令,想看看这个库到底是什么。
(ql:quickload '1am)
To load "1am":Load 1 ASDF system:1am(1AM); Loading "1am"
可以看到,这个库定义了一个ASDF系统,名字叫1am。只要能够加载,好奇先生就能够为所欲为。
(require 'explore-lisp)(multiple-value-list (el:dir '1am))
NIL((1AM:RUN 1AM:*TESTS* 1AM:SIGNALS 1AM:TEST 1AM:IS) 5)
只有区区五个符号,而且,看起来似乎是一个测试库。好奇先生猜测。
这完全难不倒好奇先生,只要运行下面的命令,这个库的深浅或者长短就完全暴漏出来了呢!
(el:export-all-external-symbols '1am :start-level 2)
NIL
*TESTS*
1AM:*TESTS*[symbol]*TESTS* names a special variable:Value: NILDocumentation:A list of tests; the default argument to `run'.
IS
1AM:IS[symbol]IS names a macro:Lambda-list: (FORM)Documentation:Assert that `form' evaluates to non-nil.Source file: /home/qchen/quicklisp/dists/quicklisp/software/1am-20141106-git/1am.lisp
RUN
1AM:RUN[symbol]RUN names a compiled function:Lambda-list: (&OPTIONAL (TESTS *TESTS*))Derived type: (FUNCTION (&OPTIONAL T) (VALUES &OPTIONAL))Documentation:Run each test in the sequence `tests'. Default is `*tests*'.Source file: /home/qchen/quicklisp/dists/quicklisp/software/1am-20141106-git/1am.lisp
SIGNALS
1AM:SIGNALS[symbol]SIGNALS names a macro:Lambda-list: (CONDITION &BODY BODY)Documentation:Assert that `body' signals a condition of type `condition'.Source file: /home/qchen/quicklisp/dists/quicklisp/software/1am-20141106-git/1am.lisp
TEST
1AM:TEST[symbol]TEST names a macro:Lambda-list: (NAME &BODY BODY)Documentation:Define a test function and add it to `*tests*'.Source file: /home/qchen/quicklisp/dists/quicklisp/software/1am-20141106-git/1am.lisp
1am的五脏六腑
而且,好奇先生还直接看到源文件的地址,那就去好好看看!
> wc -l *27 1am.asd105 1am.lisp114 README.md246 total
原来,这个排名第一的库,就只有三个文件,总共246行,代码就只有132行!
ASDF 定义文件
;;; Copyright (c) 2014 James M. Lawrence
;;;
;;; Permission is hereby granted, free of charge, to any person
;;; obtaining a copy of this software and associated documentation
;;; files (the "Software"), to deal in the Software without
;;; restriction, including without limitation the rights to use, copy,
;;; modify, merge, publish, distribute, sublicense, and/or sell copies
;;; of the Software, and to permit persons to whom the Software is
;;; furnished to do so, subject to the following conditions:
;;;
;;; The above copyright notice and this permission notice shall be
;;; included in all copies or substantial portions of the Software.
;;;
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;;; DEALINGS IN THE SOFTWARE.(defsystem :1am:description "A minimal testing framework.":license "MIT":author "James M. Lawrence <llmjjmll@gmail.com>":components ((:file "1am")))
代码文件
;;; Copyright (c) 2014 James M. Lawrence
;;;
;;; Permission is hereby granted, free of charge, to any person
;;; obtaining a copy of this software and associated documentation
;;; files (the "Software"), to deal in the Software without
;;; restriction, including without limitation the rights to use, copy,
;;; modify, merge, publish, distribute, sublicense, and/or sell copies
;;; of the Software, and to permit persons to whom the Software is
;;; furnished to do so, subject to the following conditions:
;;;
;;; The above copyright notice and this permission notice shall be
;;; included in all copies or substantial portions of the Software.
;;;
;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
;;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
;;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
;;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
;;; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
;;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
;;; DEALINGS IN THE SOFTWARE.(defpackage #:1am(:use #:cl)(:export #:test #:is #:signals #:run #:*tests*))(in-package #:1am)(defvar *tests* nil "A list of tests; the default argument to `run'.")
(defvar *pass-count* nil)
(defvar *running* nil)
(defvar *failed-random-state* nil)(defun %shuffle (vector)(loop for i downfrom (- (length vector) 1) to 1do (rotatef (aref vector i) (aref vector (random (1+ i)))))vector)(defun shuffle (sequence)(%shuffle (map 'vector #'identity sequence)))(defun call-with-random-state (fn)(let ((*random-state* (or *failed-random-state*(load-time-value (make-random-state t)))))(setf *failed-random-state* (make-random-state nil))(multiple-value-prog1 (funcall fn)(setf *failed-random-state* nil))))(defun report (test-count pass-count)(format t "~&Success: ~s test~:p, ~s check~:p.~%" test-count pass-count))(defun %run (fn test-count)(let ((*pass-count* 0))(multiple-value-prog1 (call-with-random-state fn)(report test-count *pass-count*))))(defun run (&optional (tests *tests*))"Run each test in the sequence `tests'. Default is `*tests*'."(let ((*running* t))(%run (lambda () (map nil #'funcall (shuffle tests)))(length tests)))(values))(defun call-test (name fn)(format t "~&~s" name)(finish-output)(if *running*(funcall fn)(%run fn 1)))(defmacro test (name &body body)"Define a test function and add it to `*tests*'."`(progn(defun ,name ()(call-test ',name (lambda () ,@body)))(pushnew ',name *tests*)',name))(defun passed ()(write-char #\.);; Checks done outside a test run are not tallied.(when *pass-count*(incf *pass-count*))(values))(defmacro is (form)"Assert that `form' evaluates to non-nil."`(progn(assert ,form)(passed)))(defun %signals (expected fn)(flet ((handler (condition)(cond ((typep condition expected)(passed)(return-from %signals (values)))(t (error "Expected to signal ~s, but got ~s:~%~a"expected (type-of condition) condition)))))(handler-bind ((condition #'handler))(funcall fn)))(error "Expected to signal ~s, but got nothing." expected))(defmacro signals (condition &body body)"Assert that `body' signals a condition of type `condition'."`(%signals ',condition (lambda () ,@body)))
这样就非常清楚了,这个库通过ASDF定义了一个系统,然后定义了几个宏和函数,用来进行测试。
test定义一个测试函数,然后将这个函数加入到*tests*列表中is用来断言一个表达式是否为真signals用来断言一个表达式是否会抛出一个特定的异常run用来运行*tests*列表中的所有测试函数*tests*用来存放所有的测试函数,作为run的默认参数
1am使用示例
完全照搬自1am的README.md文件,挠痒痒先生对此负全责。
首先是定义测试的部分,相当透明。
(defpackage :example (:use :cl :1am))
(in-package :example)(test foo-test(is (= 1 1))(is (zerop 0)))(test bar-test(signals simple-error(error "bar!")))
#<PACKAGE "EXAMPLE">#<PACKAGE "EXAMPLE">FOO-TESTBAR-TEST
简单测试
接下来是简单的测试,有几种运行测试的办法。
- 直接运行
run函数,会运行*tests*列表中的所有测试函数 - 运行
test函数(真的是一个普通的函数),会运行指定的测试函数 - 直接构造一个测试函数列表,作为参数传递给
run函数 - 设置
*tests*列表,然后运行run函数
实际上,这样就可以满足定位bug,快速测试的所有需求了。由于Lisp的动态特性,还能够在调试中动态定义测试函数,加入运行。
(in-package :example)
(run)
#<PACKAGE "EXAMPLE">FOO-TEST..
BAR-TEST.
Success: 2 tests, 3 checks.
(foo-test)
FOO-TEST..
Success: 1 test, 2 checks.
(run '(bar-test))
BAR-TEST.
Success: 1 test, 1 check.
(setf *tests* '(foo-test))
(run)
(FOO-TEST)FOO-TEST..
Success: 1 test, 2 checks.
探索永不停止
这个排名第一的测试库1am,用起来非常简单,整个设计非常透明,代码量也很小,其实对于复杂系统的测试而言,这可能是一个很大的优点。
好奇先生看了一眼在做白日梦的白日梦先生和觉得什么都不可能的不可能先生,心里想,其实Common Lisp还真有些库是大家都在引用的,比如alexandria,不行再把alexandria好好探索一下?
好奇先生的时间快速飞逝,deadline也不停tik-tok-tik-tok。
相关文章:
老古董Lisp实用主义入门教程(12):白日梦先生的白日梦
白日梦先生的白日梦 白日梦先生已经跟着大家一起学Lisp长达两个月零五天! 001 粗鲁先生Lisp再出发002 懒惰先生的Lisp开发流程003 颠倒先生的数学表达式004 完美先生的完美Lisp005 好奇先生用Lisp来探索Lisp006 好奇先生在Lisp的花园里挖呀挖呀挖007 挑剔先生给出…...
UE5 Windows热更新解决方案思路(HotPatcher+Tomcat+RuntimeFilesDownloader)
以下个人学习笔记。其中必会存在一些问题,仅作参考。本人版本5.1。 参考视频: UE4热更新:HotPatcher插件使用教程_哔哩哔哩_bilibili 3.检查需要下载的版本_哔哩哔哩_bilibili 参考文章: UE 热更新:Questions &…...
进程管理工具:非daemon进程管理工具supervisor
一、非daemon进程管理工具:supervisor Windows安装supervisor https://pypi.org/project/supervisor-win/4.5.0/#files 一)进程管理supervisor简介 supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程&…...
c++模拟真人鼠标轨迹算法
一.鼠标轨迹算法简介 鼠标轨迹底层实现采用 C / C语言,利用其高性能和系统级访问能力,开发出高效的鼠标轨迹模拟算法。通过将算法封装为 DLL(动态链接库),可以方便地在不同的编程环境中调用,实现跨语言的兼…...
android12/13/14版本wms最新面试题:dumpsys window和sf一定会一致么?
背景: 近期学员们学习了马哥wms课程后,去参加相关的大厂的framework面试,有一个学员朋友带回来了一个wms相关的面试题,具体面试题描述如下: 问题1 请问wms的window和SurfaceFlinger的Layer有什么关系? 回…...
Python脚本示例,你可以使用这个脚本来自动化登录网站、选择页面元素和提交表单
devtools 元素页面可以选择元素,copy xpath用于查找 python编程:1、浏览器登录https://58.xxx/ 账号:xxx 密码:FN123456 2、选择“技能训练” 3、选择“云网智能运维员培训相关资料” 4、选择“L1-Linux操作系统与运维题库” 5、依次选择1-50题目&#x…...
安卓13设置动态修改设置显示版本号 版本号增加信息显示 android13增加序列号
总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 设置 =》关于平板电脑 =》版本号 在这里显示了系统的一些信息,但是这里面的信息并不包含序列号之类的信息,我们修改下系统设置,在这里增加上相关的序列号。 2.问题分析…...
从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之三:在目标服务器上恢复数据
从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之三:在目标服务器上恢复数据 目录 从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之三:在目标服务器上恢复数据一、修改参数文件的内容二、…...
相互作用感知的 3D 分子生成 VAE 模型 - DeepICL 评测
DeepICL 是一个基于相互作用感知的 3D 分子生成模型,能够在目标结合口袋内进行相互作用引导的小分子设计。DeepICL 通过利用蛋白质-配体相互作用的普遍模式作为先验知识,在有限的实验数据下也能实现高度的泛化能力。 一、背景介绍 DeepICL 来源于韩国科学…...
Java实现随机抽奖的方法有哪些
在Java中实现随机抽奖的方法,通常我们会使用java.util.Random类来生成随机数,然后基于这些随机数来选择中奖者。以下将给出几种常见的随机抽奖实现方式,包括从数组中抽取、从列表中抽取以及基于权重的抽奖方式。 1. 从数组中抽取 import ja…...
grafana加载缓慢解决方案
背景 目前随着数据和图表的逐渐增多,Grafana 页面加载速度明显变慢,严重影响了用户体验,几次都有骂娘的冲动.,因此我们需要对 Grafana 进行优化,以提升加载性能。 对于速度优化,我们可以从以下方面进行入…...
【湖南步联科技身份证】 身份证读取与酒店收银系统源码整合———未来之窗行业应用跨平台架构
一、html5 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8" /><script type"text/javascript" src"http://51.onelink.ynwlzc.net/o2o/tpl/Merchant/static/js…...
多路复用和事件轮询机制
多路复用:Nio 服务端只有一个线程处理多个连接 事件轮询机制:select 底层用了 epoll。 select open 调用了 epoll 通过3个方法来实现事件轮询 1.epoll.create 创建epoll 多个集合 2.epoll.ctl 如果有事件会把事件挪到就绪事件列表。 3.epoll.wait 会监听…...
Android常用C++特性之std::abs
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。 std::abs 是 C 标准库中的一个函数,用于计算整数、浮点数或其他数值类型的绝对值。它返回一个值,该值是参数的非负数形式,即去掉负…...
LabVIEW提高开发效率技巧----使用状态机架构
状态机架构(State Machine Architecture)是LabVIEW编程中的一种常见且高效的设计模式,特别适合用于处理具有多个操作状态的复杂系统。通过这种架构,程序能够根据不同的输入条件或事件,在多个状态之间切换,从…...
Feign:服务挂了也不会走fallback
Feign 本质上是一个 HTTP 客户端,用于简化微服务之间的 HTTP 通信。它允许开发者通过定义接口和注解来声明式地编写 HTTP 客户端,而无需手动编写 HTTP 请求和响应处理的代码。 今天在模拟微服务A feign调用微服务B的时候,把微服务B关了&#…...
网络编程操作—函数
一、socket创建套接字 #include <sys/types.h> //头文件 #include <sys/socket.h> int socket(int domain, int type, int protocol); 三个参数:domain、type、protocol 1.domain:域名,领域,定义域(中文解释&…...
博客摘录「 GD32的flash读、擦除、写操作」2024年9月2日
关于GD32的Flash读、擦除、写操作,以下是基于当前可获得信息(截至2024年9月2日)的详细解答: 一、GD32 Flash的基本特性 存储空间:GD32的Flash存储空间大小因型号而异,可支持从几KB到几MB不等的存储容量。页大小:Flash按页组织,不同型号的GD32其页大小可能不同。例如,…...
【性能优化】低配starRocks常驻内存优化
背景说明 由于服务器的实际资源小于starRocks官方的配置,导致starRocks在无任务的情况下,常驻内存偏高,可用于查询的资源变小。 官方文档 实际部署的集群一般是4C8G和8C16G,be的配置不达标 为了解决单次查询内存不足的问题&…...
科研绘图系列:R语言树结构聚类热图(cluster heatmap)
文章目录 介绍加载R包导入数据数据预处理画图修改图形导出数据系统信息介绍 热图结合树结构展示聚类结果通常用于展示数据集中的模式和关系,这种图形被称为聚类热图或层次聚类热图。在这种图中,热图部分显示了数据矩阵的颜色编码值,而树结构(通常称为树状图或聚类树)则显…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
