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

news2024/11/18 5:48:47

在这里插入图片描述

白日梦先生的白日梦

白日梦先生已经跟着大家一起学Lisp长达两个月零五天!

  1. 001 粗鲁先生Lisp再出发
  2. 002 懒惰先生的Lisp开发流程
  3. 003 颠倒先生的数学表达式
  4. 004 完美先生的完美Lisp
  5. 005 好奇先生用Lisp来探索Lisp
  6. 006 好奇先生在Lisp的花园里挖呀挖呀挖
  7. 007 挑剔先生给出终止迭代的条件
  8. 008 挠痒痒先生建网站记
  9. 009 小小先生学习Lisp表达式
  10. 010 聪明先生拒(ji)绝(xu)造轮子
  11. 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: NIL
  Documentation:
    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.asd
 105 1am.lisp
 114 README.md
 246 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 1
        do (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使用示例

完全照搬自1amREADME.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-TEST






BAR-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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2175534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于工作虚拟组的一些思考

这是学习笔记的第 2493篇文章 因为各种工作协作&#xff0c;势必要打破组织边界&#xff0c;可能会存在各种形态的虚拟组。 近期沉淀了一些虚拟组的管理方式&#xff0c;在一定时间范围内也有了一些起色&#xff0c;所以在不断沉淀的过程中&#xff0c;也在不断思考。 这三个虚…

企业级版本管理工具(1)----Git

目录 1.Git是什么 2.Git的安装和使用 在Ubuntu下安装命令如下&#xff1a; 使用git --version查看已安装git的版本&#xff1a; 使用git init初始化仓库&#xff1a; 使用tree .git列出目录&#xff1a; 使用git config命令设置姓名和邮箱&#xff1a; 加入--global选项…

WPF MVVM入门系列教程(一、MVVM模式介绍)

前言 还记得早些年刚工作的那会&#xff0c;公司的产品从Delphi转成了WPF&#xff08;再早些年是mfc&#xff09;。当时大家也是处于一个对WPF探索的阶段&#xff0c;所以有很多概念都不是非常清楚。 但是大家都想堆技术&#xff0c;就提出使用MVVM&#xff0c;我那会是第一次…

想做个WPS的自动化代码,参考如下:

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

水仙花数求解-C语言

1.问题&#xff1a; 输出100-1000之间所有的“水仙花数”。 2.解答&#xff1a; “水仙花数”是指一个3位数&#xff0c;其各位数字立方和等于该数本身&#xff0c;逐个位数判断即可&#xff0c;写代码的时候要考虑到每一位。 3.代码&#xff1a; #include<stdio.h>//…

9.28QT基础

widget.cpp widegt.h .pro main.cpp 一个仿QQ登录界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setFixedSize(350,500);this->setStyleSheet("background-color:#e5f0ff;");QLineEdit *edit1 new QLine…

1.2.3 HuggingFists安装说明-MacOS安装

MacOS版安装说明 下载地址 【GitHub】GitHub - Datayoo/HuggingFists4Mac 【百度网盘】https://pan.baidu.com/s/12WxZ-2GgMtbQeP7AcmsyHg?pwd2024 安装说明 环境要求 操作系统&#xff1a;MacOS 硬件环境&#xff1a;至少4核8G 安装步骤 1. 安装Docker环境。若已安装Do…

kali linux 终端复用和界面移动

kali linux 终端复用和界面移动 经验和操作 渗透测试的工具选择考虑 01 能用命令行就不用图形ui 图形ui 容易对细节隐藏&#xff0c;命令行工具的在终端输出的日志相对透明&#xff0c;容易观察和调整 wireshark – tcpdump burpsuit – curl( web 访问相关), wfuzz(模糊测…

带你0到1之QT编程:十七、Http协议实战,实现一个简单服务器和一个客户端进行http协议通信

此为QT编程的第十七谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

Python15行代码 tkinter模块 写计算机

之前去备战csp-j了 也有一段时间没更新了 结果白名单没捞着 还差点被我妈打喜 今天闲来无事 写个计算器玩玩 _____________________________________________________________________________ 老规矩 先放代码 from tkinter import *;from math import sqrt;aTk();a.geome…

机械键盘驱动调光DIY--【DAREU】

1 下载键盘对应的驱动&#xff0c;不要装到C盘 达尔优驱动下载中心 2 驱动更改教程 标准模式 键盘功能 鼠标功能 切换灯光 切换配置文件 多媒体 windows快捷键 禁用 Fn 启动程序 文本功能 光标定位 FN模式 灯光效果设置 注意 宏--自定义功能

【SpringCloud】多机部署, 负载均衡-LoadBalance

多机部署, 负载均衡-LoadBalance 1. 负载均衡介绍1.1 问题描述1.2 什么是负载均衡1.3 负载均衡的⼀些实现服务端负载均衡客⼾端负载均衡 2. Spring Cloud LoadBalancer 1. 负载均衡介绍 1.1 问题描述 观察上个章节远程调⽤的代码 根据应⽤名称获取了服务实例列表从列表中选择…

【SQL】未订购的客户

目录 语法 需求 示例 分析 代码 语法 SELECT columns FROM table1 LEFT JOIN table2 ON table1.common_field table2.common_field; LEFT JOIN&#xff08;或称为左外连接&#xff09;是SQL中的一种连接类型&#xff0c;它用于从两个或多个表中基于连接条件返回左表…

CSS布局中的定位

一、position 1.static position: static; 默认值&#xff0c;没有定位2 .relative 相对定位&#xff1a;相对自身原来的位置进行偏移 偏移设置&#xff1a;top、left、right、bottom 相对定位元素的规律&#xff1a; 设置相对定位的盒子会相对于它原来的位置&#xff0c;通…

Nature数据库介绍及个人获取Nature文献下载途径

Springer Nature集团是一家全球领先的从事科研、教育和专业出版的机构&#xff0c;也是世界上最大的学术图书出版公司&#xff0c;同时出版全球最具影响力的期刊&#xff0c;也是开放获取领域的先行者。Springer Nature在2015年由Nature出版集团&#xff08;Nature Portfolio&a…

JS加密=JS混淆?(JS加密、JS混淆,是一回事吗?)

JS加密、JS混淆&#xff0c;是一回事吗&#xff1f; 是的&#xff01;在国内&#xff0c;JS加密&#xff0c;其实就是指JS混淆。 1、当人们提起JS加密时&#xff0c;通常是指对JS代码进行混淆加密处理&#xff0c;而不是指JS加密算法&#xff08;如xor加密算法、md5加密算法、…

正点原子——DS100示波器操作手册

目录 基础按键&#xff1a; 快捷键 主界面&#xff1a; 垂直设置&#xff1a; 通道设置&#xff1a; 探头比列&#xff1a; 垂直档位&#xff1a; 垂直偏移&#xff1a; 幅度单位&#xff1a; 水平设置&#xff1a; 触发方式&#xff1a; 测量和运算: 光标测量&am…

面试题:MySQL你用过WITH吗?领免费激活码

感谢Java面试教程的Java多线程文章&#xff0c;点击查看>原文 Java面试教程&#xff0c;发mmm116可获取IDEA-jihuoma 在MySQL中&#xff0c;WITH子句用于定义临时表或视图&#xff0c;也称为公共表表达式&#xff08;CTE&#xff09;。它允许你在一个查询中定义一个临时结果…

二叉搜索树 K模型 和 KV模型

&#x1f33b;个人主页&#xff1a;路飞雪吖~ ✨专栏&#xff1a;C/C 目录 一、二叉搜索树&#xff08;K模型&#xff09;的模拟实现 &#x1f31f;二叉搜索树的概念 &#x1f31f;二叉搜索树的操作 &#x1f320;二叉搜索树的查找 &#x1f320;二叉搜索树的插入 &#x…

Docker安装与应用

前言 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言开发。Docker 可以让开发者打包他们的应用以及依赖包到一个轻 量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互 之间…