https://www.gnu.org/software/smalltalk/
There's the free/open Pharo ("Squak for grown-ups"): https://pharo.org/
(Recently featured on hn in the guise of smalltalk on truffle/graalvm https://news.ycombinator.com/item?id=21735782 )
And commercial offerings like Gemstone:
https://gemtalksystems.com/products/gs64/
The recently open sourced dolphin: http://www.object-arts.com/gettingstarted.html
You can run whatever code you want in those windows, but just by finishing the tutorial you'll have an idea of what you're getting into.
It's on my backlog of things to toy with, along with Prolog. And after playing with Objective-C long enough I quite enjoy the syntax.
As a teaser, consider a predicate Concat(X, Y, Z). In Prolog, capitalized identifiers are considered as unbound variables. There aren't return values; instead, you compute via unification.
So we can approximate the idea of a list concat funtion by entering something like `Concat([1, 2], [3, 4], X).` The Prolog evaluator will answer that X must be [1, 2, 3, 4] in order for the predicate to hold true. Looks like a standard function with a quirky way to provide an out param.
But these are predicates, not functions. Concat's internal logic defines a logical relation among the various values. This logic holds no matter which values you leave unbound. So here are some other things you get for free:
`Concat(X, Y, [1, 2, 3, 4]).` -- this will, in turn, iterate through all possible values of X and Y that make this predicate true. Thus Prolog will give us X: [], Y: [1,2,3,4]; but also X: [1], Y: [2,3,4]; and so on.
`Concat(X, [3, 4], [1, 2, 3, 4]).` -- this will give us X: [1, 2]; alternatively, it will give us the answer 'no' (sort of equivalent to false) if [3, 4] is not some tail of the provided list.
`Concat([1, 2], [3, 4], [1, 2, 3, 4]).` -- will give us "yes", for true.
This is a simple example, but now perhaps the potential power of Prolog is more visible. Imagine the possibilities -- for instance, a constructed grammar can tell you not only if a given candidate sentence is valid, but it can also (in theory) generate every single valid sentence in turn.
I've had an idea for a prolog side-project for a while, but just haven't learned enough yet to know how I could implement it. In my mind, reserving a slot in a calendar or otherwise finding the next best opportunity is a valid use-case.
Interestingly, I enjoy Objective-C despite its syntax.
"Cuis is a free Smalltalk-80 environment with a specific set of goals: being simple and powerful. It is also portable to any platform, fast and efficient."
Learning the Smalltalk “world”/vm is an essential part of learning Smalltalk the language. Many people are initially put off by this but if you try to find a “Smalltalk without a Smalltalk-specific IDE” you are missing out on an enormous part of what Smalltalk is.
0. https://www.cs.virginia.edu/~evans/cs655/readings/smalltalk....
The os has become a passive tool to run stuff on, but once it was an involved middle layer that the user might be tapping throughout their use, with the os & user capable of understanding exposing & controlling some of the items in the program space. Now the program is more of a blind space to the os, doing it's own thing. Adjusting a program's volume & resizing it's window is all the interaction most users project from os space into program space.
More general systems research please!
I guess developers always implement their own ignorance to a certain degree (and how could they not!? except, you know, spending more time learning their craft). What they don't know the OS can do, they will recreate - often poorly - in their own software. It does get rather comical and the various frameworks that you can subscribe to in modern programming languages repeat the concept, just that now, you're reimplementing things that the language can already do, but in the framework.
My favorite example is the various kinds of "service" patterns, like dependency injection - in many instances that I've seen, you could boil most of its use down to simple function calls. But since global functions are ew, you instead create a service that you inject and then call a method in. Boom, the gods of OOP are happy and nobody is allowed to say: "Wait a minute, if I take a few steps back and squint a little, what you're doing looks surprisingly similar to a global function call."
(And yes, I know, DI is supposed to be about overriding functions, yada yada very few people actually do that and it's often such an organizational hassle with downstream problems that projects eventually resort to put up conventions from doing that most of the time. Anyways - tell that to the people that I've seen implement, I kid you not, a CamelCaseService.)
So if you have a class that uploads files to a cloud storage provider - it would make use of IStorageProvider, and you might have AmazonS3StorageProvider, AzureBlobStorageProvider, LocalDiskStorageProvider, and for testing you would have DevNullStorageProvider.
A program using DI without interfaces with different implementations is missing the other advantages of DI.
Soon there will be packages with millions of Actor cores for quadrillions of Actors. Operating systems, e.g. Linux, will be inadequate for Reusable Sacalable Intelligent Systems.
See the following: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3428114
Digging into the code, I found that the VM just gives a code block access to all top level objects by default, but that isn’t a requirement. You can instantiate your own “global” and run the block within that. Back then I believe it was being used because old closures needed to see old top level class objects that might have been changed in the meanwhile. So you can use this to sandbox functions.
I would imagine it isn’t perfect, but it could be made so.
Pharo is a modern open source Smalltalk that was derived from Squeak. Nice UI, vibrant ecosystem and community. https://pharo.org/
It looks like I want to start with Pharo Launcher, so I've installed the Pharo VM and Pharo Launcher, but when I try to start Pharo Launcher a window pops up and it just exists. All I can see in the terminal is a message about pthread_setschedparam failing, which does not seem fatal.
I wonder whether my problem is with not understanding what I'm doing, or with NixOS, or something in between...
Just spotted this on Cuis smalltalk github page:
"If you get this error message (you won't get it if you run Cuis as root or sudo):
pthread_setschedparam failed: Operation not permitted ...
Then you need to do this (just one time):
sudo cp Cuis-Smalltalk-Dev/squeak.conf /etc/security/limits.d/squeak.conf
Log out and log back in, or reboot the machine."
Might be something similar for pharo?
https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev/blob/ma...
I'd guess you could get some hints by running ldd on the vm (I'm assuming it's not strictly a static binary).
You need the vm and an image - the launcher I imagine is a vm and just enough image to display a menu and get a "proper" image downloaded.
Perhaps I'm missing something but I doubt the Linux VM download on that page will help me. Ordinary binaries don't tend to run on NixOS without at least some ELF patching due to the Nix store architecture.
That is possible in other many other languages, including system ones like C.
Which doesn't really mean much when it comes to the standard developer experience and how that differs between programming a live image and the tooling built around that versus manipulating text and the tooling built around that. One lives at the abstraction level of running code and the other at the level of syntax.
In C/C++, I can do live debugging, reverse-time debugging, edit-and-continue debugging, multi-device debugging, multi-threading debugging... We also got language servers, on the fly retesting and recompiling, all kinds of profiling... All that with free or open tools readily available, not to mention paid, proprietary ones.
In higher-level languages, fancy features are even more prevalent.
So, what are we missing exactly from Smalltalk?
That's kind of the point.