A revolutionary OS/Programming Idea

Alaric B Snell alaric@alaric-snell.com
Sat Oct 4 15:57:02 2003


John Newman wrote:

> PJB, you have not sufficiently explained why anything
> that lisp can do, cannot be expressed graphically. 
> Perhaps if I knew lisp, I could respond.  All I can
> say is, any language is interpreted or compile
> hierarchically, so the lisp language should be
> implementable in the scheme I am talking about.  There
> should be no reason that one cannot create an analog
> of how one interfaces with the lisp language in a
> graphical way.

He's not saying that what you do in LISP can't be done graphically; just 
that the graphical editors for LISP never really made it in the big time.

Here's a quick rundown of LISP.

LISP systems have a data model. C++'s data model is about ints, chars, 
floats, structs, unions, pointers, and objects - so you know what I mean 
by a data model, right?

LISP's data model is dynamically typed, which means that you don't 
really have typed variables, just typed values. In C++, you declare a 
variable as an 'int', and it can only hold integers. In Lisp, you 
declare a variable, and it can hold anything.

The basic types are:

  - Numbers (split into ints and floats and whatnot), written as: 2
  - Strings, written as: "string"
  - Symbols (which are like strings, but are written without quotes, and 
are used as short names for things), written as: foo
  - Lists, written as: (item item item)

The lists are, in fact, linked lists; each node in the chain has two 
pointers, called 'car' and 'cdr' for historical reasons. car points to 
the contents of that entry in the list, cdr points to the next entry or 
is null if this is the last one.

So you might have a list of people's names:

("Alaric" "John" "Pascal")

Or a list of information about a person, with a convention that the 
first element is the first name etc:

("Alaric" "Snell" "alaric@alaric-snell.com")

Or you could more flexible represent that as a list of lists, where each 
list has two elements - a symbol, which is the name of the 'property', 
and the value of it, like so:

((first-name "Alaric")
  (last-name "Snell")
  (email "alaric@alaric-snell.com"))

That's a bit like a struct in C.

Anyway, the neat thing about LISP - that will probably please you - is 
that source code is actually represented in the data model, as the 
direct AST. The rules for interpreting a simple LISP dialect would be:

  - To interpret a number or string, return that number or string
  - To interpret a symbol, look up the variable that the symbol names 
and returns its value
  - To interpret a list, take the first element of the list. If it's a 
keyword like 'if' or whatnot, then handle that according to the rules 
below, otherwise interpret every element of the list, throw up an error 
if the result of the first element isn't a function object, and 
otherwise call the function with the rest of the list as parameters.

     - To handle an 'if': Check the 'if' has three parameters. Interpret 
the first one. If the result is boolean true, interpret the second one 
and return the result, otherwise interpret the third one and return THAT.

     - To handle a 'define': Check the 'define' has two parameters. The 
first one must be a symbol. Interpret the second one, and create a new 
variable with the first parameter as its name, and the result of the 
interpretation as the second one.

    - To handle a 'defun': Check we have two parameters again. The first 
one must be a list of symbols. The first element of that list is the 
name of the function to be defined, and the other elements are the names 
of its parameters. The second parameter is the code for the function 
body. Compile that code and store it in the list of functions with the 
given name.

    ...etc

I've glossed over many issues, but you get the idea. According to the 
above rules, you could write programs like:

(print (+ 1 2))

Evaluating that consists of noticing that it's a list. The symbol 
'print' is not a special keyword, so the list of functions is consulted 
and the 'print' function found. Now the parameters are interpreted in 
turn - there's only one parameter, and it's again a list, and + is not a 
keyword so the function called + is found, and the paramters 
interpreted. 1 and 2 are both numbers and the results of interpretation 
are '1' and '2' respectively, according to the rules, so the + function 
is called on the integers 1 and 2, returning the integer 3.

So the print function is called on the integer 3.

BUT the same program could be treated as data; another program could 
examine it just like the interpreter does. Bear in mind that the program 
only looks like "(print (+ 1 2))" when displayed to a human - in memory 
or on disk it's a data structure, pointers and integers and symbols.

Only the I/O system actually knows about the round brackets and so on.

It's trivial to write your own editor that is purely graphical, too...

> Again, pjb, the problem I am adressing is that I have
> no idea what any of that means.  But about the problem
> you raise with this source, again, I think a graphical
> implementation of sql or lisp should be able to handle
> sql or lisp data objects, respectively, whether
> graphically represented or not.

The neat thing about LISP is that your graphical tree editor needn't 
actually know about LISP per se - just about lists, numbers, symbols, 
and strings. The language LISP builds on that by assigning *meaning* to 
things like "(if foo bar (baz))" - which you now know means "If the 
variable foo is true, return the value of the variable bar, otherwise 
return the result of calling the function baz (with no arguments) :-)

The LISP tree data model thing is actually known as 's-exprs'. (if foo 
bar (baz)) is an s-expr (Symbolic Expression) that happens to make sense 
as LISP code.

The same nice tree editor is just as handy for editing data files, 
configuration files, and source code files ;-)

I think that's important for your idea...

ABS