Live data from Hacker News

They Called It LISP for a Reason: List Processing (2005)

gigamonkeys.com

121–125 of 125 posts

Re: They Called It LISP for a Reason: List Processing (2005)

#121

Earlier quoted context omitted.

> Pointers to TWO pointers (first pointer is named car, and the 2nd pointer is named cdr). This is not true; only cdr is a pointer to a pointer. car is a pointer to a value. For example, if x is (1 2), then (car x) is a pointer to the value 1, while (cdr x) is a pointer to the list (2), so only the latter is "to a pointer". > convert your C code into a vector or a hash-map. nit: C has neither vectors nor hash-maps, n…

(car [(This example) of a list]) == (This example), which is a pointer.

that's an example, sure, but the original claim was that "lisp lists have two pointers to pointers", which certainly is not always true.

Re: They Called It LISP for a Reason: List Processing (2005)

#122

Earlier quoted context omitted.

> only cdr is a pointer to a pointer. This isn't really true either. Either half of a cons could contain a pointer or a direct value. Lisp makes the decision about pointers based on whether the value you're trying to store is small enough to fit there directly or not. And crucially, Lisp can tell the difference between a pointer and a value at runtime which means it will always do the right thing with whatever it fin…

> Nothing in Lisp requires pointers in either half of a cons cell. You are definitely right about that, but the initial claim was made about "Lisp list", for which cdr is certainly a pointer. I would expect that when we refer to "Lisp lists", we certainly don't include things like (cons 1 2)

Except at the end of the list when the cdr contains nil, which is not a pointer but a special value.

BTW

  (listp (cons 1 2)) =>  true
so (cons 1 2) is indeed a list; it's just not a proper list.

Re: They Called It LISP for a Reason: List Processing (2005)

#123

Earlier quoted context omitted.

Forth is also homoiconic (arguably more so than lisp) and it can be thought of as being purely vectors.

Forth's homoiconicity seems to be disputed: https://wiki.c2.com/?HomoiconicityClassification

You could see forth as just netstrings recursively. You evaluate the outermost netstring by unquoting and then doing a forth over the netstrings it contains.

Re: They Called It LISP for a Reason: List Processing (2005)

#124
post #112

Earlier quoted context omitted.

REPL is a Read Eval Print Loop, which is a way to interact with a Lisp runtime. This is independent on how EVAL is implemented. A bunch of Lisp systems implement EVAL with an incremental compiler. An interpreter is a Lisp feature where code gets interpreted from source at runtime. Some implementations have one, some don't, some only have an interpreter, some only have a compiler, some have several compilers, some hav…

Thank you for taking the time to explain. I now get it. SBCL includes the compiler in each binary and this is called incremental compiling. That explains the expressiveness. It is kind of like a JIT when needed. Compile everything you can AoT, leave dynamic parts to runtime compilation. It makes perfect sense. Thanks . I guess the difference is that in an interpreter you don't go down to assembly, you parse and run s…

Basically all SBCL code is pre-compiled. There is mostly no runtime compilation happening. Only if the user/developer actually wants it. For example one can connect to a running SBCL and have one or more networked REPLs into it.

Re: They Called It LISP for a Reason: List Processing (2005)

#125
post #109

Earlier quoted context omitted.

> You are dissasembling inside the interpreter. What you see is no interpreter. It's an interactive interface, reading code, compiling it, executing it, printing the result. There is by default no interpreter. Everything is compiled in SBCL. A Lisp system typically includes an on-board compiler and/or interpreter.

REPL is the interpreter isn't it? When you type the code into sbcl you are using the REPL which is the interpreter. Try running sbcl without the REPL and produce an executable binary file. Maybe the binary representation changes into something with dynamic dispatch?

The REPL (traditionally "listener") is a kind of interpreter, because it reads textual input, and hands it off for processing. There is some definition of "interpreter" which this meets.

lispm's point is that it's not a/the Lisp interpreter. An Lisp interpreter and Lisp listener are different things. The listener is more like a "command interpreter".

You can write a very poorly featured listener yourself, by literally following the REPL acronym: (loop (print (eval (read)))). You have not written a Lisp interpreter in four operators; the read and eval functions are doing that. The following is a copy and paste from an actual session:

  [1]> (loop (print (eval (read))))
  (+ 2 2)

  4 

  (let ((x 9))
    (* x x))

  81 

Some other languages are the same way. When Bash runs a script, it's not going through the interactive command line processor that is used for interactive input, which has completion, recall and editing. That command line processor isn't what parses and understands Bash syntax.

We can write a REPL at the Bash prompt also. We can write a loop which reads a line of input, evaluates it as shell syntax, and then repeats that ad infinitum until we hit Ctrl-C:

  $ while true ; do read -r command ; eval "$command" ; done
  echo foo
  foo

  for x in 1 2 3; do printf "[%s]\n" $x; done
  [1]
  [2]
  [3]

  uname -a
  Linux sun-go 4.15.0-167-generic #175-Ubuntu SMP Wed Jan 5 01:55:52 UTC 2022 i686 i686 i686 GNU/Linux
  ^C
The shell language interpreter is in the eval command; we have not written a shell! The "for x in 1 2 3" syntax isn't coming from our "interpreter" loop.

Lisp's eval isn't necessarily an interpreter. A Lisp implementation which has only a compiler will implement eval by compiling, like this:

  ;; insert expression into lambda expression.
  ;; compile lambda expression, resulting in a compiled function object
  ;; call function object, with no arguments.
  (defun eval (expr)
    (funcall (compile `(lambda () ,expr))))
You can write this function in any Common Lisp (just don't call it cl:eval). Thereby you obtain a compiling eval, even if the standard cl:eval is interpretive.
Post reply on HN