Hi , Aurel , Mike .. well, even the desktop is not crash-proof (some recent experience) ...
Charles, it's not strictly needed - the "list" mixes all possible types and may be nested with other lists -- the type is discovered by its syntax ,
p.e. x is an integer / x.y is a float / x/y a fraction / x+iy a complex number / "xyzab" a string / \xyz a char/byte / nil is the nothing / (whatever ) is a list / 'x a symbol ... etc ,
.. lists an atoms of any type can be nested , to visualize nesting, maybe an example is thinking about describing the structure of a building - you open a door and there's a room , in that room there is a door , or maybe two or more doors etc.. the lists are a handy system to set-up bin trees without a pre-defined "branching" structure.
As for the structures, it is best to make the code readable by simulating some structure like syntax (imo) -- Lisp becomes very easy unreadable.
Let's say we're going to work with complex numbers :
(define (C# x y) (list x y)) --- seems very idiotic, but we know now that (C# . . ) represents a complex number.
Now we can build.
(define (C+ a b &rest) (list (+ (a 0) (b 0)) (+ (a 1) (b 1)) &rest ) )
now we can do something as (C+ (C# 4 3) (C# 1 3))
or better readable : (set 'z (C# x y)) and then (C+ z z) etc..
-- that's not special, but - a moment we get the idea to add the polar coordinates to the system (we need the Euler/De Movre notation).
we can just expand to the list -> ( x y r theta) , the nice thing is that this new form is still valuable for our previous defined C+.
to test if it is an "extended" complex number :
(define (demoivre? Z) (= (length Z) 4))
and if needed (define (expand-to-polar Z) (when (not (demoivre? z)) (make-demoivre Z)))
Summarizing : languages as Basic are much better readable ;-)
------------------------------- math stuff (probably boring)
A few weeks ago , I tried to set up an analytic formula for Fibonacci numbers , (I let the Lisp do it) it went :
the most important first , as the arguments are two numbers :
(a b) -> (b a+b)
(define (Fibnext n) (list (n 1) (+ (n 0) (n 1))))
and then the iterations (define unit (list 1 1)) -- the starting pair. (doing all this by pairs is much more clearer // pair->pair is much more logical than pair->number )
the code calculated the increase / iteration (it rapidly goes to (1+sqrt(5))/2 (the golden ratio btw)
then it calculated the initial constant in the formula , and checked the error against exact calculated values.
the obtained formula A+ C*pow((1+sqrt(5)/2),n) is "almost" exact.
to be honest - the Frenchman Bonnet calculated this exact around 1850/ and published it , but he needed 3 powers to do so (what is the minimum to do it exact) -- and De Moivre found this +- a century before him, but found it not worth publishing ;-)
-------------------------------
Haskell introduced again the assignment declarations btw .. it's sometimes somewhat difficult in Lisp -- NewLisp has separate commands for floats and ints + - * / and add sub mul div - and picoLisp works with unlimited bignumbers and a scaling factor for the floating point , something as 132 scale 2 = 1.32 , Racket uses exact->inexact combined with broken numbers .. 1/7 is an exact number, writing it decimal will take till the end of times , so it has to be converted into an inexact number ... (and it also gives the possibility to works with streams like Haskell does (in-range) , (in-naturals) etc.. the lists are not pre-built but lazy calculated ...
summarizing : in a list everything can be mixed , even lists ( where ... recursive ) ....
best Rob