> From: Jon Harrop <use...@[EMAIL PROTECTED]
>
> Algebraic datatypes are found in MLs (like OCaml and F#) and
> Haskell. They are composed of sum and product types:
> type t =
> | A of int * string
> | B of bool * float * char
> | C
> The choice A|B|C is a sum type: a value is any one of those
constructors.
> The arguments "bool * float * char" are a product type: a value must
> contain all of those fields.
Ah, the original Boolean trick of overloading addition and
multiplication symbols (plus and asterisk) to actually mean union
and intersection instead.
Common Lisp has the same thing, except without overloading.
Referring to CLtL (Steele), section 4.4 (page 44) "Type Specifiers
That Combine".
(and type1 type2 ...) = intersection
(or type1 type2 ...) = union
(Too lazy to find the same material in the HyperSpec today.)
> Mathematica lacks static type checking
So there's no way to assert a fact about some data value somewhere
in your code and have the compiler warn you if that fact can't be
guaranteed based on what it knew earlier in the same code?
> Actually, I can't think of any other languages that sup****t
> recursive anonymous functions anyway: none of Lisp, Scheme, SML,
> OCaml, F# and Haskell do AFAIK.
OK, I'm taking that as a challenge!! Is there any way in Common
Lisp that a recursive anonymous function can be defined. I'm pretty
sure it's possible to use an uninterned symbol as a name of a
function, which in effect makes it anonymous. I'll use that as my
fallback if I can't do it *right* where there's no symbol
whatsoever used as a local "name" of a function. If Lisp were
truly interpreted, with the CONS structure kept for all time,
then it'd be trivial: Write an anonymous function that calls another
function,
(let ((tmp (function (lambda (x) ... (bar ...) ...)))
then RPLACA the name of that other function with the actual lambda
expression from the main definition. Here's a crude SETQ version,
writing the lambda expression directly:
(setq anon-pre-copy-tree
'(lambda (tree)
(if (atom tree) tree
(cons (bar (car tree)) (bar (cdr tree))))))
(setq *print-circle* t)
(setq anon-recurse-copy-tree
(nsubst anon-pre-copy-tree 'bar anon-pre-copy-tree))
#1=(LAMBDA (TREE)
(IF (ATOM TREE) TREE (CONS (#1# (CAR TREE)) (#1# (CDR TREE)))))
(setq foo (list 1 2 3 (list 4 5) 6))
(eval (list anon-recurse-copy-tree 'foo))
Illegal instruction (core dumped)
2304 -rw------- 1 rem user 2342912 Feb 12 09:36 lisp.core
That was in CMU Common Lisp 18b
If anybody is curious, I moved it to here tem****arily:
<http://www.rawbw.com/~rem/NewPub/lisp.core>
Is there a version of Common Lisp where that would work??
Hmm, maybe I should write my own version of EVAL that works only
the old-fa****oned way (by dynamic/special bindings, no lexical
stuff, and no JIT complilation, just recurse directly within EVAL
while traversing the tree of code to be executed) to avoid the bug
in CMUCL's version of EVAL?
> Callcc is a lot more like forking than threads.
I've been under the impression that forking was a special case of
multiple threads, where a single thread spawns two continuation
threads, taking opposite paths from some branch point, and the
original thread then waits for both to complete before combining
their results and proceeding as a single thread.
> Arrays are Mathematica's primitive data type and it calls them
> (confusingly) "List"s.
Well they *are* lists i.e. vectors, they just aren't linked lists,
they're contiguous lists, which have some advantages and some
disadvantages compared with linked lists. Can elements of
Mathematica's contiguous lists be contiguous lists (arrays)
themselves?
> But Mathematica's equivalent of cons cells are arrays of objects,
> so they can store an arbitrary number of elements contiguously.
> Speaking of which, why doesn't Lisp do that?
No, you're wrong. Mathematica doesn't have an exact equivalent of
CONS cells, i.e. ordered pairs of a distinct type different from
any multi-pointer object. Lisp has the equivalent of Mathematica's
"lists", namely one-dimensional general arrays. Lisp has *both*
kinds of objects, one-dimensional general arrays which can hold any
number of pointers, and CONS cells which are specialized to have
exactly two pointers and to be more efficient than a two-element
general array. CONS cells are *not* a sub-type of general arrays,
whereas a list of two elements in Mathematica, as you cite, *is* a
sub-type of multi-element lists.
Now it would be possible in Lisp to use two-element general arrays
as if CONS cells: Have a new version of READ that generated them
where CONS cells would normally be generated, a new version of
PRINT that printed as if they were CONS cells, and a new version of
EVAL that traversed them just as the regular EVAL traversed regular
CONS cells. That would be a cute hack, even if of no practical
value.


|