The Mystery of Moose

Thank you for your very thorough answers!

That makes a lot of sense actually. So Skia is just being the “framebuffer” and pretty much is an OS-level I/O interface, and nothing from GT is being written in Rust. But wouldn’t it maybe be nice for a Smalltalk VM to use Skia so that things other than GT could use it? Is there some kind of rift between the Pharo and GT teams, or would putting Skia in Pharo break all of Pharo and so it’s better to try it out in a completely new project?

With today’s standard Smalltalk workflows, that never happens. Source code and notes are kept in Git repositories. Images are usually short-lived. I use mine for a few days at most.

I’ve heard this text-file-based workflow mentioned before. It bugs me quite a lot because it seems extremely “un-Smalltalky” (it feels like we’ve moved back to the “batch run, discard the flaky RAM environment after the run finishes” philosophy), but on the other hand it also feels like a survival adaptation to the brute pragmatics problem of how to do change management and backup in a world where Smalltalk is neither the OS nor the network. It doesn’t really feel like the solution Alan Kay hoped for, but at least it works and is robust.

I find myself doing much the same thing in Node.js as my current “personal malleable computing platform”. I use Node inside Termux on my Android phone and Node in a command window on a Windows or Linux desktop. Then I put my main scripts as .js module files, and restart Node every time I change them, but also drive Node mostly interactively from the REPL. It’s not exactly what I want to do, but it’s the only environment so far I’ve found that can run identical environments on desktop and phone, so I have it with me, and I can code live database queries as Javascript functions and edit my data in a text editor. If necessary I can edit the code too, but I often find myself interactively prototyping functions just in the REPL. And then I can copy data and code just as files in and out of the phone.

Node is surprisingly good as a REPL. Command-line history that saves between sessions, and tab completion, means that even on a phone it’s possible to perform steps of data loading and parsing without too many keystrokes. Copy-paste for patching small functions in flight isn’t as good as a proper browser/inspector, but works better than one would expect.

It would be nice to have more structure than text files, but there seems to be a fundamental tension between “strictly classful/typeful objectness” and “cross-platform transportability”. The tighter we lock down types/objects, the more tightly bound they become to code, and that means we have to either export Turing-complete, system-dependent, hard to analyze code with them (a cybersecurity risk, these days), or we have to dissolve their encapsulation and identity at the network or disk boundary and export them as some kind of plain, examinable data record. And then parse and “compile” them fresh as they come in from the network or disk.

It always fascinates me that Smalltalk was a product of the ARPA-IPTO culture and heavily inspired by the message-passing Internet. And yet! The Internet itself did not become an object-based network. I wonder if there’s an alternate history where ARPA went completely down the Smalltalk-y route, such that instead of a file-based Web we got a completely distributed object-based network? What might such a thing have looked like?

For most of the 1990s it felt like such a thing was absolutely inevitable, until it suddenly wasn’t. I can’t quite put my finger on when the “wasn’t” hit, but it was probably between the appearance of Google and Linux (2000) and their “text is the best interface” mindset, and the dominance of iPhone and app stores (circa 2010). I think it was mid-2000s when I first noticed the “object orientation is bad, actually” backlash.

1 Like

Smalltalk as implemented now, is not encapsulating any behavior or data. This is why it is not useful.
What Alan Kay wanted doesn’t exist at the moment.

When an object is part of a bigger object, you shouldn’t be able to reference it from outside of that object.

An object should be able to be
A. inside an object
B. outside of an object.
C. Be able to move between A or B.

It should not be both inside and outside.

In my experience with Squeak and Cuis, the way it works is that you work with Packages that you load and save. The backend stuff like files is handled transparently.

1 Like

Priorities between Pharo and GT teams differ indeed, but the long-term plan for Pharo is to use the same Smalltalk-level graphics layer (called “Bloc”) as GT. Skia is considered an implementation detail by everyone, and Pharo is likely to support different rendering backends for Bloc at some time.

It is! Smalltalk made the transition from “the basic software layer of a computer” to “a programmable universe embedded in a larger computing system”, which implied adaptation to the universal data store of today’s computers: the file system. Which is pragmatic, and probably ensured its survival, but it’s certainly not what Alan Kay envisaged.

That’s my conclusion as well. The “everything is an object” view of Smalltalk is nice while you are in Smalltalk, but there are things that Smalltalk is not good at, so I need other universes, and then I need to exchange data, and then it’s back to the file system. Which is something I have accepted by now. I am not trying to fight or escape any more.

The dream is still alive, maybe we will end up seeing something like that in the future of the Web.

Not sure that is actually possible. Consider an OO network stack. There’s a “TCP/IP object”, which contains “packet” objects. But any client of TCP/IO also has to refer to packets.

1 Like

You simply pass the packet to the outside world, and never reference it from TCP/IP again. This is called linearity.

Right, you can do that with instances, but you still have an implicit reference to the class definition, which remains inside. And as long as it is immutable, I don’t see much of a problem with that.

2 Likes

Practically very little code is written this way.

Hmm. So if I had say a strongly typed Collection and I ask for an object at a given index and get an object reference… would maybe every message sent to that object reference be silently proxied through its containing Collection to verify that, eg, mutations don’t break the typing contract? That seems like it would be quite helpful. I like the idea of some objects having a permanent home and/or controller.

There seem to be a number of related concerns in object systems that are currently missing pieces. Or maybe just one missing piece that keeps cropping up. Mostly to do with virtual machines, packages, namespaces, backups, transactions, rollback and undo. The idea that even the concept of “object reference” should be able to be virtualised and proxied though a controller (and that controller can change without clients holding the object reference needing to know). This doesn’t currently seem easy or cheap to do, but it seems like it could be.

Ie something I’d like to do is be able to “Declare a new session/transaction”, then “Enter” that session somehow (put some kind of interaction focus into or out of that session), then while my focus is in that session, not only all objects I create but all messages sent and changes made to and by other objects that in any way interact with my interaction focus, even distant remote effects are encapsulated entirely within that session. It’s my own private little sub-image - potentially even my own private view of the entire Internet (if the external systems I’m sending messages to can be simulated). Then, I can close off the session and have it available as an object that could be exported between systems and somehow “mounted” in either read-only or read-write modes, or even examined or created entirely via automation.

Naturally, sessions would have to be objects and they would have to be able to be stacked up in chains of “inheritance” to arbitrary depth.

Is “capturing all messages sent even by distant objects, if they are caused by my messages” doable, and with reasonable performance? And does the concept that a session must be examinable violate the strict ideology of object encapsulation? I don’t know, but this setup seems to be something we need because we keep rebuilding it in multiple subtly incompatible ways in multiple different OSes and architectures.

1 Like

Meanwhile, I’m still reading through the Cuis Book. On page 76 of 222:

The Collections- class categories are the most prolific, there are 7 of them
gathering 46 classes.

46 collection classes. And this is the “minimal” variant of Squeak? I understand it’s only one person’s project so it’s not necessarily representative, but still.

I feel like such a massive explosion of classes is probably not a great thing for user-friendliness. How can even a professional programmer possibly choose which collection to use? Let alone a user who’s not trained in programming?

“Too much complexity and too much brittleness / big design up front in the class ontology” is also the strong impression that I always got when reading 1990s Gang of Four / Design Patterns material. Once a class is put into an inheritance tree, it feels very hard to refactor this kind of decision and to simplify it later, so class sprawl was the main impression people had of the Java and XML years. The rise of JSON and “one collection data type should be enough for anyone, maybe two at a pinch” was a rebellion against this and it felt very refreshing at the time. It still feels refreshing being able to mock up ideas in one universal “dictionary/array” type without having to freeze the data architecture into a class.

I also don’t understand how a principled focus on messaging passing and polymorphism led to class-ontology sprawl in Smalltalks. It’s the exact opposite of what I expected to happen. In strictly-typed compiled Java, sure, I can understand it. But shouldn’t dynamic late-bound polymorphism and untyped variable slots have led to fewer classes?

Alan Kay is on record as saying that he doesn’t like inheritance, thinks Morphic used it too much, and that it’s not the important part of his concept of OOP. I guess Squeak, Pharo and Cuis must not yet have taken Kay’s critique on board, since inheritance is still very central to their design.

Would it be possible to create a Smalltalk-like language with a very restricted set of classes and no inheritance, which use some kind of composition mechanism instead?

2 Likes

Collection classes are very central to Smalltalk, because they do double duty as control structures, which the language does not have. The collection classes and their numerous methods make up for the minimalism in the language. And they correspond to half of some other language’s standard library.

Alan Kay saw Smalltalk as a stepping stone, as a system just good enough to build a better next-generation system. If everyone had listened to him, Smalltalk would be a curiosity in history museums by now. And perhaps replaced by nothing, as I none of Alan Kay’s later experiments made it beyond the status of a research prototype.

The people working on Smalltalk today thus have goals and priorities very different from Alan Kay’s. It’s not fair to judge their accomplishments by what Alan Kay would have preferred.

The only way to figure that out is by trying. Prototypes (Self, JavaScript) were one idea in this direction. Maybe there are others.

1 Like

Squeak kinda sorta has something that could be considered the beginnings of that in its Projects facility. Inside a project all changes go to a separate changelog. It might be a good start.

This is one of the reasons I’ve been looking at Smalltalk-76 (and 78). It’s a much smaller and very neat system.

1 Like

Hmm. So if I had say a strongly typed Collection and I ask for an object at a given index and get an object reference… would maybe every message sent to that object reference be silently proxied through its containing Collection to verify that, eg, mutations don’t break the typing contract? That seems like it would be quite helpful. I like the idea of some objects having a permanent home and/or controller.

In smalltalk you do not have types but methods play a similar role. You cannot interact with an object unless you use the methods it has. By proxying the msgs through the methods of the container, you guarantee that a contract will be upheld as long as the methods are correct.

Let us say that you have an object that contains a set of points that are part of a circle. You should move points only through the container, because the method guarantees that the move will place the point in the circle.

If you dont, then the object cannot guarantee anything about its state.

In Temporal Logic of Action TLA+ , similarly there are no types, but we model the dynamical system that occurs due to certain actions and initial conditions.

In TLA, the system is a closed system, meaning that no random action is possible to happen.
This is the essence of encapsulation simply by computational means, without types. In essence we define a dynamical system.

Refinement in TLA is a very important concept, and could possibly be a replacement of classes.

1 Like

Re graphics stack, https://medium.com/feenk/one-rendering-tree-918eae49bcff explains some motivation for their choices.

2 Likes

The single rendering tree is actually something whose advantages are not so immediately obvious. It takes some time to realize what you can do with that. For example (a real one): draw a graph whose nodes are text editors. Another one (real as well, and part of GT): the “scene driller”. That’s a special kind of inspector that lets you inspect the complete rendering tree. For every graphical element, you can access not only its attributes, but even the code that generated it.

3 Likes

A single GUI rendering tree for a Smalltalk seems like a great and obvious idea. But I don’t understand how Pharo didn’t already have this. Aren’t all Smalltalk UI elements just Smalltalk objects, and aren’t all Smalltalk objects already nodes in a single unified address space? Why was it necessary to completely rewrite the GUI system from scratch in order to get what Smalltalk already provides?

I mean I presume that Pharo didn’t provide this, somehow, but… how did it manage not to?

IIRC it was because it inherited Morphic from Squeak which was an unholy mess. (lots of unfinished experiments and extension and other stuff)

Note that Cuis also rewrote Morphic to be sensible.

1 Like

Pharo has indeed inherited its graphics layer from Squeak. It’s based on a single pixel canvas, but not a single rendering tree. There is a window manager, and application code is supposed to draw only inside its window.

But Pharo is also evolving away from the Morphic heritage. There’s a GTK-based graphics infrastructure now, so programmers can use multiple native windows. And Pharo will likely adopt the Bloc graphics layer from Glamorous Toolkit, but in a not-fully-compatible version, for reasons that I don’t know.

1 Like