commit 86592afd4aa1662c69773633726a0cc28afce45f
parent 584194fceb6af154a4e7504cc0fd625b7bc8ef0f
Author: Alexander Burger <abu@software-lab.de>
Date: Fri, 12 Aug 2011 11:52:53 +0200
FAQ/docs updates
Diffstat:
4 files changed, 46 insertions(+), 24 deletions(-)
diff --git a/doc/faq.html b/doc/faq.html
@@ -35,6 +35,7 @@
<li><a href="#macros">Do you have macros?</a>
<li><a href="#strings">Why are there no strings?</a>
<li><a href="#arrays">What about arrays?</a>
+<li><a href="#floats">How to do floating point arithmetics?</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 PicoLisp in hardware?</a>
<li><a href="#segfault">I get a segfault if I ...</a>
@@ -232,15 +233,15 @@ write country- and language-independent applications.
is quite good. Typical Lisp programs operating on list data structures are
executed in (interpreted) PicoLisp 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. This is
-mainly due to PicoLisp's somewhat inefficient implementation of bignums in the
-32-bit version.
+with lots of numeric calculations, however, may be slower on a 32-bit system,
+due to PicoLisp's somewhat inefficient implementation of numbers. The 64-bit
+version improved on that.
<p>But in practice, speed was never a problem, even with the first versions of
PicoLisp in 1988 on a Mac II with a 12 MHz CPU. And certain things are cleaner
-and easier to do in plain <code>C</code> anyway. It is very easy to write
-<code>C</code> functions in PicoLisp, either in the kernel, as shared object
-libraries, or even inline in the Lisp code.
+and easier to do in plain <code>C</code> or <code>asm</code> anyway. It is very
+easy to write <code>C</code> functions in PicoLisp, either in the kernel, as
+shared object libraries, or even inline in the Lisp code.
<p>PicoLisp is very space-effective. Other Lisp systems reserve heap space twice
as much as needed, or use rather large internal structures to store cells and
@@ -305,11 +306,10 @@ dynamically generated GUI, a fast interpreter is preferable over any compiler.
structure. A compiler transforms it to another (physical) machine, with the
result that many assumptions about the machine's behavior won't hold any more.
Besides that, PicoLisp primitive functions evaluate their arguments
-independently and are not very much suited for being called from compiled code.
-Finally, the gain in execution speed would probably not be worth the effort.
-Typical PicoLisp applications often use single-pass code which is loaded,
-executed and thrown away; a process that would be considerably slowed down by
-compilation.
+independently and are not suited for being called from compiled code. Finally,
+the gain in execution speed would probably not be worth the effort. Typical
+PicoLisp applications often use single-pass code which is loaded, executed and
+thrown away; a process that would be considerably slowed down by compilation.
<p><hr>
@@ -336,9 +336,6 @@ obvious: Browsers are installed virtually everywhere. So we developed a protocol
which persuades a browser to function as a GUI front-end to our applications.
This is much simpler than to develop a full-blown web server.
-<p>In a sense, PicoLisp is a "pure" application server, not a web server
-handling "web applications".
-
<p><hr>
<h2><a name="lambda">I cannot find the LAMBDA keyword in PicoLisp</a></h2>
@@ -475,10 +472,11 @@ utilities than in production code, so that they can be easily encapsulated.
<p>This is not true. Closures are a matter of scope, not of binding.
-<p>For a closure it is necessary to build and maintain an environment. For
-lexical bindings, this has <i>always</i> to be done, and in case of compiled
-code it is the most efficient strategy anyway, because it is done once by the
-compiler, and can then be accessed as stack frames at runtime.
+<p>For a closure it is necessary to build and maintain a separate environment.
+In a system with lexical bindings, this has to be done at <i>each</i> function
+call, and for compiled code it is the most efficient strategy anyway, because it
+is done once by the compiler, and can then be accessed as stack frames at
+runtime.
<p>For an interpreter, however, this is quite an overhead. So it should not be
done automatically at each and every function invocation, but only if needed.
@@ -490,6 +488,10 @@ href="refB.html#bind">bind</a></code> or <code><a
href="refJ.html#job">job</a></code>, which dynamically manage statically scoped
environments.
+<p>Environments are first-class objects in PicoLisp, more flexible than
+hard-coded closures, because they can be created and manipulated independently
+from the code.
+
<p>As an example, consider a currying function:
<pre><code>
@@ -617,6 +619,25 @@ on. Lists can be made circular. And lists don't cause memory fragmentation.
<p><hr>
+<h2><a name="floats">How to do floating point arithmetics?</a></h2>
+
+<p>PicoLisp does not support real floating point numbers. You can do all kinds
+of floating point calculations by calling existing library functions via
+<code><a href="refN.html#native">native</a></code>, inline-C code, and/or by
+loading the "@lib/math.l" library.
+
+<p>But PicoLisp has something even (arguably) better: Scaled <a
+href="ref.html#num-io">fixpoint numbers</a>, with unlimited precision.
+
+<p>The reasons for this design decision are manifold. Floating point numbers
+smack of imperfection, they don't give "exact" results, have limited precision
+and range, and require an extra data type. For fixpoint support, the system must
+handle just integer arithmetics, I/O and string conversions. The rest is under
+programmer's control and responsibility (the essence of PicoLisp). Carefully
+scaled fixpoint calculations can do anything floating points can do.
+
+
+<p><hr>
<h2><a name="bind">What happens when I locally bind a symbol which has a function definition?</a></h2>
<p>That's not a good idea. The next time that function gets executed within the
diff --git a/doc/ref.html b/doc/ref.html
@@ -669,7 +669,8 @@ corresponding to the number of digits in <code><a
href="refS.html#*Scl">*Scl</a></code>.
<p>Formatted output of scaled fixed-point values can be done with the <code><a
-href="refF.html#format">format</a></code> function:
+href="refF.html#format">format</a></code> and <code><a
+href="refR.html#round">round</a></code> functions:
<pre><code>
: (format 1234567890 2)
diff --git a/doc/refF.html b/doc/refF.html
@@ -412,8 +412,9 @@ only be called immediately after <code><a href="refT.html#task">task</a></code>.
<code>sym|lst</code> to a number. In both cases, optionally a precision
<code>cnt</code>, a decimal-separator <code>sym1</code> and a
thousands-separator <code>sym2</code> can be supplied. Returns <code>NIL</code>
-if the conversion is unsuccessful. See also <code><a
-href="ref.html#num-io">Numbers</a></code>.
+if the conversion is unsuccessful. See also <a
+href="ref.html#num-io">Numbers</a> and <code><a
+href="refR.html#round">round</a></code>.
<pre><code>
: (format 123456789) # Integer conversion
diff --git a/doc/refR.html b/doc/refR.html
@@ -669,9 +669,8 @@ href="refF.html#flip">flip</a></code> .
<dt><a name="round"><code>(round 'num1 'num2) -> sym</code></a>
<dd>Formats a number <code>num1</code> with <code>num2</code> decimal places,
according to the current scale <code><a href="refS.html#*Scl">*Scl</a></code>.
-<code>num2</code> defaults to 3. See also <code><a
-href="refF.html#format">format</a></code> and <code><a
-href="ref.html#num-io">Numbers</a></code>.
+<code>num2</code> defaults to 3. See also <a href="ref.html#num-io">Numbers</a>
+and <code><a href="refF.html#format">format</a></code>.
<pre><code>
: (scl 4) # Set scale to 4