老古董Lisp实用主义入门教程(5):好奇先生用Lisp探索Lisp

news2024/11/28 10:35:20

在这里插入图片描述

鲁莽先生什么都不管

鲁莽先生打开电脑,安装一堆东西,噼里啪啦敲了一堆代码,叽里呱啦说了一堆话,然后累了就回家睡觉了。

这可把好奇先生的兴趣勾起来,他怎么也睡不着。好奇先生打开电脑,看了看鲁莽先生留下的代码和可执行文件,然后开始研究起来。

好奇先生第一次见到Lisp

好奇先生看到了一堆括号,他不知道这是什么,但是他知道这是一种编程语言,于是他开始查资料,了解到这是一种叫做Lisp的语言。

这个语言最大的特点就是括号,括号里面是函数名,括号外面是参数。因为括号很多,Lisp也被称为Lots of Irritating Silly Parentheses(许多令人烦恼的愚蠢括号)。

真是好玩啊!好奇先生想,真想要试试看。

好奇先生按照鲁莽先生的说明,安装SBCL,然后打开REPL,输入了一行代码:

This is SBCL 2.4.6, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (+ 1 2)
3

好的,这下可以做加法啦!实际上,Lisp的加法可以加多个数:

(+ 1 2 3 4 5 6)
21

这不是很好理解吗?括号里面是一个列表,列表的第一个元素是+,后面的元素是被加的数字。画出来就是这样的:

1
2
3
4
5
6
+

这不算什么,好奇先生想,我可以用Lisp来做更复杂的事情。

(+ 1 (* 2 3) (- 4 5))
6

再按照上面的方法画出来:

1
2
3
4
5
+
*
-

1 + 2 * 3 + (4 - 5) = 6 ,结果是6。其实很直观!

好奇先生觉得自己完全懂了:每个列表第一个元素是要干什么,后面的元素是对谁干。而且,后面的元素也可以是列表,这个列表的第一个元素同样是要干什么,后面的元素是对谁干。

好奇先生更好奇了

好奇先生觉得自己完全懂了,Lisp的代码就是一个括号套住的内容(包括括号本身),可以称为表达式(expression),表达式的左边一个括号,右边一个括号,中间是一个操作符(operator)和零个或多个操作数(operand)。

<left_parenthesis> = "("
<right_parenthesis> = ")"
<expression> ::= <left_parenthesis> <operator> <operand>* <right_parenthesis>
<operand> ::= <expression> | <???>

这个<operator>是什么?这个<operand>是什么?到底是几个?为什么还能是0个?这个<???>是什么?好奇先生更好奇了。

好奇先生继续研究

好奇先生因为很好奇,早就学过无数种编程语言,他能理解这个<operator>是一个函数或者方法或者操作符,比如+-*/sincostansqrtlogexp等等。而这个<operand>是一个值,或者一个变量。当然,无论是值或者变量,其实都有一个很本质的含义,就是内存中的一块区域,这个区域在某些程序设计语言中,表达为地址头、内存长度,这两个两可以完全定位这个区域。但是在Lisp中,到底是什么呢?

Lisp的数据类型

好奇先生查了一下,Lisp中貌似就只有两类大类数据类型:列表(list)和原子(atom)。

  • 列表
    • 由括号括起来的列表
    • 列表的元素可以是列表
    • 列表的元素可以是atom
    • listp可以判断是否是列表
  • Atom,中文直译为原子,在这里可以理解为不可再分的最小单位,比如:
    • 数字,numberp可以判断是否是数字
    • 字符串,stringp可以判断是否是字符串
    • 符号,symbolp可以判断是否是符号
    • 函数,functionp可以判断是否是函数

通过这些操作符(函数)就能够探索各种对象的类型。好奇先生对自己的说法又有了亿点点更多的好奇。对象?什么对象?Lisp里面操作的是什么?好奇先生继续研究。

Lisp中的字面量

字面量,就是直接表示的值,比如1"hello"'atnil:my-key等等。这些值是直接表示的,不需要计算,不需要解释,不需要转换,就是它们自己。实际上,这些值就是Lisp中基本被操作的对象。并非是面向对象编程中的对象。

那么,跟C中间每个量实际上都是一块内存区域是否一样呢?好奇先生不停地问出新问题。

啊,问题太多了,太多啦!好奇先生觉得自己的好奇心已经被点燃了,他决定继续研究,继续探索,继续学习。

好奇先生工具箱

好奇先生每次到第一个新地方,总是最先想知道公共交通能到哪里,所以在打探一个新的编程语言时,他总是先找找有没有什么探索工具可以用。

比如上面的type-of,以及哪些判断类型的命令。此外,lisp还有一些其他的工具,比如:

  • list-all-packages,可以列出所有的包
  • do-external-symbols,可以遍历一个包中的所有符号
  • apropos,可以找到一个符号的定义

好奇先生最喜欢这种工具箱!用这些工具,他就能探索这个SBCL世界!

packages

Common Lisp中的包(package)是一种组织符号的方式,可以把符号分组,然后通过包的名字来访问这些符号。比如,cl-user包中有+这个符号,那么我们可以通过cl-user:+来访问这个符号。

(apropos 'list-all-packages)

;; LIST-ALL-PACKAGES (fbound)
;; NIL

好像没有提供太多的信息。

(list-all-packages)

;; (#<PACKAGE "QUICKLISP-CLIENT"> #<PACKAGE "UIOP/FILESYSTEM">
;; #<PACKAGE "ALIVE/SBCL/SYMBOLS"> #<PACKAGE "IMPL-SPECIFIC-GRAY">
;; #<PACKAGE "QL-IMPL"> #<PACKAGE "UIOP/DRIVER"> #<PACKAGE "ALIVE/INSPECTOR">
;; #<PACKAGE "SB-WALKER"> #<PACKAGE "ASDF/FIND-COMPONENT"> #<PACKAGE "SB-MOP">
;; #<PACKAGE "UIOP/PACKAGE"> #<PACKAGE "ASDF/BACKWARD-INTERNALS">
;; #<PACKAGE "ALIVE/LSP/TYPES/FORMAT-OPTIONS"> #<PACKAGE "QL-MKCL">
;; #<PACKAGE "SB-BIGNUM"> #<PACKAGE "ALIVE/PACKAGES">
;; #<PACKAGE "UIOP/BACKWARD-DRIVER"> #<PACKAGE "ALIVE/UTILS">
;; #<PACKAGE "UIOP/LAUNCH-PROGRAM"> #<PACKAGE "ALIVE/SBCL/THREADS">
;; #<PACKAGE "ASDF/FOOTER"> #<PACKAGE "ALIVE/SESSION"> #<PACKAGE "SB-REGALLOC">
;; #<PACKAGE "QL-CMUCL"> #<PACKAGE "SB-PCL"> #<PACKAGE "QL-CCL">
;; #<PACKAGE "SB-EXT"> #<PACKAGE "ASDF/OPERATE"> #<PACKAGE "ALIVE/RANGE">
;; #<PACKAGE "ALIVE/FILE"> #<PACKAGE "UIOP/RUN-PROGRAM">
;; #<PACKAGE "ALIVE/LSP/DEFINITION"> #<PACKAGE "ASDF/PARSE-DEFSYSTEM">
;; #<PACKAGE "ALIVE/LSP/COMPLETIONS"> #<PACKAGE "ALIVE/STREAMS">
;; #<PACKAGE "QL-DIST-USER"> #<PACKAGE "ALIVE/SBCL/FILE"> #<PACKAGE "QL-INFO">
;; #<PACKAGE "SB-SYS"> #<PACKAGE "QL-CONFIG"> #<PACKAGE "ALIVE/LSP/UTILS">
;; #<PACKAGE "ALIVE/SBCL/STREAMS"> #<PACKAGE "ALIVE/LSP/TYPES/SEM-TOKENS">
;; #<PACKAGE "SB-DISASSEM"> #<PACKAGE "BORDEAUX-THREADS">
;; #<PACKAGE "ALIVE/LSP/PACKET"> #<PACKAGE "ALIVE/LSP/MESSAGE/RESPONSE">
;; #<PACKAGE "SB-FASL"> #<PACKAGE "UIOP/UTILITY"> #<PACKAGE "JSON-SYSTEM">
;; #<PACKAGE "QL-SETUP"> #<PACKAGE "SB-POSIX"> #<PACKAGE "ALIVE/PARSE/TOKENIZER">
;; #<PACKAGE "ASDF/FIND-SYSTEM"> #<PACKAGE "SB-UNICODE">
;; #<PACKAGE "FLEXI-STREAMS-SYSTEM"> #<PACKAGE "ASDF/CONCATENATE-SOURCE">
;; #<PACKAGE "SB-DEBUG"> #<PACKAGE "ALIVE/FORMAT"> #<PACKAGE "QL-UTIL">
;; #<PACKAGE "SB-LOCKLESS"> #<PACKAGE "SB-ALIEN-INTERNALS">
;; #<PACKAGE "BORDEAUX-THREADS-2"> #<PACKAGE "SB-ALIEN">
;; #<PACKAGE "ALEXANDRIA-2"> #<PACKAGE "QL-SCL"> #<PACKAGE "ASDF/USER">
;; #<PACKAGE "ALIVE/TYPES"> #<PACKAGE "ALIVE/THREADS">
;; #<PACKAGE "SPLIT-SEQUENCE"> #<PACKAGE "ASDF/COMPONENT">
;; #<PACKAGE "ASDF/FORCING"> #<PACKAGE "QL-GUNZIPPER"> #<PACKAGE "SB-INTROSPECT">
;; #<PACKAGE "UIOP/STREAM"> #<PACKAGE "ASDF/PACKAGE-INFERRED-SYSTEM">
;; #<PACKAGE "SB-PRETTY"> #<PACKAGE "ASDF/SOURCE-REGISTRY">
;; #<PACKAGE "SB-SEQUENCE"> #<PACKAGE "ASDF/SYSTEM-REGISTRY">
;; #<PACKAGE "SB-APROF"> #<PACKAGE "ALIVE/POSITION"> #<PACKAGE "SB-PROFILE">
;; #<PACKAGE "ALIVE/COMPILE-MESSAGE"> #<PACKAGE "ALEXANDRIA">
;; #<PACKAGE "UIOP/OS"> #<PACKAGE "QL-NETWORK"> #<PACKAGE "ASDF/LISP-ACTION">
;; #<PACKAGE "ALIVE/LSP/HOVER"> #<PACKAGE "ALIVE/LSP/SYMBOL">
;; #<PACKAGE "ASDF/PLAN"> #<PACKAGE "ALIVE/LOGGER"> #<PACKAGE "SB-C">
;; #<PACKAGE "QL-BUNDLE"> #<PACKAGE "UIOP/PATHNAME"> #<PACKAGE "SB-BSD-SOCKETS">
;; #<PACKAGE "ALIVE/TEXT-EDIT"> #<PACKAGE "ASDF/SESSION"> #<PACKAGE "JSON">
;; #<PACKAGE "ALIVE/SELECTION"> #<PACKAGE "QL-HTTP"> #<PACKAGE "ASDF/INTERFACE">
;; #<PACKAGE "ASDF/OUTPUT-TRANSLATIONS"> #<PACKAGE "ALIVE/LSP/PARSE">
;; #<PACKAGE "QL-MINITAR"> #<PACKAGE "ASDF/ACTION"> #<PACKAGE "UIOP/VERSION">
;; #<PACKAGE "ALIVE/LSP/MESSAGE/REQUEST"> #<PACKAGE "SB-THREAD">
;; #<PACKAGE "QL-SBCL"> #<PACKAGE "ASDF/BUNDLE"> #<PACKAGE "KEYWORD">
;; #<PACKAGE "ALIVE/EVAL"> #<PACKAGE "ALIVE/PARSE/FORMS">
;; #<PACKAGE "ALIVE/LSP/MESSAGE/ABSTRACT"> #<PACKAGE "SB-LOOP">
;; #<PACKAGE "SB-DI"> #<PACKAGE "SB-UNIX"> #<PACKAGE "UIOP/CONFIGURATION">
;; #<PACKAGE "UIOP/IMAGE"> #<PACKAGE "SB-IMPL"> #<PACKAGE "SB-GRAY">
;; #<PACKAGE "COMMON-LISP-USER"> #<PACKAGE "SB-BROTHERTREE">
;; #<PACKAGE "ASDF/OPERATION"> #<PACKAGE "ALIVE/DEBUGGER">
;; #<PACKAGE "QL-IMPL-UTIL"> #<PACKAGE "ALIVE/PARSE/TOKEN">
;; #<PACKAGE "ALIVE/LSP/SEM-ANALYSIS"> #<PACKAGE "ALIVE/MACROS">
;; #<PACKAGE "QL-LISPWORKS"> #<PACKAGE "SB-VM"> #<PACKAGE "GLOBAL-VARS">
;; #<PACKAGE "SB-ASSEM"> #<PACKAGE "UIOP/COMMON-LISP">
;; #<PACKAGE "ALIVE/LSP/TYPES/CONFIG-ITEM"> #<PACKAGE "TRIVIAL-GARBAGE">
;; #<PACKAGE "ASDF/BACKWARD-INTERFACE"> #<PACKAGE "ALIVE/LSP/TYPES/RESTART-INFO">
;; #<PACKAGE "SB-FORMAT"> #<PACKAGE "ASDF/UPGRADE"> #<PACKAGE "SB-INT">
;; #<PACKAGE "QL-CLISP"> #<PACKAGE "USOCKET"> #<PACKAGE "ALIVE/PARSE/FORM">
;; #<PACKAGE "ALIVE/LSP/MESSAGE/NOTIFICATION"> #<PACKAGE "SB-WIN32">
;; #<PACKAGE "ALIVE/SYMBOLS"> #<PACKAGE "SB-EVAL"> #<PACKAGE "SB-X86-64-ASM">
;; #<PACKAGE "QL-MEZZANO"> #<PACKAGE "QL-PROGRESS"> #<PACKAGE "QL-ALLEGRO">
;; #<PACKAGE "COMMON-LISP"> #<PACKAGE "ALIVE/SERVER">
;; #<PACKAGE "ALIVE/LSP/MESSAGE/FORMAT-UTILS"> #<PACKAGE "QL-CDB">
;; #<PACKAGE "ALIVE/ERRORS"> #<PACKAGE "ALIVE/FRAMES"> #<PACKAGE "JSON-RPC">
;; #<PACKAGE "QL-CLASP"> #<PACKAGE "UIOP/LISP-BUILD"> #<PACKAGE "SB-KERNEL">
;; #<PACKAGE "FLEXI-STREAMS"> #<PACKAGE "TRIVIAL-GRAY-STREAMS">
;; #<PACKAGE "ASDF/SYSTEM"> #<PACKAGE "QL-DIST"> #<PACKAGE "ALIVE/LSP/ERRORS">
;; #<PACKAGE "QL-ECL"> #<PACKAGE "ALIVE/ASDF">
;; #<PACKAGE "SB-BSD-SOCKETS-INTERNAL"> #<PACKAGE "QL-ABCL">)

原来好奇先生已经安装这么多有用的(或者没用的)包。

还可以自己定义一个包,并且看看自己定义的包是不是能被找到。好奇先生看到结果,高兴得不得了。

(let ((before (list-all-packages))) 
  (make-package 'temp) 
  (set-difference (list-all-packages) before))

;; (#<PACKAGE "TEMP">)

当然,我们还可以查找一个包,这里用的是find-package

(find-package 'cl-user)
(find-package :cl-user)
(find-package "CL-USER")

这三种形式都可以,只是注意,最后那个用字符串的方式,必须是大写的。太麻烦,好奇先生动动手指,写了一个函数。

(defun find-package-ignore-case (name)
  "Find a package by name, ignoring case"
  (if (stringp name)
      (find-package (string-upcase name))
      (find-package name)))

这下子,就可以直接忽视大小写了。那么,能不能用一个包的名字的一部分来查找一个包呢?好奇先生又动动手指,写了一个函数。

(defun part-in-list-p (part list)
  "Return true if any element of list contains part"
  (find-if (lambda (x) (search part x)) list))

(defun find-package-with-part (part)
  "Find a package by part of its name or nickname"
  (let ((result '())
        (part-upcase (string-upcase part)))
    (dolist (package (list-all-packages))
      (if (or (search part-upcase (package-name package))
              (part-in-list-p part-upcase (package-nicknames package)))
          (push package result)))
    result))

第一个函数,用来在一个列表中找到是否包含一个字符串,如果包含,就返回真。第二个函数,用来查找一个包的名字或者别名中是否包含一个字符串。

(find-package-with-part "cl")
; (#<PACKAGE "QL-ABCL"> #<PACKAGE "QL-ECL"> #<PACKAGE "QL-CLASP">
;  #<PACKAGE "COMMON-LISP"> #<PACKAGE "QL-CLISP"> #<PACKAGE "UIOP/COMMON-LISP">
;  #<PACKAGE "COMMON-LISP-USER"> #<PACKAGE "QL-SBCL"> #<PACKAGE "JSON">
;  #<PACKAGE "QL-SCL"> #<PACKAGE "ALIVE/SBCL/STREAMS">
;  #<PACKAGE "ALIVE/SBCL/FILE"> #<PACKAGE "QL-CCL"> #<PACKAGE "SB-PCL">
;  #<PACKAGE "QL-CMUCL"> #<PACKAGE "ALIVE/SBCL/THREADS"> #<PACKAGE "QL-MKCL">
;  #<PACKAGE "ALIVE/SBCL/SYMBOLS"> #<PACKAGE "QUICKLISP-CLIENT">)

现在,好奇先生对自己系统中的包了如指掌,完全满足了他的部分好奇心,因为好奇先生的好奇先生是无穷无尽的!知道自己的系统中有这么多包之后,好奇先生的好奇心简直要爆炸了,每个包里到底有什么?

包里有什么呢?当然是symbols

粗鲁先生看到好奇先生噼里啪啦地敲着键盘,嘴里念念有词,突然听到一句”包里有什么呢?“,他大声回答:“当然是符号啦!”好奇先生听到这个回答,觉得很有道理,于是他开始查找一个包里面的所有符号。


;; list all external symbols in a package
(defun dir (package)
  (let ((result '())
        (len 0))
    (do-external-symbols (s package (values result len))
      ;   (format t "~a~%" s)
      (push s result)
      (incf len))))

因为这就像是列出一个目录的文件,好奇先生当然把这个函数命名为dir

(dir (find-package 'cl))(READ-BYTE FIND-PACKAGE ROUND LET* +++ COPY-SYMBOL BREAK ARRAY
;            LISP-IMPLEMENTATION-TYPE PPRINT-FILL REMHASH FILE-LENGTH FLOOR
;            MOST-POSITIVE-LONG-FLOAT STRING= BOOLE-C1 LOGNAND BIT-IOR
;            SYNONYM-STREAM-SYMBOL STANDARD-GENERIC-FUNCTION
;            GET-INTERNAL-REAL-TIME DESCRIBE-OBJECT IN-PACKAGE SET
;            *COMPILE-FILE-PATHNAME* ISQRT PROBE-FILE UNION VECTOR MEMBER-IF-NOT
;            LOGBITP STREAM-ERROR-STREAM APPEND NSUBLIS PATHNAME
;            SET-DISPATCH-MACRO-CHARACTER CDAADR PROG SYNONYM-STREAM CONJUGATE
;            LOGTEST SPECIAL NIL DOUBLE-FLOAT-EPSILON SHADOW TRACE SYMBOL-PLIST
;            CADAR DELETE-FILE COPY-ALIST PATHNAME-DIRECTORY SIN SHIFTF
;            STANDARD-METHOD TYPE PROG1 FLOAT-SIGN BIT-AND PLUSP COMPILER-MACRO
;            NOT STREAM-ELEMENT-TYPE CADDDR STRING<= ADJOIN REMPROP CHAR-EQUAL
;            RETURN-FROM LEAST-POSITIVE-NORMALIZED-SHORT-FLOAT BOOLE-CLR LCM
;            POSITION HANDLER-CASE COMPUTE-APPLICABLE-METHODS DEFMETHOD BOOLE-1
;            CONTROL-ERROR CLASS CHAR-LESSP DELETE-PACKAGE
;            BROADCAST-STREAM-STREAMS LEAST-POSITIVE-NORMALIZED-DOUBLE-FLOAT NULL
;            FIFTH EXP WITH-OUTPUT-TO-STRING FTRUNCATE LAST STRING-CAPITALIZE
;            MAPCON CDDDDR LOGORC2 PRINT-OBJECT >= USER-HOMEDIR-PATHNAME
;            *MODULES* CAAADR SLOT-MISSING RATIONALIZE TANH BIT-EQV ///
;            ROW-MAJOR-AREF *LOAD-PATHNAME* *PRINT-ESCAPE* READTABLE-CASE NCONC
;            BOOLE-2 STANDARD-CLASS SIMPLE-BIT-VECTOR COUNT-IF BOOLE-SET
;            DEFPARAMETER ZEROP DYNAMIC-EXTENT FILE-STRING-LENGTH STRUCTURE
;            RPLACD SET-MACRO-CHARACTER CHAR/= SYMBOL-MACROLET CAAAR // *PACKAGE*
;            WITH-OPEN-FILE DEFSTRUCT TWO-WAY-STREAM ASSOC-IF-NOT SHORT-FLOAT
;            EXTENDED-CHAR < READ-CHAR-NO-HANG LOGAND ECHO-STREAM-INPUT-STREAM T
;            CHAR< FUNCTION BOOLE-ORC2 *MACROEXPAND-HOOK* STRING/= FBOUNDP /
;            RASSOC EVAL-WHEN CLRHASH WARN AND LISTEN RANDOM-STATE
;            SPECIAL-OPERATOR-P SYMBOL-PACKAGE COMPILATION-SPEED *LOAD-PRINT*
;            PPRINT-POP SEARCH LONG-FLOAT-EPSILON *TERMINAL-IO* CDDDAR
;            ADJUST-ARRAY MAKE-PATHNAME KEYWORD MERGE NO-APPLICABLE-METHOD
;            *PRINT-PPRINT-DISPATCH* VECTOR-POP SEQUENCE BIGNUM POP CHAR SETQ MOD
;            SIMPLE-STRING-P CERROR MAKE-ECHO-STREAM STRING-NOT-LESSP
;            *PRINT-BASE* UPDATE-INSTANCE-FOR-DIFFERENT-CLASS
;            FLOATING-POINT-UNDERFLOW HASH-TABLE-REHASH-THRESHOLD INCF LDB-TEST
;            LIST MEMBER-IF ARRAY-HAS-FILL-POINTER-P OPEN-STREAM-P THIRD &WHOLE
;            BIT-NOT GENSYM CCASE BOOLE-XOR SET-SYNTAX-FROM-CHAR DOLIST
;            ALPHANUMERICP STRING-STREAM MOST-NEGATIVE-SINGLE-FLOAT ELT TRUENAME
;            NSTRING-DOWNCASE LEAST-POSITIVE-NORMALIZED-SINGLE-FLOAT *READ-BASE*
;            NSET-DIFFERENCE THROW PHASE THE BIT-ANDC1 ASSERT ACOS
;            WILD-PATHNAME-P CDR DIGIT-CHAR-P MACROEXPAND-1 NSET-EXCLUSIVE-OR
;            TYPECASE PPRINT-INDENT CDADR CLASS-NAME COMPILE-FILE-PATHNAME
;            FDEFINITION RASSOC-IF APROPOS-LIST INTEGER-LENGTH *READ-SUPPRESS*
;            UNLESS NSTRING-CAPITALIZE FTYPE BUILT-IN-CLASS ** MAKE-CONDITION
;            STRING ENCODE-UNIVERSAL-TIME BIT-ANDC2 HASH-TABLE-SIZE CELL-ERROR
;            ATANH RATIONALP NAME-CHAR SET-DIFFERENCE BIT-NAND CONDITION
;            CHAR-GREATERP &OPTIONAL DISASSEMBLE ERROR CADDR SAFETY CHAR-CODE
;            WARNING ENDP *PRINT-RADIX* STANDARD-OBJECT MAPCAN PATHNAMEP
;            TWO-WAY-STREAM-OUTPUT-STREAM FMAKUNBOUND ARRAY-ROW-MAJOR-INDEX
;            SUBSEQ LOAD DELETE-IF-NOT UNBOUND-SLOT-INSTANCE LOGORC1 OPTIMIZE
;            STRING< STABLE-SORT NSUBSTITUTE DIGIT-CHAR ENOUGH-NAMESTRING
;            BYTE-POSITION PPRINT-LOGICAL-BLOCK SUBSTITUTE-IF TAILP
;            FLOATING-POINT-INEXACT EQL FIND-METHOD FLET ARRAY-TOTAL-SIZE-LIMIT
;            UNUSE-PACKAGE RATIO LEAST-NEGATIVE-NORMALIZED-LONG-FLOAT
;            GET-DISPATCH-MACRO-CHARACTER MAKE-SEQUENCE NBUTLAST NRECONC MACROLET
;            CHAR<= MINUSP PRINT-UNREADABLE-OBJECT LOWER-CASE-P STANDARD
;            HASH-TABLE-COUNT FLOAT-PRECISION REVAPPEND CALL-ARGUMENTS-LIMIT
;            READ-FROM-STRING UNDEFINED-FUNCTION COPY-READTABLE ASIN
;            DEFINE-SETF-EXPANDER HANDLER-BIND
;            LEAST-POSITIVE-NORMALIZED-LONG-FLOAT PPRINT-TAB NUNION REALP
;            POSITION-IF BOOLE-ANDC1 ABORT NUMBER DECLAIM COMPILED-FUNCTION-P
;            PACKAGE-USED-BY-LIST CHAR-NOT-LESSP WITH-INPUT-FROM-STRING
;            SIMPLE-WARNING STORE-VALUE *COMPILE-VERBOSE* DELETE-DUPLICATES
;            MOST-NEGATIVE-FIXNUM DELETE AREF DEFUN STREAM-ERROR BOOLE-C2
;            PPRINT-LINEAR MULTIPLE-VALUE-SETQ FILE-STREAM STRING-TRIM
;            REMOVE-IF-NOT UNREAD-CHAR OTHERWISE DESCRIBE RPLACA WRITE-SEQUENCE
;            MIN SOFTWARE-VERSION *PRINT-LEVEL* SECOND CHECK-TYPE PPRINT BUTLAST
;            BASE-CHAR COMPLEXP PATHNAME-NAME SLOT-UNBOUND ODDP PRIN1-TO-STRING
;            STRING-RIGHT-TRIM COMPILE-FILE ++ FILE-ERROR-PATHNAME PRINC
;            GET-PROPERTIES MOST-POSITIVE-FIXNUM MAKE-LOAD-FORM-SAVING-SLOTS
;            REALPART DIRECTORY CDADAR CONSTANTLY
;            FLOATING-POINT-INVALID-OPERATION NOTANY PATHNAME-MATCH-P DECF MEMBER
;            MULTIPLE-VALUE-PROG1 DEFGENERIC IDENTITY CHAR-CODE-LIMIT VECTOR-PUSH
;            DEFINE-SYMBOL-MACRO + GETF LEAST-NEGATIVE-LONG-FLOAT CHAR-DOWNCASE
;            LEAST-NEGATIVE-DOUBLE-FLOAT SINGLE-FLOAT-NEGATIVE-EPSILON
;            ADJUSTABLE-ARRAY-P SUBTYPEP *FEATURES* NUMBERP FILE-ERROR
;            POSITION-IF-NOT > DEFPACKAGE PPRINT-DISPATCH
;            MOST-POSITIVE-SINGLE-FLOAT SUBSTITUTE-IF-NOT COMPILED-FUNCTION LOG
;            DO* PARSE-INTEGER SIMPLE-ERROR LEAST-NEGATIVE-SINGLE-FLOAT
;            DEFINE-COMPILER-MACRO LOGANDC2 KEYWORDP FIND-ALL-SYMBOLS BIT-ORC1
;            *PRINT-CIRCLE* ARRAY-DIMENSION-LIMIT CAAR SPACE DOCUMENTATION
;            UPGRADED-COMPLEX-PART-TYPE STREAM PROGRAM-ERROR PUSHNEW MASK-FIELD
;            CHARACTERP LDIFF DIRECTORY-NAMESTRING LOOP-FINISH DPB
;            CHAR-NOT-GREATERP LENGTH LEAST-NEGATIVE-NORMALIZED-SINGLE-FLOAT
;            DRIBBLE SLOT-VALUE PPRINT-TABULAR SIMPLE-BASE-STRING SIGNED-BYTE
;            PACKAGE-ERROR-PACKAGE DEFINE-MODIFY-MACRO SHORT-SITE-NAME
;            ARRAY-RANK-LIMIT CODE-CHAR FUNCALL DEPOSIT-FIELD MAKE-ARRAY ED
;            COPY-PPRINT-DISPATCH BIT-ORC2 LOGICAL-PATHNAME FIND-SYMBOL
;            WRITE-STRING DO WRITE-BYTE CHAR-NOT-EQUAL MAPLIST BOOLEAN
;            ECHO-STREAM MAPL NSUBST-IF DEFTYPE EVAL USE-VALUE
;            TRANSLATE-LOGICAL-PATHNAME PRINT-NOT-READABLE-OBJECT PROG2
;            SUBSTITUTE *PRINT-PRETTY* TENTH FFLOOR STRING-NOT-EQUAL
;            INVOKE-RESTART-INTERACTIVELY /= DO-SYMBOLS MAP-INTO CTYPECASE
;            MULTIPLE-VALUE-BIND FOURTH CAADR MOST-NEGATIVE-SHORT-FLOAT &BODY
;            BOOLE *TRACE-OUTPUT* LOAD-LOGICAL-PATHNAME-TRANSLATIONS
;            SHORT-FLOAT-NEGATIVE-EPSILON ACOSH ALPHA-CHAR-P SIMPLE-ARRAY
;            PACKAGE-NAME RANDOM APROPOS DEBUG HASH-TABLE-P OR INVOKE-DEBUGGER
;            PRINT-NOT-READABLE CHAR-INT MAKE-SYNONYM-STREAM
;            MAKE-DISPATCH-MACRO-CHARACTER SIMPLE-BIT-VECTOR-P COUNT FILL
;            IGNORE-ERRORS LEAST-NEGATIVE-NORMALIZED-SHORT-FLOAT
;            LOGICAL-PATHNAME-TRANSLATIONS DO-ALL-SYMBOLS REVERSE MAKUNBOUND SOME
;            DECODE-UNIVERSAL-TIME SHORT-FLOAT-EPSILON COMPILER-MACRO-FUNCTION
;            RETURN PATHNAME-VERSION SUBLIS FIND-IF *STANDARD-INPUT*
;            MAKE-INSTANCE CLEAR-INPUT SINGLE-FLOAT-EPSILON MAKE-SYMBOL IMPORT
;            *PRINT-GENSYM* LET CADDAR BIT-VECTOR NSTRING-UPCASE
;            UPGRADED-ARRAY-ELEMENT-TYPE MULTIPLE-VALUE-LIST NUMERATOR =
;            SIMPLE-VECTOR-P SCALE-FLOAT ARITHMETIC-ERROR-OPERANDS PROG*
;            BOOLE-NAND UNTRACE INPUT-STREAM-P PSETF READTABLE METHOD-QUALIFIERS
;            FILE-POSITION USE-PACKAGE SYMBOL-VALUE NEXT-METHOD-P SIMPLE-STRING
;            GRAPHIC-CHAR-P STREAMP CDDAAR CALL-NEXT-METHOD
;            MOST-NEGATIVE-DOUBLE-FLOAT FILE-AUTHOR WHEN TYPE-OF BIT-NOR CHAR>
;            SINGLE-FLOAT ENSURE-GENERIC-FUNCTION PI *RANDOM-STATE* PSETQ EQ
;            HASH-TABLE EVENP *PRINT-RIGHT-MARGIN* OPEN REQUIRE GENTEMP
;            *READTABLE* MAKE-STRING-OUTPUT-STREAM CDAR LOGEQV DEFINE-CONDITION
;            CLASS-OF SIMPLE-CONDITION-FORMAT-CONTROL STANDARD-CHAR PACKAGE-ERROR
;            LOAD-TIME-VALUE PACKAGE 1- PROGV STORAGE-CONDITION <= FORMATTER
;            FILE-WRITE-DATE BOOLE-NOR UPDATE-INSTANCE-FOR-REDEFINED-CLASS TAN
;            END-OF-FILE IMAGPART BIT-VECTOR-P EQUAL FIND-CLASS DEFMACRO Y-OR-N-P
;            REST PATHNAME-DEVICE FUNCTION-KEYWORDS SET-EXCLUSIVE-OR NAMESTRING
;            HASH-TABLE-REHASH-SIZE GET-DECODED-TIME *COMPILE-PRINT*
;            CELL-ERROR-NAME INTEGERP ABS FLOAT-DIGITS SIMPLE-VECTOR
;            MOST-NEGATIVE-LONG-FLOAT FIND-RESTART IF REMF
;            DEFINE-METHOD-COMBINATION SHADOWING-IMPORT COMPLEX GO
;            WITH-HASH-TABLE-ITERATOR SET-PPRINT-DISPATCH CONCATENATED-STREAM
;            TYPE-ERROR-DATUM SLOT-MAKUNBOUND LEAST-POSITIVE-SINGLE-FLOAT
;            MAKE-INSTANCES-OBSOLETE SORT NSUBST PRINC-TO-STRING
;            TYPE-ERROR-EXPECTED-TYPE VALUES-LIST YES-OR-NO-P FLOAT-RADIX SIGNUM
;            READ-SEQUENCE *BREAK-ON-SIGNALS* MULTIPLE-VALUES-LIMIT CONCATENATE
;            PPRINT-NEWLINE COPY-TREE &REST &ENVIRONMENT METHOD-COMBINATION-ERROR
;            *GENSYM-COUNTER* STRUCTURE-CLASS ETYPECASE PARSE-ERROR
;            STRING-DOWNCASE * MAP SUBST-IF *DEBUG-IO* STRING-LEFT-TRIM SYMBOL
;            LONG-FLOAT-NEGATIVE-EPSILON PAIRLIS STRINGP LOOP LOGIOR VECTORP
;            BROADCAST-STREAM WITH-SLOTS CATCH MAKE-RANDOM-STATE FORMAT COPY-SEQ
;            STRING-LESSP APPLY REM CALL-METHOD IGNORE CONSP SYMBOLP
;            *PRINT-LENGTH* READ-DELIMITED-LIST SBIT READER-ERROR RESTART-CASE
;            PPRINT-EXIT-IF-LIST-EXHAUSTED FUNCTION-LAMBDA-EXPRESSION SIXTH FIND
;            SYMBOL-FUNCTION LOGNOT TRANSLATE-PATHNAME VALUES MACHINE-INSTANCE
;            STRING-UPCASE CADADR PEEK-CHAR *PRINT-READABLY* RESTART-BIND ASSOC
;            INTERACTIVE-STREAM-P SINH CDDAR UNBOUND-SLOT STRING> GCD PACKAGEP
;            UPPER-CASE-P TRUNCATE RENAME-FILE CADAAR BOOLE-IOR
;            INITIALIZE-INSTANCE MAKE-STRING STANDARD-CHAR-P &AUX NSUBSTITUTE-IF
;            DECLARE CDDR CLOSE ARRAY-DISPLACEMENT WRITE INTEGER CHAR>= VARIABLE
;            MERGE-PATHNAMES WITH-SIMPLE-RESTART BYTE-SIZE ASH COMPILE IGNORABLE
;            NOTEVERY MISMATCH INVALID-METHOD-ERROR FORCE-OUTPUT
;            REMOVE-DUPLICATES UNSIGNED-BYTE MAKE-METHOD RESTART-NAME BOOLE-AND
;            FINISH-OUTPUT UNWIND-PROTECT BOOLE-EQV *PRINT-CASE* WITH-ACCESSORS
;            *PRINT-ARRAY* SVREF ARRAY-DIMENSIONS - METHOD DEFVAR SEVENTH
;            MOST-POSITIVE-DOUBLE-FLOAT REMOVE-METHOD PATHNAME-TYPE TIME BOUNDP
;            LAMBDA-PARAMETERS-LIMIT ROTATEF LONG-SITE-NAME LOCALLY
;            DIVISION-BY-ZERO SLOT-BOUNDP SIMPLE-CONDITION BOTH-CASE-P
;            GET-MACRO-CHARACTER LIST-ALL-PACKAGES STRUCTURE-OBJECT MAKE-LIST
;            SIMPLE-CONDITION-FORMAT-ARGUMENTS BOOLE-ORC1 MAKE-HASH-TABLE
;            FIND-IF-NOT COPY-LIST CEILING GETHASH BYTE
;            CONCATENATED-STREAM-STREAMS DELETE-IF *QUERY-IO* PUSH
;            FLOATING-POINT-OVERFLOW ROOM TYPEP FRESH-LINE PRINT REMOVE NREVERSE
;            MAPHASH DO-EXTERNAL-SYMBOLS ECHO-STREAM-OUTPUT-STREAM COND NTH LISTP
;            FLOAT ARRAYP SHARED-INITIALIZE ASSOC-IF EQUALP ALLOCATE-INSTANCE BIT
;            BOOLE-ANDC2 HOST-NAMESTRING CONS BASE-STRING
;            ARITHMETIC-ERROR-OPERATION NSUBSTITUTE-IF-NOT RANDOM-STATE-P
;            NSUBST-IF-NOT READ-LINE READ-CHAR TERPRI MAKE-BROADCAST-STREAM
;            SUBSETP MULTIPLE-VALUE-CALL MAKE-LOAD-FORM STRING-EQUAL
;            VECTOR-PUSH-EXTEND MAKE-STRING-INPUT-STREAM TREE-EQUAL CAADDR GET
;            EXPT CONTINUE LEAST-POSITIVE-LONG-FLOAT TAGBODY STRING-NOT-GREATERP
;            OUTPUT-STREAM-P BIT-XOR CLEAR-OUTPUT RASSOC-IF-NOT
;            REINITIALIZE-INSTANCE SXHASH SIMPLE-TYPE-ERROR
;            LEAST-POSITIVE-SHORT-FLOAT INVOKE-RESTART RESTART EXPORT QUOTE
;            ADD-METHOD PACKAGE-USE-LIST COPY-STRUCTURE TYPE-ERROR
;            PARSE-NAMESTRING PATHNAME-HOST READ-PRESERVING-WHITESPACE CASE
;            ARRAY-TOTAL-SIZE INSPECT LIST* COMPUTE-RESTARTS DEFCONSTANT
;            DENOMINATOR PROCLAIM MACHINE-VERSION LONG-FLOAT CDADDR CAR READ
;            MAKE-TWO-WAY-STREAM GENERIC-FUNCTION DEFSETF LABELS ATAN
;            ARRAY-ELEMENT-TYPE PACKAGE-SHADOWING-SYMBOLS COUNT-IF-NOT
;            ARITHMETIC-ERROR MOST-POSITIVE-SHORT-FLOAT CDDADR LDB
;            HASH-TABLE-TEST *DEFAULT-PATHNAME-DEFAULTS* LAMBDA
;            LEAST-NEGATIVE-NORMALIZED-DOUBLE-FLOAT MACRO-FUNCTION
;            WRITE-TO-STRING REPLACE REMOVE-IF SUBST-IF-NOT ARRAY-RANK MAX INLINE
;            LOGXOR INTERNAL-TIME-UNITS-PER-SECOND NTH-VALUE
;            DOUBLE-FLOAT-NEGATIVE-EPSILON COSH SCHAR NINTERSECTION SATISFIES
;            REDUCE ECASE INTERN CDAAR LOGNOR *** INTERSECTION SPEED STRING>=
;            DECLARATION *LOAD-VERBOSE* *PRINT-LINES* LEAST-POSITIVE-DOUBLE-FLOAT
;            RATIONAL UNBOUND-VARIABLE CHAR-UPCASE FILL-POINTER SLEEP PRIN1 1+
;            COMPLEMENT INTEGER-DECODE-FLOAT EVERY RENAME-PACKAGE
;            GET-INTERNAL-RUN-TIME UNEXPORT STREAM-EXTERNAL-FORMAT
;            ARRAY-IN-BOUNDS-P WITH-PACKAGE-ITERATOR LISP-IMPLEMENTATION-VERSION
;            CAADAR DOTIMES CIS ENSURE-DIRECTORIES-EXIST CHAR-NAME MUFFLE-WARNING
;            *DEBUGGER-HOOK* FIRST ASINH CONSTANTP DOUBLE-FLOAT
;            *READ-DEFAULT-FLOAT-FORMAT* DEFCLASS STEP METHOD-COMBINATION
;            WITH-CONDITION-RESTARTS PROVIDE *STANDARD-OUTPUT* MACHINE-TYPE NINTH
;            SQRT COS LOGANDC1 PACKAGE-NICKNAMES FUNCTIONP NO-NEXT-METHOD MAPC
;            CHARACTER CDDDR NOTINLINE MAKE-CONCATENATED-STREAM REAL CDAAAR
;            GET-SETF-EXPANSION SLOT-EXISTS-P BLOCK WRITE-LINE CHANGE-CLASS SUBST
;            WRITE-CHAR READTABLEP NTHCDR SOFTWARE-TYPE
;            TWO-WAY-STREAM-INPUT-STREAM MAKE-PACKAGE ACONS
;            LEAST-NEGATIVE-SHORT-FLOAT FLOATP CAAAAR MAPCAR LOGCOUNT ATOM
;            FCEILING ARRAY-DIMENSION DECODE-FLOAT SERIOUS-CONDITION SYMBOL-NAME
;            STRING-GREATERP SIGNAL *ERROR-OUTPUT* *COMPILE-FILE-TRUENAME*
;            FILE-NAMESTRING *PRINT-MISER-WIDTH* UNINTERN GET-UNIVERSAL-TIME
;            LIST-LENGTH CADR FIXNUM WITH-STANDARD-IO-SYNTAX WITH-OPEN-STREAM
;            DESTRUCTURING-BIND *LOAD-TRUENAME* FROUND WITH-COMPILATION-UNIT
;            EIGHTH SETF &KEY PROGN LAMBDA-LIST-KEYWORDS STYLE-WARNING
;            &ALLOW-OTHER-KEYS CHAR= MACROEXPAND GET-OUTPUT-STREAM-STRING COERCE
;            *READ-EVAL*)(nth-value 1 (dir (find-package 'cl)))
; 978

天啦天啦天啦,这个common-lisp包里居然有978个可供外部访问的符号!好奇先生简直要疯了!

好奇先生想要对每一个符号使用describe,并且把所有的符号都输出到一个文件里,于是他写了一个函数。

;; print all symbols and doc strings in a file
(defun dir-package (package)
  "List all external symbols in a package and their doc strings in a file"
  (let ((sorted-names (sort (dir package) #'string<))
        (fn (format nil "~a.md" package)))
    (with-open-stream (s (open fn :direction :output :if-exists :supersede))
      ;; header line
      (format s "# ~a external symbols~%~%~%" package)
      ;; list all external symbols     
      (let ((index 1))
        (dolist (name sorted-names)
          (format s "~d. [~A](#~A)~%" index name name)
          (incf index)))
      (format s "~%~%")
      ;; describe all external symbols
      (dolist (name sorted-names)
        (format s "##  `~a`~%~%" name)
        (format s "```lisp~%")
        (describe name s)
        (format s "```~%")))))

这下好了,好奇先生有一个markdown文件,里面包含了所有的符号和他们的文档字符串。好奇先生对这个文件简直是爱不释手。

# CL external symbols


1. [&ALLOW-OTHER-KEYS](#&ALLOW-OTHER-KEYS)
2. [&AUX](#&AUX)
3. [&BODY](#&BODY)
4. [&ENVIRONMENT](#&ENVIRONMENT)
5. [&KEY](#&KEY)
6. [&OPTIONAL](#&OPTIONAL)
7. [&REST](#&REST)
8. [&WHOLE](#&WHOLE)
9. [*](#*)
10. [**](#**)
11. [***](#***)
12. [*BREAK-ON-SIGNALS*](#*BREAK-ON-SIGNALS*)
13. [*COMPILE-FILE-PATHNAME*](#*COMPILE-FILE-PATHNAME*)
14. [*COMPILE-FILE-TRUENAME*](#*COMPILE-FILE-TRUENAME*)
15. [*COMPILE-PRINT*](#*COMPILE-PRINT*)
16. [*COMPILE-VERBOSE*](#*COMPILE-VERBOSE*)
17. [*DEBUG-IO*](#*DEBUG-IO*)
18. [*DEBUGGER-HOOK*](#*DEBUGGER-HOOK*)
19. [*DEFAULT-PATHNAME-DEFAULTS*](#*DEFAULT-PATHNAME-DEFAULTS*)
20. [*ERROR-OUTPUT*](#*ERROR-OUTPUT*)
21. [*FEATURES*](#*FEATURES*)
22. [*GENSYM-COUNTER*](#*GENSYM-COUNTER*)
23. [*LOAD-PATHNAME*](#*LOAD-PATHNAME*)
24. [*LOAD-PRINT*](#*LOAD-PRINT*)
25. [*LOAD-TRUENAME*](#*LOAD-TRUENAME*)
26. [*LOAD-VERBOSE*](#*LOAD-VERBOSE*)
27. [*MACROEXPAND-HOOK*](#*MACROEXPAND-HOOK*)
28. [*MODULES*](#*MODULES*)
29. [*PACKAGE*](#*PACKAGE*)
30. [*PRINT-ARRAY*](#*PRINT-ARRAY*)
31. [*PRINT-BASE*](#*PRINT-BASE*)
32. [*PRINT-CASE*](#*PRINT-CASE*)
33. [*PRINT-CIRCLE*](#*PRINT-CIRCLE*)
34. [*PRINT-ESCAPE*](#*PRINT-ESCAPE*)
35. [*PRINT-GENSYM*](#*PRINT-GENSYM*)

...


##  `YES-OR-NO-P`

COMMON-LISP:YES-OR-NO-P
  [symbol]

YES-OR-NO-P names a compiled function:
  Lambda-list: (&OPTIONAL FORMAT-STRING &REST ARGUMENTS)
  Declared type: (FUNCTION
                  (&OPTIONAL (OR STRING NULL FUNCTION) &REST T)
                  (VALUES BOOLEAN &OPTIONAL))
  Derived type: (FUNCTION (&OPTIONAL T &REST T)
                 (VALUES BOOLEAN &OPTIONAL))
  Documentation:
    YES-OR-NO-P is similar to Y-OR-N-P, except that it clears the
       input buffer, beeps, and uses READ-LINE to get the strings
       YES or NO.
  Source file: SYS:SRC;CODE;QUERY.LISP

##  `ZEROP`

COMMON-LISP:ZEROP
  [symbol]

ZEROP names a compiled function:
  Lambda-list: (NUMBER)
  Declared type: (FUNCTION (NUMBER) (VALUES BOOLEAN &OPTIONAL))
  Derived type: (FUNCTION (T) (VALUES BOOLEAN &OPTIONAL))
  Documentation:
    Is this number zero?
  Known attributes: foldable, flushable, unsafely-flushable, movable
  Source file: SYS:SRC;CODE;NUMBERS.LISP

这个文件实在太长了,只能每个人都产生了在自己电脑上查看。

好奇先生的部分好奇心暂时得到完全的满足,他有一整套工具对自己的Lisp系统进行探索。真是太棒了!

总结

  1. 包是Lisp中的一个重要概念,它可以帮助我们组织符号。
  2. 一个包可以包含很多符号,我们可以通过do-external-symbols来遍历一个包中的所有符号。
  3. 一个符号可以有文档字符串,我们可以通过describe来查看一个符号的文档字符串。
  4. 对于Lisp的学习,应该尽快建立REPL工具,然后用Lisp来探索Lisp。

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

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

相关文章

Figma 替代品 Penpot 安装和使用教程

在设计领域&#xff0c;Figma 无疑是一个巨人。它彻底改变了设计流程&#xff0c;将协作带到了一个全新的高度。然而&#xff0c;随着 Adobe 收购 Figma 的消息传出&#xff0c;许多设计师和开发者开始担心&#xff1a;Figma 未来会如何演变&#xff1f;那些好用的特性会不会被…

【python】深入探讨python中的抽象类,创建、实现方法以及应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【SpringBoot】11 多数据源(MyBatis:dynamic-datasource)

介绍 多数据源&#xff1a;指的是一个单一应用程序中涉及了两个及以上的数据库&#xff0c;这种配置允许应用程序根据业务需求灵活地管理和操作不同的数据库。 需求 一个应用服务中&#xff0c;连接多个数据库&#xff0c;有本地的也有远程的&#xff0c;有MysQL、Oracle、P…

代码随想录算法训练营day51:图论02:99. 岛屿数量;100. 岛屿的最大面积

99. 岛屿数量 卡码网题目链接&#xff08;ACM模式&#xff09;(opens new window) 题目描述&#xff1a; 给定一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的矩阵&#xff0c;你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而…

PHP农场扶农系统智慧认养智慧乡村系统农场系统小程序源码

&#x1f331;科技赋能田园梦 —— 探索“农场扶农系统”与“智慧认养智慧乡村”新篇章&#x1f680; &#x1f308;【开篇&#xff1a;田园新风尚&#xff0c;科技引领未来】 在快节奏的都市生活中&#xff0c;你是否曾梦想过拥有一片属于自己的绿色天地&#xff1f;现在&am…

大一新生看过来,【入学证件照】这样拍才可以千万不要拍错了

大一新生在拍摄证件照时&#xff0c;确实需要注意一些关键点&#xff0c;以确保照片符合规定并能成功使用。‌不会的可以多看看我首页说明&#xff0c;VX小城续&#xff1a;桃子证件照&#xff0c;帮你搞定大学四年所以的照片可以打印邮寄 首先&#xff0c;重要的是要注意以下几…

通信总线-串口/IIC/SPI

基本概念 1.串行&#xff1a;只有一个数据线&#xff0c;bit&#xff08;位&#xff09;一个一个传输&#xff08;本质传输的是电信号&#xff0c;高低电平代表0或1&#xff09; 更常用&#xff08;UART&#xff0c;IIC&#xff0c;SPI&#xff09; 2.并行&#xff1a;多个…

企业文件防泄密怎么做?10款透明加密软件排行榜

在信息时代&#xff0c;企业的核心竞争力往往体现在其拥有的知识和信息上&#xff0c;而企业文件的安全性直接关系到这些信息的保护。文件防泄密已成为企业管理中的重要议题&#xff0c;透明加密技术因其无缝集成和高效保护的特性&#xff0c;成为企业防泄密的首选方案。2024年…

RabbitMQ与ElasticSearch面试

目录 RabbitMQ 1、你们项目中哪里用到了RabbitMQ 2、为什么会选择使用RabbitMQ 3、使用RabbitMQ如何保证消息不丢失 4、消息的重复消费问题如何解决的 5、如何解决消息堆积在MQ的问题 6、RabbitMQ如何保证消费的顺序性 7、RabbitMQ的延迟队列有了解过嘛 8、RabbitMQ如…

<数据集>流水线物件识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;8643张 标注数量(xml文件个数)&#xff1a;8643 标注数量(txt文件个数)&#xff1a;8643 标注类别数&#xff1a;26 标注类别名称&#xff1a;[Crankshaft, Centrifugal_body, Washer_container, Circlip_containe…

FTP协议-匿名用户登录 从0到1

前言 日常大家可能接触web漏洞比较多而对其他端口及协议不那么了解&#xff0c;其实其他协议漏洞在渗透中也同样重要只是平时可能接触得不多。本文将介绍FTP协议、FTP匿名用户登录及其具体流程分析和自动化利用demo。 FTP简介 FTP是File Transfer Protocol&#xff08;文件传…

利用Aspose.BarCode 在 C# 中创建微型二维码

Aspose.BarCode提供多种编程语言的 API&#xff0c;例如Java、Python、C等。它提供了强大的解决方案&#xff0c;可以通过编程创建和处理条形码和二维码&#xff0c;我们将实现如何使用Aspose.BarCode for .NET在 C# 中创建微型二维码。接下来&#xff0c;我们还将演示如何以编…

软件测试工程师是做什么的?

软件测试工程师扮演着软件开发过程中的关键角色&#xff0c;他们的主要职责是对软件进行全面的测试&#xff0c;确保其质量和稳定性。 随着软件行业的迅猛发展&#xff0c;对这类专业人才的需求也在不断增长。 本文将深入探讨软件测试工程师的职责及其所需的技能。 一、软件测…

新技术能够区分真实照片和 AI 伪造图片,但为何平台没有使用?|TodayAI

随着生成式 AI 图像工具的快速发展&#xff0c;网络上越来越多的图像真假难辨。尽管已有技术能够区分真实照片和 AI 伪造图片&#xff0c;但大多数在线平台尚未充分利用这一技术。随着美国总统大选临近&#xff0c;网络上充斥着关于候选人唐纳德特朗普和卡玛拉哈里斯的各种照片…

组合模式 详解

组合模式 简介: 将对象组合成树形结构以表示"部分-整体"的层次结构, 使得用户对单个对象和组合对象的使用具有一致性. 组合模式也是一种结构类型的模式.看简介比较容易理解, 毕竟树形结构是数据结构必修的, 我们仍然举个例子方便理解 以公司的组织架构为例 公司 - …

Web大学生网页作业成品——明星EXO介绍网页设计与实现(HTML+CSS)(10个页面)(TABLE布局)

&#x1f389;&#x1f389;&#x1f389; 常见网页设计作业题材有**汽车、环保、明星、文化、国家、抗疫、景点、人物、体育、植物、公益、图书、节日、游戏、商城、旅游、家乡、学校、电影、动漫、非遗、动物、个人、企业、美食、婚纱、其他**等网页设计题目, 可满足大学生网…

LED 数码显示管的结构

LED 数码显示管是一种常用的字符显示器件,能与 CMOS、TTL 等集成电路直接配合,作静态、动态扫描显示之用。图12-33(a)是LED数码显示管的实物图&#xff0c;图 12-33(b)是LED数码显示管的内部结构。它实际上是由8个发光二极管构成的&#xff0c;其中7个发光二极管排列成“8”字形…

【线性表】内容总结

1.单链表&#xff0c;循环链表&#xff0c;双向链表的循环效率 2.顺序表和链表的比较 1.什么是存储密度 1.定义&#xff1a; 存储密度是指结点数据本身所占的存储量和整个结点结构中所占的存储量 之比&#xff0c;即: 2.实例 比如在32位系统上&#xff0c;一个12字节的结…

保姆级Python与PyCharm安装教程

本文演示所用的所用的所有工具包都已经打包好了&#xff0c;【点击这里】即可获得 一、简介 Python是一种广泛使用的高级编程语言&#xff0c;因其简洁的语法和丰富的库支持&#xff0c;在数据科学、Web开发、人工智能等领域广受欢迎。PyCharm是由JetBrains开发的一款针对Pyt…

一篇文章带你了解归并排序-分治法

文章目录 两个有序数组排序一个局部有序数组排序分治法归并排序 两个有序数组排序 先来一个场景假设&#xff0c;先有两个有序数组{1,3,5,9}、{2,4,6,8}&#xff0c;要求合并成一个有序数组。 我们先上一段简单的处理代码 public static int[] merge(int[] leftArr, int[] righ…