Live data from Hacker News

Lisp, Smalltalk, and the Power of Symmetry (2014)

insearchofsecrets.com

31–40 of 62 posts

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#31
post #16

Earlier quoted context omitted.

No, this is incorrect. The syntax and the AST must be isomorphic for a language to be homoiconic. It's not enough to expose the compiler/AST as a first-class library. Wikipedia has a nice entry on this. In short, "homoiconicity is where a program's source code is written as a basic data structure that the programming language knows how to access." [1]: https://en.wikipedia.org/wiki/Homoiconicity

According to that page, the term was introduced by the designer of something called TRAC, who used it to denote the idea that the program is stored in the memory in the same form in which the user enters it, which allows it to be inspected and changed. Nothing about ASTs.

What you said and what I said are in agreeement, so I'm not sure I follow. "Program stored in memory in the same form in which the user enters it" makes it isomorphic. Which was exactly the point I was trying to make in response to the parent comment.

You cannot simply expose the compiler/AST data structure and call your language homoiconic because the text the user enters and the resulting AST are not isomorphic which is a necessary precondition for homoiconicism.

I may be missing something in what you said though, so please do let me know.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#32
> What most of these languages seem to miss is that Smalltalk’s class system, like Lisp’s macro system, is a symptom of the power already available in the language, not its cause. If it didn’t already have it, it wouldn’t really be that hard to add it in yourself.

What most of these articles seem to miss is that that Java's designers were themselves expert Lispers and Smalltalkers, and they most certainly realized all that, and that Java's success is a consequence of them understanding exactly why not to repeat the same design. Design doesn't live in a vacuum. Design is shaping a product not just to fit some platonic ideal, but reality, with all its annoying constraints.

To understand why Lispers and Smalltalkers designed Java the way they did, I recommend watching James Gosling's talk, How The JVM Spec Came To Be[1], and the first 20 minutes or so of Brian Goetz's talk, Java: Past, Present, and Future[2].

[1]: https://www.infoq.com/presentations/gosling-jvm-lang-summit-...

[2]: https://www.youtube.com/watch?v=Dq2WQuWVrgQ

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#33
post #7

Earlier quoted context omitted.

There are alternatives that make static analysis look like the suboptimal approach. https://pointersgonewild.com/2015/09/24/basic-block-versioni...

Static analysis is not just about inferring types and hot paths for optimization. For that kind of stuff, a dynamic analysis is most of the time way better (lots of JIT compilers with speculative optimizations prove this point). There is another goal where static analysis shines: verification. If I'm writing a somewhat critical application, I want to make sure that it behaves according to my intent in all cases. For…

Right, but an important point here is "some highly dynamic language features make analysis really imprecise or really hard". Not all "late bindings" are born equal. JavaScript's dispatch is very different from Java's from a static analysis perspective, the latter being almost indistinguishable from pattern matching.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#34
post #28

> Smalltalk is powerful because all Smalltalk data are programs–all information is embodied by running, living objects. That's what Lisp systems do too. Program elements like classes, functions, methods, symbols, ... are first class objects. With something like CLOS you have a similar level of object-oriented meta-programming capabilities. Many Lisp systems offer additionally to execute Lisp data using a Lisp interpr…

> Smalltalk OTOH uses text as source code

That is not completely correct. It uses a mixture of text (strings) and objects. The class graph is composed of objects, but the method bodies are stored as objects and (optionally) strings.

To edit the class graph, it presents (parts of) it as text that you can edit (see ClassDescription>>definition in Squeak). E.g. to allow you to edit the Behavior class, it generates the following string and presents it in a text editor:

  Behavior subclass: #ClassDescription
	instanceVariableNames: 'instanceVariables organization'
	classVariableNames: 'TraitImpl'
	poolDictionaries: ''
	category: 'Kernel-Classes'
Notice that this is a Smalltalk statement that can be evaluated. If you edit this strings and accept it, it will evaluate the code which updates the objects describing the class. The primary representation is not textual, but an object graph.

A method is stored as byte code, and optionally as a string. The system will present you with a textual representation that you can edit, which is either the stored string or the decompiled byte code (which loses the original comments, indentation, and variable names). You can strip the textual representation of all methods to slim down the image (see SmalltalkImage>>abandonSources).

You can also file in/out a textual representation of classes and their methods. But that is not the primary representation of the code.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#35
post #33
post #7

Earlier quoted context omitted.

Static analysis is not just about inferring types and hot paths for optimization. For that kind of stuff, a dynamic analysis is most of the time way better (lots of JIT compilers with speculative optimizations prove this point). There is another goal where static analysis shines: verification. If I'm writing a somewhat critical application, I want to make sure that it behaves according to my intent in all cases. For…

Right, but an important point here is "some highly dynamic language features make analysis really imprecise or really hard". Not all "late bindings" are born equal. JavaScript's dispatch is very different from Java's from a static analysis perspective, the latter being almost indistinguishable from pattern matching.

I totally agree with that. When I mentioned dynamic dispatch, I had something like Scheme or JavaScript in my mind. Dynamic dispatch in those languages require a more subtle analysis to obtain precise results. I wish I could edit my parent comment to clarify my example.

To clarify my position (hence my parent comment's point) on this general matter, I'm OK with any language feature that is amenable to static analysis in a practical amount of time. This puts me closer to PL conservatives in Steve Yegge's spectrum.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#36
post #30

Earlier quoted context omitted.

I'm well aware, I've programmed in Pharo daily for a decade; I Smalltalk for a living. What I said it true practically speaking, you're getting into implementation details that don't make a practical difference. Lisp and Smalltalk are both image based systems, but Smalltalk'ers actually work on the running live image all of the time, they aren't ever booting from the sources file nor are they ever editing it manually…

> editing it manually You edit the source code via the IDE. Just like in Lisp systems. It's just that the IDE works differently. > Smalltalk'ers actually work on the running live image all of the time That's the dominant way to work in Lisp, too. My Lisp Machine even runs it as an OS. I use LispWorks for development on my Mac - the IDE is the running Lisp system. > it's not the normal worflow to work entirely in the…

> Actually that's the default mode. If you develop Lisp code with SLIME / GNU Emacs, it talks to a live Lisp system.

So do you dump your image at the end? My understanding is that most people work with files, and execute stuff occasionally while they're editing, then save the files. Next time, you reload from source - you don't start from an image with state. And if you fail to run something, your source and your repl become out of sync.

I've never seen anyone actually doing image-based development in a lisp, despite some lisps supporting it - even in livecoding (music), the standard is to edit a file, then occasionally send parts of the file to a repl.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#37
post #34
post #28

> Smalltalk is powerful because all Smalltalk data are programs–all information is embodied by running, living objects. That's what Lisp systems do too. Program elements like classes, functions, methods, symbols, ... are first class objects. With something like CLOS you have a similar level of object-oriented meta-programming capabilities. Many Lisp systems offer additionally to execute Lisp data using a Lisp interpr…

> Smalltalk OTOH uses text as source code That is not completely correct. It uses a mixture of text (strings) and objects. The class graph is composed of objects, but the method bodies are stored as objects and (optionally) strings. To edit the class graph, it presents (parts of) it as text that you can edit (see ClassDescription>>definition in Squeak). E.g. to allow you to edit the Behavior class, it generates the f…

> That is not completely correct. It uses a mixture of text (strings) and objects. The class graph is composed of objects, but the method bodies are stored as objects and (optionally) strings.

All changes to the class graph are also stored as changes in text. Every class has a textual representation. You can load an earlier image and replay this. This is basically like loading Lisp code into a Lisp image.

> it will evaluate the code which updates the objects describing the class.

This is like Lisp. The Lisp code manipulates the runtime class graph.

> But that is not the primary representation of the code.

The primary representation is text. That's what the IDE presents you when you edit the method.

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#38
post #32

> What most of these languages seem to miss is that Smalltalk’s class system, like Lisp’s macro system, is a symptom of the power already available in the language, not its cause. If it didn’t already have it, it wouldn’t really be that hard to add it in yourself. What most of these articles seem to miss is that that Java's designers were themselves expert Lispers and Smalltalkers, and they most certainly realized al…

Gosling was an expert Lisper? I only heard that he developed a strange/tiny Lisp variant called Mocklisp as extension language for his Emacs editor.

> Design doesn't live in a vacuum.

Java was designed as a modernized/slim replacement for C++ when developing set-top boxes and PDAs. What SUN took from Lisp and Smalltalk in some limited form was the runtime: managed runtime with GC, code loading, typed objects and a virtual machine. VMs were thought as an advantage on machines with little memory, because of compact code representations. Various Lisps and also Smalltalk had that. But that was mostly it. The language level wasn't influenced by Lisp at all: no Lisp syntax, no Evaluator, no lambdas, no code-as-data, no macros, no support for functional programming, ...

https://en.wikipedia.org/wiki/Oak_(programming_language)

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#39
post #30

Earlier quoted context omitted.

> editing it manually You edit the source code via the IDE. Just like in Lisp systems. It's just that the IDE works differently. > Smalltalk'ers actually work on the running live image all of the time That's the dominant way to work in Lisp, too. My Lisp Machine even runs it as an OS. I use LispWorks for development on my Mac - the IDE is the running Lisp system. > it's not the normal worflow to work entirely in the…

> Actually that's the default mode. If you develop Lisp code with SLIME / GNU Emacs, it talks to a live Lisp system. So do you dump your image at the end? My understanding is that most people work with files, and execute stuff occasionally while they're editing, then save the files. Next time, you reload from source - you don't start from an image with state. And if you fail to run something, your source and your rep…

> So do you dump your image at the end?

For example if you deliver an application, that's what one usually does.

> My understanding is that most people work with files, and execute stuff occasionally while they're editing, then save the files

One works with files, but together with the running Lisp system. I would work with a mix of compiled (fast load) and source files. Let's say you work on a new version of your graphics editor. You start the Lisp image and load the current version into it - mostly from fasl files. Some years ago people would more often have started a dumped image, because it took some time to load the fasl files. Even today, if the program is really large, you might want to use a dumped image of some version of it.

But independent of how you reach there, you start Lisp and then recreate a state of the working image (either from a dumped image or from loading files), where you continue to work from.

The image then will have a the development information, debug information, application state, compiler info, ...

In Smalltalk you would typically load a saved image more often. In Lisp you would recreate the state from a base image and then fast-load the stuff you need.

> And if you fail to run something, your source and your repl become out of sync.

Yes that happens and current Lisp systems actually don't have a goal to keep that in sync. You have to check manually that the source or the compiled system actually loads and runs - means recreate the correct state.

> I've never seen anyone actually doing image-based development in a lisp, despite some lisps supporting it - even in livecoding (music), the standard is to edit a file, then occasionally send parts of the file to a repl.

In the sense of Smalltalk (image + managed source code) there are only few people doing that in Lisp - nowadays. That debate (managed code images vs. a mixed file/image model) was lost in the early 80s with some later attempts to create a manage source model with code in data bases.

In the sense of saving images as pre-loaded code, that's seen and especially for application delivery. The LispWorks IDE I'm using has a lot of stuff pre-loaded (with some on-demand loading) as a single image. If I develop something, it is loaded into it and the application then is a newly dumped image. LispWorks also supports some exotic stuff like regularly saved sessions. It also keeps track which sessions have been saved based on which other sessions.

http://www.lispworks.com/documentation/lw70/IDE-M/html/ide-m...

Re: Lisp, Smalltalk, and the Power of Symmetry (2014)

#40
The thing about both Lisp and Smalltalk that keeps making me feel alienated is that their power seems much weaker beyond their kingdom. The outside world does not have an object browser, nor is it made of s-expressions.

Tcl occupies a very nice place in this regard: its homoiconicity and symmetry (and late binding) come from text. The outside world, to a very close approximation, is also made of text. Subprocesses, sockets, FFI, files and user interaction just feel more native - in the image-oriented languages, I always find myself fighting the ambassador who imperfectly represents these things in forms the kingdom understands.

Just a feeling. They're all wonderful languages, and this article speaks well to some of the "why".

Post reply on HN