Hacker News new | past | comments | ask | show | jobs | submit login
Actors for Squeak Smalltalk (tonyg.github.io)
81 points by tonyg 4 months ago | hide | past | web | favorite | 26 comments

Thanks for sharing!

I have a question coming from Erlang-world eg how exactly did you implement concurrency? Erlang VM has a counter for each VM instruction and does process switch based on that, did you implement something similar? Is this preemptive concurrency like the one in Erlang?

And a second question - will it work in Pharo? :)

Class Actor inherits from class Process, so Squeak's underlying process-switching machinery is in effect, complete with priorities, nonpreemption, any use of semaphores etc.

It could in principle work in Pharo, and I did try to port it to Pharo - almost all of the necessary infrastructure is the same - but I remember that at the time there were two problems. The first is that Pharo doesn't have an integrated Promise implementation. The second is that I couldn't get Pharo's sockets to behave as reliably as Squeak's. I don't remember details - missing error reporting in certain situations perhaps? - but I'd be very very pleased if a Pharo expert were to have a try at doing a port.

> This library adds an Erlang-style Actor model to Squeak.

Did you find any inspiration in late '80s experiments on implementing Actors in Smalltalk?

"From Objects to Actors: Study of a Limited Symbiosis in Smalltalk-80"


Thank you!

I've actually started learning Squeak/Smalltalk recently, and the possibility of using actor model is a great additional motivator, since I'm interested in agent-oriented programming.

Isn't an object is already an actor in Smalltalk?

Nope. Smalltalk objects aren't concurrent or asynchronous in any way. Smalltalk "messages" are good old method calls.

(To nitpick: there's a heck of a lot of concurrency, a property of system design, language design, and problem domain, but not much parallelism, a property of the specific VM in use. Smalltalk systems are usually managing interactivity on multiple fronts at the same time.)

> Smalltalk "messages" are good old method calls.

Technically, this is not exactly true. Messages are propagated to superclasses if an objects has no receiver, so they are more messages than method calls.

Also, the design decisions were to make objects an isolated entities which communicate by message passing. They does not have implicit mailboxes like it is in Erlang, and are not strongly-isolated, share-nothing entities (which is what makes the whole system fault-tolerant).

However, objects are definitely has some concurrency, but no async features in modern terms.

> Messages are propagated to superclasses if an objects has no receiver, so they are more messages than method calls.

are they ? this could be implemented with simple vtables and function pointers, without any difference in the case of a function being present or not in the child class case

Smalltalk "messages" are not asynchronous, but they are also not "good old method calls."

One example of that is that objects handle any message and if it doesn't know how to reply by default (defined in Object class) it raises an error. But this can be redefined (message doesNotUnderstand:) to do anything you want.

Smalltalk supports multicore since the early days, in fact the Blue Book even has some examples for data simulation.

Simulations can be done on one time-sliced processor!

Which main "Smalltalk" are you thinking of when you say "supports multicore since the early days"?

There certainly have been research Smalltalk implementations that do, like:

"Multiprocessor Smalltalk: A Case Study of a Multiprocessor-Based Programming Environment"


and more complete implementations like Actra and Gemstone/S.

The reference to the Blue Book made it quite obvious.

Thanks for the paper reference.

As for Gemstone I was aware of it. :)

> reference to the Blue Book

So you mean ParcPlace Smalltalk-80 "supports multicore since the early days"?

I think those Smalltalk "processes" are run in the same OS thread and only use one core, so please explain what you mean.

Were you aware of Actra?

After re-reading the Process/ProcessScheduler chapter you are right, it explicitly mentions one VM per CPU.

So from that point I stand corrected, however I would say it was an implementation detail, as the ProcessScheduler could easily have other policies.

> implementation detail

There's an enormous chasm between research experiments:

September 1988 "From Objects to Actors: Study of a Limited Symbiosis in Smalltalk-80"


:and well-understood techniques supported by all the programming tools.

Thanks for the paper.

Oh, my bad. Erlang's processes are actors, not Smalltalk objects, sorry.

The original Smalltalk was pretty close. By Smalltalk-76, they'd switched to calling methods synchronously (although still naming the calls "messages", I believe).

Is the spawning overhead comparable to that of Erlang's BEAM?

The performance tradeoffs are quite different, because this library uses the unmodified Smalltalk virtual machine that underlies Squeak. I would guess spawning is quite fast, because it is more-or-less just a few object allocations (plus a couple of linked list manipulations), but I have not made any serious measurements of performance of the system. Also, the Squeak VM has (IIRC) limited ability to make use of true parallelism.

A second tradeoff is in terms of flexibility: this is an ordinary (and fairly small) Smalltalk library, and so can be quickly sculpted into variations on the theme of Actors. Making similar modifications to Erlang would be very expensive. I aim to use this library as a foundation for experimenting with Syndicate-style ideas (https://syndicate-lang.org/) in a pervasively OO setting.

Syndicate seems very cool! Do you know if it's used by anyone or is it more of a research project at this stage? Am I right that the pattern seems very similar to re-frame [0] in Clojurescript? It seems like it might be an excellent way to develop web apps, especially since I see there's a javascript version as well.

[0] https://github.com/Day8/re-frame

It is still a research project, though I am working on a new implementation that brings it up to production standards.

Re-frame does look similar, but Syndicate is general in the same way that the Actor model is general; DOM support and other "I/O devices" are bolt-on drivers, not built in to the core.

Syndicate does make a nice way to develop web apps; for example, the whatsapp-like chat app here https://github.com/tonyg/syndicate/tree/master/examples/webc... shows a few of the ideas, though it's only prototype/experimental quality. The new implementation ought to be suitable for making such applications "for real". See also the handful of in-browser demos, which naturally focus on web-ish things: http://syndicate-lang.org/examples/.

The Racket implementation has been used to implement not only the server side of the webchat app, but also a TCP/IP stack [1], an IRC server [2], and a side-scrolling platform game [3].

I'm afraid that there's very little documentation available (it is still a research project, after all!). You can read more about the ideas behind it here, though: http://syndicate-lang.org/tonyg-dissertation/.


[1] https://github.com/tonyg/syndicate/tree/master/examples/nets...

[2] https://github.com/tonyg/syndicate/tree/master/examples/ircd

[3] https://github.com/tonyg/syndicate/blob/master/examples/plat...

Thanks I will check out those examples! Again, this looks really cool. I just started playing a bit with Racket, so this is nice to dive into.

> Also, the Squeak VM has (IIRC) limited ability to make use of true parallelism.

The Squeak VM is single-threaded, OS-wise, so it's just green threads. I don't even honestly remember to what extent its green threads are preemptive; I do remember that anything hitting C would pause other threads until it concluded, though, which made it really important to make sure that e.g. your database driver was 100% Smalltalk so it wouldn't lock the VM constantly.

Kinda. The VM executes Smalltalk on a single thread (interpreting or running JIT-compiled code). At the Smalltalk level, the unit of concurrency is called a "process". Processes are assigned priorities. Processes with higher priority preempt processes of lower priority, but processes of the same priority are cooperative.

So yes, "green threads". However, the VM does run multiple OS threads. When a Smalltalk process does IO, that gets performed on a different OS thread by the VM and the calling Smalltalk process is blocked, which lets another Smalltalk process get scheduled.

You could do that trick for things like calling ODBC or computationally expensive C code, but if you just call single-threaded C code directly, yeah, it'll block all Smalltalk processes until it returns.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact