Hacker News new | ask | show | jobs
by lispm 3328 days ago
> 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 interpreter and Lisp has a simple data representation for Lisp programs: Lisp data.

Smalltalk OTOH uses text as source code and usually a compiler to byte-code.

> because Lisp source code is expressed in the same form as running Lisp code

Only if you use a Lisp interpreter. Otherwise the running Lisp code might be machine code or some byte code.

> Smalltalk goes one further than Lisp: it’s not that Smalltalk’s source code has no syntax so much as Smalltalk has no source code.

That's a misconception. Smalltalk has source code. As text. It's just typically managed by the integrated development environment.

It's actually Lisp which goes further than Smalltalk, because Lisp has source as data and can use that in Lisp interpreters directly for execution.

1 comments

> 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.

> 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.

For traditional smalltalk systems (ie. anything except GNU Smalltalk), that textual representation is generated by serializing the object graph. And the traditional text format is not exactly designed to be human editable, also it does not describe classes as self-contained concept, it is stream of expressions interspersed with strings that get magically processed by something that was setup by previous expressions (eg. Behavior>>#methodsFor: switches the deserializer state into this second mode).

The problem with Smalltalk is that you lose all it's power when you stop using the IDE. The idea that Smalltalk's runtime metaobject system is somehow equivalent to Lisp's macros is completely wrong, but the system as a whole is powerful enough to make it look like that it does not need macros, because:

1) the IDE automates many things away (but often by doing textual transformations on the source code) 2) the general ST programming culture builds heavily on monkey patching (which is also usually somehow automated by the IDE)

Even with this, ST is also where the whole idea of design patterns started, with half of the patterns being workarounds around insufficiently expressive language (ie. no macros and multiple different "callable" types/syntax categories).

> 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.

I forgot about that. The changes files is more like a log file, though (e.g. if you change a class multiple times, the changes file will have multiple versions of that class in it). It is generated as a side effect of manipulating the object graph in the image. The normal development is not to edit the changes file and then load it (which is how I usually edit Lisp code).

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

Agree.

> > 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.

My use of 'represention' is wrong here, I should have stuck with source.

For the body of methods I agree with you. For the class graph, the source is the object graph, and the IDE has multiple ways to present it to you. The textual representation is but one representation (generated from the object graph). You can e.g. also display the class hierarchy as a hierarchical list. To manipulate the source, aside from editing text, you can also use commands to rename a class, or delete instance variables in a list view (if I remember correctly in Cincom). And yes, you have similar things in Slime, but then your image gets out of sync with the textual source.

I don't think there is a clear line between development in Lisps and Smalltalks, though. My experience with (Cincom) Smalltalk was that it was much more image based and not file based. That had the drawback that e.g. editors, diff tools and source control were reimplemented in Smalltalk (often slow and buggy). An advantage is that e.g. debugging is more tightly integrated: it is trivial to implement an undefined method inside the debugger and continue, in SLDB adding an undefined method is slightly more clumsy (e.g. the debugger wouldn't know which file to put it in). My experience with e.g. SBCL, LispWorks is that it is much more text/file based. I start from text files and evaluated (parts of) them. Every once and a while I restart the Lisp image and reload from scratch. But you can find Smalltalks that are text based (e.g. GNU Smalltalk) and Lisps that are more image based (e.g. Symbolics).