📄 faq.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Pico Lisp FAQ</title><link rel="stylesheet" href="doc.css" type="text/css"></head><body><a href="mailto:abu@software-lab.de">abu@software-lab.de</a><p align=right><i>Monk: "If I have nothing in my mind, what shall I do?"</i><br><i>Joshu: "Throw it out."</i><br><i>Monk: "But if there is nothing, how can I throw it out?"</i><br><i>Joshu: "Well, then carry it out."</i><br><i>(Zen koan)</i><br><h1>Pico Lisp Frequently Asked Questions</h1><p align=right>(c) Software Lab. Alexander Burger<p><ul><li><a href="#yet">Why did you write yet another Lisp?</a><li><a href="#who">Who can use Pico Lisp?</a><li><a href="#advantages">What are the advantages over other Lisp systems?</a><li><a href="#performance">How is the performance compared to other Lisp systems?</a><li><a href="#interpreted">What means "interpreted"?</a><li><a href="#compiler">Is there (or will be in the future) a compiler available?</a><li><a href="#portable">Is it portable?</a><li><a href="#webServer">Is Pico Lisp a web server?</a><li><a href="#lambda">I cannot find the LAMBDA keyword in Pico Lisp</a><li><a href="#dynamic">Why do you use dynamic variable binding?</a><li><a href="#problems">Are there no problems caused by dynamic binding?</a><li><a href="#closures">But with dynamic binding I cannot implement closures!</a><li><a href="#macros">Do you have macros?</a><li><a href="#bind">What happens when I locally bind a symbol which has a function definition?</a><li><a href="#hardware">Would it make sense to build Pico Lisp in hardware?</a><li><a href="#few">Why are there only a few questions in this FAQ?</a></ul><p><hr><h2><a name="yet">Why did you write yet another Lisp?</a></h2><p>Because other Lisps are not the way I'd like them to be. They concentrate onefficient compilation, and lost the one-to-one relationship of language andvirtual machine of an interpreted system, gave up power and flexibility, andimpose unnecessary limitations on the freedom of the programmer. Other reasonsare the case-insensitivity and complexity of current Lisp systems.<p><hr><h2><a name="who">Who can use Pico Lisp?</a></h2><p>Pico Lisp is for programmers who want to control their programmingenvironment, at all levels, from the application domain down to the bare metal.Who want use a transparent and simple - yet universal - programming model, andwant to know exactly what is going on. This is an aspect influenced by Forth.<p>It does <i>not</i> pretend to be easy to learn. There are already plenty oflanguages that do so. It is not for people who don't care what's under the hood,who just want to get their application running. They are better served with somestandard, "safe" black-box, which may be easier to learn, and which allegedlybetter protects them from their own mistakes.<p><hr><h2><a name="advantages">What are the advantages over other Lisp systems?</a></h2><h3>Simplicity</h3><p>Pico Lisp is easy to understand and adapt. There is no compiler enforcingspecial rules, and the interpreter is simple and straightforward. There are onlythree data types: Numbers, symbols and lists ("LISP" means "List-, Integer- andSymbol Processing" after all ;-). The memory footprint is minimal, and thetarball size of the whole system is just a few hundred kilobytes.<h3>A Clear Model</h3><p>Most other systems define the language, and leave it up to the implementationto follow the specifications. Therefore, language designers try to be asabstract and general as possible, leaving many questions and ambiguities to theusers of the language.<p>Pico Lisp does the opposite. Initially, only the single-cell data structurewas defined, and then the structure of numbers, symbols and lists as they arecomposed of these cells. Everything else in the whole system follows from theseaxioms. This is documented in the chapter about the <a href="ref.html#vm">ThePico Machine</a> in the reference manual.<h3>Orthogonality</h3><p>There is only one symbolic data type, no distinction (confusion) betweensymbols, strings, variables, special variables and identifiers.<p>Most data-manipulation functions operate on the value cells of symbols aswell as the <code>CAR</code>s of list cells:<p><pre><code>: (let (N 7 L (7 7 7)) (inc 'N) (inc (cdr L)) (cons N L))-> (8 7 8 7)</code></pre><p>There is only a single functional type, no "special forms". As there is nocompiler, functions can be used instead of macros. No special "syntax"constructs are needed. This allows a completely orthogonal use of functions. Forexample, most other Lisps do not allow calls like<p><pre><code>: (mapcar if '(T NIL T NIL) '(1 2 3 4) '(5 6 7 8))-> (1 6 3 8)</code></pre><p>Pico Lisp has no such restrictions. It favors the principle of "LeastAstonishment".<h3>Object System</h3><p>The OOP system is most powerful, because it is fully dynamic, yet extremelysimple:<p><ul><li>In other systems you have to statically declare "slots". In Pico Lisp,classes and objects are completely dynamic, they are created and extended atruntime. "Slots" don't even exist at creation time. They spring into existencepurely dynamically. You can add any new property or any new method to any singleobject, at any time, regardless of its class.<li>The multiple inheritance is such that not only classes can have severalsuperclasses, but each individual object can be of more than one class.<li>Prefix classes can surgically change the inheritance tree for any class orobject.<li>Fine-control of inheritance in methods with <code><ahref="refS.html#super">super</a></code> and <code><ahref="refE.html#extra">extra</a></code>.</ul><h3>Pragmatism</h3><p>Pico Lisp has many practical features not found in other Lisp dialects. Amongthem are:<p><ul><li>Auto-quoting of lists when the <code>CAR</code> is a number. Instead of<code>'(1 2 3)</code> you can just write <code>(1 2 3)</code>. This is possiblebecause a number never makes sense as a function name, and has to be checked atruntime anyway.<li>The <code><a href="refQ.html#quote">quote</a></code> function returns allunevaluated arguments, instead of just the first one. This is both faster(<code>quote</code> does not have to take the <code>CAR</code> of its argumentlist) and smaller (a single cell instead of two). For example, <code>'A</code>expands to <code>(quote . A)</code> and <code>'(A B C)</code> expands to<code>(quote A B C)</code>.<li>The symbol <code><a href="ref.html#atres">@</a></code> is automaticallymaintained as a local variable, and set implicitly in certain flow- andlogic-functions. This makes it often unnecessary to allocate and assign localvariables.<li><a href="tut.html#funio">Functional I/O</a> is more convenient thanexplicitly passing around file descriptors.<li>A well-defined <a href="ref.html#cmp">ordinal relationship</a> betweenarbitrary data types facilitates generalized comparing and sorting.<li>Uniform handling of <code>var</code> locations (i.e. values of symbols and<code>CAR</code>s of list cells).<li>The universality and usefulness of symbol properties is enforced andextended with implicit and explicit bindings of the symbol <code><ahref="refT.html#This">This</a></code> in combination with the access functions<code><a href="ref_.html#=:">=:</a></code>, <code><ahref="ref_.html#:">:</a></code> and <code><a href="ref_.html#::">::</a></code>.<li>A very convenient list-building machinery, using the <code><ahref="refL.html#link">link</a></code>, <code><ahref="refY.html#yoke">yoke</a></code>, <code><ahref="refC.html#chain">chain</a></code> and <code><ahref="refM.html#made">made</a></code> functions in the <code><ahref="refM.html#make">make</a></code> environment.<li>The syntax of often-used functions is kept non-verbose. For example, insteadof <code>(let ((A 1) (B 2) C 3) ..)</code> you write <code>(let (A 1 B 2 C 3)..)</code>, or just <code>(let A 1 ..)</code> if there is only a singlevariable.<li>The use of the hash character (<code>#</code>) as a comment delimiter ismore adequate today, and allows a clean hash-bang (<code>#!</code>) syntax forstand-alone scripts.<li>The interpreter is <a href="ref.html#invoc">invoked</a> with a simple andflexible syntax, where command line arguments are either files to be interpretedor functions to be directly executed. With that, many tasks can be performedwithout writing a separate <a href="tut.html#script">script</a>.<li>A sophisticated system of interprocess communication, file locking andsynchronization allows multi-user access to database applications.<li>A Prolog interpreter is tightly integrated into the language. Prologclauses can call Lisp expressions and vice versa, and a self-adjustingdepth-first search predicate <code>select</code> can be used in databasequeries.</ul><h3>Persistent Symbols</h3><p>Database objects ("external" symbols) are a primary data type in Pico Lisp.They look like normal symbols to the programmer, but are managed (fetched fromand stored to the data base) automatically by the system. Symbol manipulationfunctions like <code>set</code>, <code>put</code> or <code>get</code>, thegarbage collector, and other parts of the interpreter know about them.<h3>Application Server</h3><p>Stand-alone system: Does not depend on external programs like Apache orMySQL. Provides a "live" user interface on the client side, with an applicationserver session for each connected client. The GUI layout and behavior isdescribed with s-expressions, generated dynamically at runtime, and mapsdirectly to the database structures.<h3>Localization</h3><p>Internal exclusive and full use of UTF-8 encoding, and self-translatingtransient symbols (strings), make it easy to write country- andlanguage-independent applications.<p><hr><h2><a name="performance">How is the performance compared to other Lisp systems?</a></h2><p>Despite the fact that Pico Lisp is an interpreted-only system, theperformance is quite good. Typical Lisp programs, operating on list datastructures, execute in (interpreted) Pico Lisp at about the same speed as in(compiled) CMUCL, and about two or three times faster than in CLisp or Scheme48.Programs with lots of numeric calculations, however, are several times slower,probably due to Pico Lisp's somewhat inefficient implementation of bignums.<p>But in practice, speed was never a problem, even with the first versions ofPico Lisp in 1988 on a Mac II with a 12 MHz CPU. And certain things are cleanerand easier to do in plain C anyway. It is very easy to write C functions in PicoLisp, either in the kernel, as shared object libraries, or even inline in theLisp code.<p>Pico Lisp is very space-effective. Other Lisp systems reserve heap spacetwice as much as needed, or use rather large internal structures to store cellsand symbols. The cells (and also the minimal symbols) in Pico Lisp use only 8bytes each. No additional tags are stored, because they are implied in thepointer encodings. No gaps remain in the heap during allocation, as there areonly objects of a single size. As a result, consing and garbage collection arevery fast, and overall performance benefits from a better cache efficiency. Heapand stack grow automatically, and are limited only by hardware and operatingsystem constraints.<p><hr><h2><a name="interpreted">What means "interpreted"?</a></h2><p>It means to directly execute Lisp data as program code. No transformation tosome other representation of code (e.g. compilation), and no structuralmodifications of these data, takes place.<p>Lisp data are the "real" things, like numbers, symbols and lists, which canbe directly handled by the system. They are <i>not</i> the textualrepresentation of these structures (which is outside the Lisp realm and takencare of the <code><a href="refR.html#read">read</a></code>ing and <code><ahref="refP.html#print">print</a></code>ing interfaces).<p>The following example builds a function and immediately calls it with twoarguments:<p><pre><code>: ((list (list 'X 'Y) (list '* 'X 'Y)) 3 4)-> 12</code></pre><p>Note that no time is wasted to build up a lexical environment. Variablebindings take place dynamically during interpretation.<p>A Pico Lisp function is able to inspect or modify itself while it is running(though this is rarely done in application programming). The following functionmodifies itself by incrementing the '0' in its body:<p><pre><code>(de incMe () (do 8 (printsp 0) (inc (cdadr (cdadr incMe))) ) ): (incMe)0 1 2 3 4 5 6 7 -> 8: (incMe)8 9 10 11 12 13 14 15 -> 16</code></pre><p>Only an interpreted Lisp can fully support such "Equivalence of Code andData". If executable pieces of data are used frequently, like in Pico Lisp'sdynamically generated GUI, a fast interpreter is preferable over any compiler.<p><hr><h2><a name="compiler">Is there (or will be in the future) a compiler available?</a></h2><p>No. That would contradict the idea of Pico's simple virtual machinestructure. A compiler transforms it to another (physical) machine, with the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -