| ▲ | Ruby and Its Neighbors: Smalltalk(noelrappin.com) |
| 188 points by jrochkind1 16 hours ago | 102 comments |
| |
|
| ▲ | postexitus 14 hours ago | parent | next [-] |
| What this blog omits to mention and I think the most impressive part of Smalltalk ecosystem is the structure of the image - the application's state that you can freeze and distribute and resume elsewhere (makes supporting client side applications so much easier). The Smalltalk image is a very interesting beast. Look at it as a kind of immortality. Many current Smalltalk systems, Pharo, Squeak, VisualWorks among them, share a common ancestor, that is, a Smalltalk image from Xerox PARC. This common ancestor however is not some remote thing, but actually still alive in those modern systems. The modern variants were produced by sending messages to the objects in that image. Some of those messages actually morphed the current objects. Classes are full-blown objects, and creating new classes is done by sending messages to class objects. Some of the objects in a Smalltalk image may date back to 1972, when the first Smalltalk image bootstrapped! Smalltalk images never die, they just fade into something potentially fundamentally different. You should view your application building as not fundamentally different from creating a new Smalltalk version. |
| |
| ▲ | Scubabear68 13 hours ago | parent | next [-] | | The image concept, in my opinion, is what really limited Smalltalk's appeal and distribution. The image meant you basically got whatever state the developer ended up with, frozen in time, with no indication really of how they got there. Think of today's modern systems and open source, with so many libraries easily downloadable and able to be incorporated in your system in a very reproducible way. Smalltalk folks derided this as a low tech, lowest-common-denominator approach. But in fact it gave us reusable components from disparate vendors and sources. The image concept was a huge strength of Smalltalk but, really in the end in my opinion, one of the major areas that held it back. Java in particular surged right past Smalltalk despite many shortcomings compared to it, partially because of this. The other part of course was being free at many levels. The other half of Smalltalk issues beyond the image one, was the cost of both developer licenses ($$$$!) and runtime licenses (ugh!). | | |
| ▲ | cbsmith 10 hours ago | parent | next [-] | | > The image meant you basically got whatever state the developer ended up with, frozen in time, with no indication really of how they got there. That wasn't a function of the image system. That was a product of your version control/CI/CD systems and your familiarity with them. Consider that Docker and other container based systems also deploy images. No reason Smalltalk has to be any different. I did software development work in Smalltalk in the 90's. We used version control (at one point, we used PVCS, which was horrible, but Envy was pretty sweet), had a build process and build servers that would build deploy images from vanilla images. Even without all that, the Smalltalk system kept a full change log of ever single operation it performed in order. In theory, someone could wipe their changelog, but that's the moral equivalent of deleting the source code for your binary. Image-based systems are no reason to abandon good engineering practices. | | |
| ▲ | lmm 6 hours ago | parent [-] | | > Consider that Docker and other container based systems also deploy images. Consider also that Docker was the only one to really get popular, perhaps because it promoted the idea of using a text-based "Dockerfile" as your source of truth and treating the images as transitory built artifacts (however false this was in practice). |
| |
| ▲ | btilly 12 hours ago | parent | prev | next [-] | | I agree that the image concept was a problem, but I think that you're focused on the wrong detail. The problem with an image based ecosystem that I see is that you are inevitably pushed towards using tools that live within that image. Now granted, those tools are able to be very powerful because they leverage and interact with the image itself. But the community contributing to that ecosystem is far smaller than the communities contributing to filesystem based tools. The result is that people who are considering coming into the system, have to start with abandoning their familiar toolchain. And for all of the technical advantages of the new toolchain, the much smaller contributor base creates a worse is better situation. While the file-based system has fundamental technical limitations, the size of the ecosystem results in faster overall development, and eventually a superior system. | | |
| ▲ | rbanffy 10 hours ago | parent | next [-] | | > But the community contributing to that ecosystem is far smaller than the communities contributing to filesystem based tools. Another point is that you need to export your tools out of your own image so others can import it into their images. This impedance mismatch between image and filesystem was annoying. | |
| ▲ | Scubabear68 12 hours ago | parent | prev [-] | | I think we could quibble over the relative importance of these points, but I agree in general. The image locking you into that ecosystem is definitely a good point. |
| |
| ▲ | rbanffy 10 hours ago | parent | prev | next [-] | | > The image meant you basically got whatever state the developer ended up with, frozen in time, with no indication really of how they got there. I worked with a similar language, Actor (Smalltalk with an Algol-like syntax), and the usual way to deal with distribution was to “pack” (IIRC) the image by pointing to the class that your app is an instance of, and the tool would remove every other object that is not a requirement of your app. With that you got an image that started directly into your app, without any trace of the development environment. | |
| ▲ | sebastianconcpt 12 hours ago | parent | prev | next [-] | | It wasn't the image concept. You use it every day in Docker containers for everything else. But saving the image has some drawbacks. Mutability always requires special care. | | |
| ▲ | chuckadams 12 hours ago | parent | next [-] | | The key is the plural in "Docker containers". You're not doing everything by modifying one Docker container that's been handed down over literally generations, you're rebuilding images as you need to, usually starting from a golden master, but sometimes starting from a scratch image into which you just copy individual files. It's the "cattle, not pets" mentality, whereas a Smalltalk or Lisp Machine image is the ultimate pet. | | |
| ▲ | Jtsummers 12 hours ago | parent [-] | | > You're not doing everything by modifying one Docker container that's been handed down over literally generations You don't do that with Smalltalk, either, at least not for the last 30 years or so. Smalltalk has worked with version control systems for decades to maintain the code outside the image and collaborate with others without needing to share images. | | |
| ▲ | rbanffy 10 hours ago | parent [-] | | It’s fun when you realize something that happened 30 years ago is a relatively recent addition to the typical workflow. | | |
| ▲ | Jtsummers 10 hours ago | parent [-] | | I try not to think about these things, I've mostly worked with hardware-centric companies and on "legacy" systems. So many things they're doing that no one else does because 5-25 years ago everyone else figured out the lessons from 30-60 years ago, except for these companies. |
|
|
| |
| ▲ | Scubabear68 12 hours ago | parent | prev [-] | | I disagree, it really was the image concept, or very specifically how it was created and maintained over time. A docker container is composed typically of underlying components. You can cowboy it for sure, but the intent is to have a composable system. The Smalltalk image resulted from the developer just banging on the system. | | |
| ▲ | isr 12 hours ago | parent [-] | | Except that's not really what happened. You're ignoring the range of in-image tools which kept track if who did what, where. From versioning of individual methods, to full blown distributed version control systems, which predated git. Not to sound harsh or gatekeep, but folks who keep repeating the canard that "The Smalltalk image resulted from the developer just banging on the system", mostly never used smalltalk in the first place. Give the original smalltalk devs some credit for knowing how to track code development over time. | | |
| ▲ | Scubabear68 11 hours ago | parent [-] | | No, I haven't ignored those tools. They were all stop-gaps that worked in a "meh" way to various degrees. Smalltalk was always optimized to one guy banging away on their solution. Add a second developer and things got much hairier, and more so as you kept adding them. | | |
| ▲ | isr 10 hours ago | parent [-] | | Hmm, well I don't know exactly when Monticello was first developed, but it was certainly in heavy use by the early 2000s. How is that "meh" when compared to ... cvs & subversion? I don't know much about the systems used in commercial smalltalks of the 90s, but I'm sure they weren't "meh" either (others more knowledgeable than me about them can chime in). image-centric development is seductive (I'm guilty). But the main issue isn't "we don't know what code got put where, and by whom". There were sophisticated tools available almost from the get go for that. Its more a problem of dependencies not being pruned, because someone, somewhere wants to use it. So lots of stuff remained in the "blessed" image (I'm only referring to squeak here) which really ought not to have been in the standard distribution. And because it was there, some other unrelated project further down the line used a class here, a class there. So when you later realise it needed to be pruned, it wasn't that easy. But nevertheless, it was still done. Witness cuis. In other words, it was a cultural problem, not a tooling problem. It's not that squeak had too few ways of persisting & distributing code - it had too many. IMHO, the main problem was never the image, or lack of tools. It was lack of modularisation. All classes existed in the same global namespace. A clean implementation of modules early on would have been nice. | | |
|
|
|
| |
| ▲ | mpweiher 11 hours ago | parent | prev | next [-] | | >> most impressive part of Smalltalk ecosystem is the structure of the image > The image concept, in my opinion, is what really limited Smalltalk's appeal and distribution. I'd say these statements are both true. The image concept is very impressive and can be very useful, it certainly achieved a lot of bang for very little buck. And it also was/is one of the major impediments for Smalltalk, at least after the mid 1980s. The impressive bit is shown by pretty much the entire industry slowly and painfully recreating the Smalltalk image, just usually worse. For example on macOS a lot of applications nowadays auto-save their state and will completely return to the state they were last in. So much that nowadays if you have a lot of TextEdit windows open and wish to make sure everything is safe, you kill the program, you don't quit it. Also, all/most of the shared libraries and frameworks that come with the system are not loaded individually, instead they are combined into one huge image file that is mapped into your process. At some point they stopped shipping the individual framework and shared library binaries. User interfaces have also trended in the direction of a an application that contains its own little world, rather than editing files that exist within the wider Unix filesystem. The image accomplished all that and more and did so very efficiently. Both in execution speed and in amount of mechanism required: have a contiguous piece of memory. Write to disk, make a note of the start pointer. On load, map or read it into memory, fix up the pointers if you didn't manage to load at the same address and you're ready to go. On G4/G5 era Macs, the latter would take maybe a second or two, whereas Pages, for example, took forever to load if things weren't already cached, despite having much less total data to load. But the drawbacks are also huge. You're really in your little world and going outside of it is painful. On an Alto in the mid to late 1970s I imagine that wasn't much of an issue, because there wasn't really much outside world to connect to, computer-wise, and where would you fit it on a 128KB machine (including the bitmap display)? But nowadays the disadvantages far outweigh the advantages. With Objective-S, I am building on top of Cocoa's Bundle concept, so special directories that can contain executable code, data or both. Being directories, bundles can nest. You can treat a bundle as data that your program (possibly the IDE) can edit. But you can also plonk the same bundle in the Resources folder of an application to have it become part of that application. In fact, the IDE contains an operation to just turn the current bundle into an application, by copying a generic wrapper application form its own resources and then placing the current bundle into that freshly created/copide app. Being directories, data resources in bundles can remain standard files, etc. With Objective-S being either interpreted or compiled, a bundle with executable code can just contain the source code, which the interpreter will load and execute. Compiling the code inside a bundle to binaries is just an optimization step, the artifact is still a bundle. Removing source code of a bundle that has an executable binary is just an obfuscation/minimization step, the bundle is still the bundle. | |
| ▲ | shevy-java 12 hours ago | parent | prev | next [-] | | Agreed with that; this is why I think it should unite both the "scripting" as well as image approach, at the same time. | |
| ▲ | cess11 12 hours ago | parent | prev | next [-] | | Contemporary Smalltalks support git. | | |
| ▲ | rbanffy 10 hours ago | parent [-] | | And, more importantly, source code files. | | |
| ▲ | igouy 9 hours ago | parent | next [-] | | For decades — "When you use a browser to access a method, the system has to retrieve the source code for that method. Initially all the source code is found in the file we refer to as the sources file. … As you are evaluating expressions or making changes to class descriptions, your actions are logged onto an external file that we refer to as the changes file. If you change a method, the new source code is stored on the changes file, not back into the sources file. Thus the sources file is treated as shared and immutable; a private changes file must exist for each user." 1984 "Smalltalk-80 The Interactive Programming Environment" page 458 | |
| ▲ | layer8 8 hours ago | parent | prev [-] | | But the image isn’t just the code, or classes, it’s also the network of objects (instances). And that’s more difficult to version, or to merge branches of. | | |
| ▲ | igouy 6 hours ago | parent [-] | | Given that the instantiation of those objects has been triggered by Smalltalk commands; those Smalltalk commands can be recorded and versioned and replayed to instantiate those objects. | | |
| ▲ | layer8 5 hours ago | parent [-] | | It means that versioning operations, even just displaying the history, effectively have to run the full image from the beginning of the history, or take intermediate snapshots of the image. In addition, there is interaction between the source code changes and the recorded command history. It also doesn't address how merging would be practical. You would have to compare the state of two images side-by-side, or rather three, for three-way merges. |
|
|
|
| |
| ▲ | Barrin92 12 hours ago | parent | prev | next [-] | | the entire philosophy of Smalltalk was to think of software artifacts as living entities. You can just find yourself in a piece of software, fully inspect everything and engage with it by way of a software archaeology. To do away with the distinction between interacting, running and writing software. They wanted to get away from syntax and files, like an inert recipe you have to rerun every time so I think if you do away with the image you do away with the core aspect of it. Computing just in general didn't go the direction they wanted it to go in many ways I think it was too ambitious of an idea for the time. Personally I've always hoped it comes back. | | |
| ▲ | shevy-java 12 hours ago | parent [-] | | I'd include both approaches. The thing is that the "scripting" approach, is just so much easier to distribute. Just look at how popular python got. Smalltalk didn't understand that. The syntax is worse than python IMO (and also ruby of course). | | |
| ▲ | rbanffy 10 hours ago | parent [-] | | Once I asked James Gosling what Java did right that Smalltalk did wrong. He simply answered “Smalltalk never played well with others”. Imposing a very different metaphor from the ground up limited adoption and integration with other tools and environments. | | |
|
| |
| ▲ | api 10 hours ago | parent | prev | next [-] | | Re: the image concept. A lot of great ideas are tried and tried and tried and eventually succeed, and what causes them to succeed is that someone finally creates an implementation that addresses the pragmatic and usability issues. Someone finally gets the details right. Rust is a good example. We've had "safe" systems languages for a long time, but Rust was one of the first to address developer ergonomics well enough to catch on. Another great example is HTTP and HTML. Hypertext systems existed before it, but none of them were flexible, deployable, open, interoperable, and simple enough to catch on. IMHO we've never had a pure functional language that has taken off not because it's a terrible idea but because nobody's executed it well enough re: ergonomics and pragmatic concerns. | | |
| ▲ | pluralmonad 7 hours ago | parent [-] | | Typed out a response indicating the really good dev experience that F# and Elixir offer, but neither are "pure". Is Haskell the closest mainstream language to meet a purity requirement? |
| |
| ▲ | lawlessone 13 hours ago | parent | prev | next [-] | | Isn't this kinda where AI is now? Like with LLM's it seems impossible to separate the "reasoning" from data it has stored to learn that reasoning. | |
| ▲ | fellowniusmonk 13 hours ago | parent | prev [-] | | For this very reason I'm working on a development platform that makes all changes part of a cheaply stored crdt log. The log is part of the application, there are some types of simulations inside of this that we can only timestamp and replay but we can always derive the starting position with 100% accuracy. | | |
| |
| ▲ | mccoyb 7 hours ago | parent | prev | next [-] | | Are you `robject` on Stack Overflow -- or perhaps you might explain why you copied verbatim their response to https://stackoverflow.com/questions/3561145/what-is-a-smallt... without citing your source? | |
| ▲ | sandcat_ 11 hours ago | parent | prev | next [-] | | Unless you are indeed the original author from StackOverflow, it would be polite to attribute your comment: https://stackoverflow.com/a/3617319 | |
| ▲ | criddell 13 hours ago | parent | prev | next [-] | | > makes supporting client side applications so much easier I was thinking that supporting a Smalltalk application must be a nightmare because it is so malleable. Users can inspect and modify the entire system, no? | | |
| ▲ | e12e 12 hours ago | parent | next [-] | | I used to think so, then watched as javascript in the browser rose to be the premium application platform - where the user has access to a console/repl, developer tools etc... | | |
| ▲ | sethhochberg 12 hours ago | parent [-] | | I think many people would suggest that this was more of an accident due to the ubiquity of the browser, though. The transition from "websites" to "web apps" was well underway by the time the dev tools became a built-in browser feature - Chrome was notable for being the first browser to release with the console, inspectors, etc out of the box, but that came later. The developer experience was quite a bit rougher in the early days, and then better but still not native in the days of plugins like Firebug. The web becoming the premium app distribution platform was, firstly, because the web was the lowest-common-denominator distribution channel. Javascript was just the tool that was available where everyone wanted to run. | | |
| ▲ | e12e 8 hours ago | parent [-] | | Yes, but maintaining a webapp isn't a nightmare due to the user being able to inspect css, edit html or access the javascript console? | | |
| ▲ | NetMageSCW 7 hours ago | parent [-] | | The difference is the changes the user can make don’t flow back to the original. If the user hits refresh they get your copy of the web app, not theirs. |
|
|
| |
| ▲ | igouy 9 hours ago | parent | prev | next [-] | | > Users can inspect and modify the entire system, no? End users? Yes if you - want them to - let them; No if you - don't want them to - stop them. | |
| ▲ | Qem 13 hours ago | parent | prev | next [-] | | > Users can inspect and modify the entire system, no? That should make the Smalltalk family popular with free software proponents. That makes me curious why that is not the case in history. The efforts of FSF on Smalltalk pale in comparison with those on C, Lisp and other languages. | |
| ▲ | ssdspoimdsjvv 8 hours ago | parent | prev | next [-] | | Smalltalk being so malleable also makes it possible to completely disable source code inspection/execution. | | |
| ▲ | igouy 8 hours ago | parent [-] | | And then what? Say you made the foreground text color the same as the background text color, so you could no longer see the source code. You can no longer do anything. You can no longer save those changes. And then what? Better, say you did that in a script file which additionally saved the image, so that image was now unusable. And then what? |
| |
| ▲ | supportengineer 13 hours ago | parent | prev [-] | | Correct, at least that was true when I was a Smalltalk developer. |
| |
| ▲ | shevy-java 12 hours ago | parent | prev | next [-] | | That part is also cool. I'd like this in ruby too, e. g. where we could have tons of objects reflect on that state, and just resume work there. Everything is an object. Squeak everywhere, but to also retain the "scripting" (light) commandline approach. Nobody in smalltalk really understood why "scripting" is important. Python showed why. | | |
| ▲ | igouy 9 hours ago | parent [-] | | > also retain the "scripting" (light) commandline approach Smalltalk developers preferred to do their scripting within the Smalltalk IDE, so they could use their familiar tools. And then save their "scripting" as a text file ("fact.st"). $ cat fact.st
Stdio stdout
nextPutAll: 100 factorial printString;
nextPut: Character lf.!
SmalltalkImage current snapshot: false andQuit: true!
And then "run" that text file ("fact.st") from the commandline. $ bin/pharo --headless Pharo10-SNAPSHOT-64bit-502addc.image fact.st
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 |
| |
| ▲ | isr 12 hours ago | parent | prev [-] | | Adding to what you said. Squeak was a clean open source reimplementation (by the devs who did the original Smalltalk-80), so it's real history starts from there (ie: the 90s, not the 70s) One thing to keep in mind is that smalltalks all have the same ability to save & load code to & from disk, just as any other programming environment. But, they also have the option of just using the image to persist, and iterate on that. Squeak overdid that aspect of it, such that over time, it became hard to prune older side projects & and it just became increasingly bloated. Both Pharo & Cuis forked from squeak at about the same time. Pharo images are fully bootstrapped from a seed. Cuis is not quite there yet, but cuis from its inception went on a ruthless simplification drive (the number of classes in the system was reduced by about 500% !), so that it's base is effectively a "seed", and the rest of a cuis image is built up by importing projects (from disk & git) on demand. But yeah, curating a set of images over time is remarkably enticing & friction free. Even in cuis, I find I have to force myself to keep flushing changes to my own packages. Its not that the tools to use files are limited. In cuis, they're not. You can work on multiple different things WITHIN THE SAME IMAGE (changes to some builtins, a couple of your own projects, etc), and the system will keep track of what belongs where. So a couple of mouse clucks will fileout the relevant code to the relevant changesets & packages. And yet - just banging on the same image is just ... fun, easy, enticing. | | |
| ▲ | mpweiher 11 hours ago | parent [-] | | > Squeak was a clean open source reimplementation Small correction: they actually cloned/converted the Apple Smalltalk image, so those bits remained. The VM was created from scratch by writing it in Slang, a Smalltalk dialect that was essentially equivalent to BCPL and could be translated to C. https://dl.acm.org/doi/10.1145/263698.263754 | | |
| ▲ | jecel 9 hours ago | parent | next [-] | | The VM in Slang had been previously published as part of the "blue book" (now that is what I call open source!) some 14 years before, and as the paper you linked to mentioned, Mario Wolczko at the University of Manchester had typed it in so it was available in machine readable form. They did drop the object memory part completely and designed a new one from scratch. Previously people had manually translated the VM from Slang to Pascal or C (I did so myself in 1986) but for this project they wrote a tool for that (in Smalltalk, of course). Here is another copy of the "Back to the Future" paper: http://www.mirandabanda.org/files/Papers/BttF.html | |
| ▲ | isr 11 hours ago | parent | prev [-] | | I didn't know that. So they didn't bootstrap an image from scratch, when they created the new VM? | | |
| ▲ | xkriva11 10 hours ago | parent | next [-] | | No, they used a tool (SystemTracer) running inside the original Smalltalk that enumerated all the objects in the running image and serialized them in a new image format into a new image file. Every time the image file format changed, it was transformed like this. Smalltalk is very close to a biological system. | |
| ▲ | mpweiher 11 hours ago | parent | prev [-] | | That's how I understand what they wrote. "Produce a new image: - Design a new Object Memory and image file format.
- Alter the ST-80 System Tracer to write an image in the new format.
- Eliminate uses of Mac Toolbox calls to restore Smalltalk- portability.
- Write a new file system with a simple, portable interface."
https://dl.acm.org/doi/10.1145/263698.263754Hmm...I wonder if Dan used the PDF writer I wrote for him to produce that version of the paper... | | |
| ▲ | isr 10 hours ago | parent [-] | | Thanks for the info. Hmm, it's kind of cool to think there might be a few classes in today's fully-accelerated-vector-graphics-morphic cuis system that were first keyed into the system on an Alto in the 70s :-) |
|
|
|
|
|
|
| ▲ | ripe 5 hours ago | parent | prev | next [-] |
| Smalltalk-80 was also good for graphics programming. Around 1990, I was a graduate student in Prof. Red Whittaker's field robotics group at Carnegie Mellon. In Porter Hall, I was fortunate to have a Sun 3/60 workstation on my desk. It had a Smalltalk-80. I learned to program it using Goldberg & Robson and other books from ParcPlace Systems. The programming environment was fantastic, better than anything I have seen before or since. You always ran it full screen, and it loaded up the Smalltalk image from disk. As the article says, you were in the actual live image. Editing, running, inspecting the run-time objects, or debugging: all these tasks were done in the exact same environment. When you came into the office in the morning, the entire environment booted up immediately to where you had left it the previous day. The image had objects representing everything, including your screen, keyboard, and mouse. Your code could respond to inputs and control every pixel on the screen. I did all my Computer Graphics assignments in Smalltalk. And of course, I wrote fast video games. I used the system to develop programs for my Ph.D thesis, which involved geometric task planning for robots. One of the programs ran and displayed a simulation of a robot moving in a workspace with obstacles and other things. I had to capture many successive screenshots for my papers and my thesis. Everybody at CMU then wrote their papers and theses in Scribe, the document generation system written by Brian Reid decades earlier. Scribe was a program that took your markup in a plain text file (sort of at a LaTeX level: @document, @section, etc.) and generated Postscript for the printer. I never had enough disk space to store so many full screen-size raster images. So, of course, instead of taking screenshots, I modified my program to emit Postscript code, and inserted it into my thesis. I had to hack the pictures into the Postscript generation process somehow. The resulting pictures were vector graphics using Postscript commands. They looked nice because they were much higher resolution than a screenshot could have been. |
|
| ▲ | goodthink 14 hours ago | parent | prev | next [-] |
| If you love the keyword syntax of Smalltalk, the reflectivity, the incremental compilation, live debugging in the environment, check out https://newspeaklanguage.org for theSmalltalk experience in the web browser. This is my favorite video by Newspeak's creator Gilad Bracha: https://youtu.be/BDwlEJGP3Mk?si=Z0ud1yRqIjVvT4oO |
| |
| ▲ | smj-edison 9 hours ago | parent [-] | | That talk is fantastic! Just a note for anyone who's interested in Newspeak, it's more of a spiritual successor than a direct descendant of smalltalk (in a good way imo). It has some really slick features like: * No global import/export namespace (all imports are dependency injected, meaning capability based security is already baked in) * Nested classes instead of modules * No variable assignment (everything is a method call) * Mixins instead of inheritance * Synchronization and code updates as near primitives * Support for foreign objects through aliens and proxies, and foreign code can call newspeak objects through expats * A native serialization to file format * support for multiple overlapping type systems |
|
|
| ▲ | travisgriggs 2 hours ago | parent | prev | next [-] |
| I did Smalltalk for ~20 years as my primary. I’m a polyglot now, maintaining/implementing in C, Python, Swift, Kotlin, and Elixir. The thing (for me) about Smalltalk was the thought to code ratio. It was awesome. It had a pretty good balance of less is more. Where working in Swift and Kotlin feel like trying to navigate the many nuances of American football or cricket, Smalltalk was like playing soccer/football-sans-america. The syntax is simple. And the computation model is straitforward and simple. Elixir is kind of like that, computationally, a few simple concepts and everything builds on that. The saddest part about Elixir is that it ran with the whole do/end syntax. Drives me nuts. But I love that computationally, though different than Smalltalk, it’s like Smalltalk in that it’s a simple consistent model. |
|
| ▲ | frou_dh 14 hours ago | parent | prev | next [-] |
| Since Smalltalk is effectively an OS unto itself, when we hear about the days of commercial applications being written in Smalltalk, how did deployment to end-users work? Were the users running, say, Windows and then the Smalltalk "OS" would be running on top of that, but in a sort of "kiosk mode" where its full OS-ness was suppressed and it was dedicated to showing a single interface? |
| |
| ▲ | arnsholt 13 hours ago | parent | next [-] | | I worked on a Smalltalk system which ran on Visual Smalltalk Enterprise, and in that system the image opened its windows as native Windows GDI windows, which made the application quite seamless in the OS (except this was in 2016-2018 and VSE was last updated in ‘99, so the look and feel was a bit dated :D). | |
| ▲ | Arcanum-XIII 11 hours ago | parent | prev | next [-] | | I used a "modern" app written in Cincom Smalltalk this year (still maintain and sold a high price), and you don't see the underlying system. Like you don't see the source code when opening any other app, in fact.
The app resets the state at startup, so no lingering eternal session. It's funny because in the past I got the chance to test izware Mirai, which is written in Lisp — when the app got into a problematic state (which was often on my machine) you were sent to the REPL where you could inspect the memory and so on. It was alien to me at the time. Today I dream of having that. | | |
| ▲ | rbanffy 10 hours ago | parent [-] | | > (still maintain and sold a high price) I was surprised a couple years back they still maintain Mantis, a 4GL I used on a mainframe (it was kind of Rails for the 3270 terminal). Even the documentation is hideously expensive. I asked if they had a “hobby license” I could use to run under Hercules. They seemed genuinely perplexed that someone would imagine they would allow me to use their software without sacrificing my firstborn. |
| |
| ▲ | pjmlp 14 hours ago | parent | prev [-] | | Easy, you make use of tree-shaking, which is actually older concept than minifying JavaScript, and add glue it together with an executable header that boots the image. | | |
| ▲ | wk_end 13 hours ago | parent | next [-] | | I don't feel like this really answers OP's question, which is more about the user experience than the technical approach. When, as a dev, I use Smalltalk, it opens up what's effectively a virtual machine on my desktop. The whole Smalltalk GUI runs inside its own frame, none of the controls are native, etc. And it's a development environment - I have access to a class browser, a debugger, a REPL, and so on. I can drill down and read/modify the source code of everything. Which is great as a dev, but may be intimidating for an end user. Is that what the end user experience is like as well? I think that's what OP is asking. I've never used a Smalltalk application as an end user to my knowledge, so I can't say myself. | | |
| ▲ | pjmlp 12 hours ago | parent | next [-] | | The user experience, in commercial Smalltalks, like Cincom Smalltalk, is just like any other compiled application. The application packager removes everything that is related to Smalltalk as developer environment, and possibly other classes that are also not used by the application, so you get a slimmed down image. Then you have the VM boot code, as native executable, that is responsible for starting the image execution. Thanks to the way executable files work in most platforms, the packing tool merges that boot loader and the slimmed down image into a single executable. When the executable starts, the loader locates the image inside the executable, loads it, and transfers execution to the runtime. Java and .NET also have similar techniques available, see jlink, or Single-file deployment respectively. | |
| ▲ | igouy 10 hours ago | parent | prev | next [-] | | > none of the controls are native Depends which Smalltalk implementation. Digitalk and Dolphin and IBM Smalltalk … wrapped native widgets. | |
| ▲ | cess11 12 hours ago | parent | prev [-] | | No, you can tell the image to not boot the 'world', only the application you've been building. The details probably vary a lot between versions of the language, but you wouldn't be forced to put system browsers and all that in the face of your user. |
| |
| ▲ | uticus 14 hours ago | parent | prev [-] | | I don't understand what "tree-shaking" means, can you point to a reference to give me a better understanding? | | |
| ▲ | nielsbot 13 hours ago | parent | next [-] | | You might know it as "dead code stripping": You remove all the things from the image that aren't used in your shipping app. Calling it "tree shaking" is web development term AFAIK. | | |
| ▲ | munificent 9 hours ago | parent [-] | | > Calling it "tree shaking" is web development term AFAIK. I think that's backwards. Lars Bak and the other V8 folks came from the Smalltalk world and brought the "tree shaking" term with them as far as I know. | | |
| ▲ | layer8 7 hours ago | parent [-] | | Wikipedia claims that it originated in Lisp, and the oldest reference I can find is this from 1991:
https://www.dreamsongs.com/Files/LispGoodNewsBadNews.pdf (section 1.6.3) In any case, before the JavaScript usage, it seems that treeshaking applied to objects to be included in a runtime image. The JavaScript usage is actually more akin to the dead-code elimination and link-time symbol removal of compiled and linked languages. | | |
|
| |
| ▲ | shrubble 13 hours ago | parent | prev | next [-] | | Tree shaking in this context is not unlike a compiler: it looks at all the code and determines if it will ever run in the image, eliminating any unnecessary code and delivering the minimal image needed. The code is in a “tree” format like an AST, and you’re shaking the tree to test what can be removed. | |
| ▲ | pjmlp 12 hours ago | parent | prev [-] | | I used a more recent term known to Web developers. It means going through the image and remove most code that isn't directly needed by the application, or only exists to support developer workflows. Usually needs a bit help for fine tuning, regarding what code to keep, and what to delete. You also find this on Java (jlink, ProGuard, D8/R8 on Android), and .NET (trimming, .NET Native manifests). |
|
|
|
|
| ▲ | sebastianconcpt 12 hours ago | parent | prev | next [-] |
| Smalltalk is among the top most ergonomic ways to model concepts in a computer (capacity to model essential complexity) because the CPU got abstracted and compacted in the VM. But destiny made CPUs win and now we're using AI to chew their accidental complexity for us. |
|
| ▲ | jimbokun 13 hours ago | parent | prev | next [-] |
| So Ruby is Smalltalk but amenable to modern development practices and tools like source control and off the shelf text editors, and usable for Unix scripts. |
| |
| ▲ | vinceguidry 9 hours ago | parent | next [-] | | Ruby isn't Smalltalk. The only thing Ruby inherited from it is the pure object model. Everything else was cribbed from other languages. Ruby doesn't have what makes Smalltalk great, the image-based development model. I'm making my own text editor in Ruby now, as I'm wishing for a more Smalltalk-like experience with it. There's just so much missing. Ruby has the reflective capability to enjoy a Smalltalk-like IDE, but Rails took over and drove Ruby in that direction long before anyone could cook one up. Which is a shame, IDEs that aren't Smalltalk / Lisp haven't graduated past the need for static analysis despite having 50 years to do so. Now it's the red-headed stepchild of languages due to no fault of its own. | |
| ▲ | antod 12 hours ago | parent | prev | next [-] | | Ruby is like Smalltalk, but with some Perl (for good or bad) mixed in too IMO. | |
| ▲ | sebastianconcpt 12 hours ago | parent | prev [-] | | Basically yes. |
|
|
| ▲ | adamzwasserman 14 hours ago | parent | prev | next [-] |
| thanks for this article. as a history of languages aficionado myself, I appreciate both the content and the style. thanks again for the good reading |
|
| ▲ | kragen 13 hours ago | parent | prev | next [-] |
| > You’ve likely used powerful coding editors and terminals. Smalltalk is just different. You are in the running environment. I've experienced this a few different times: with Microsoft BASIC-80 (and GW-BASIC), with SBCL and SLIME, with LOGO, with GForth, with OpenFirmware, with MS-DOS DEBUG.COM, with Jupyter, and of course with Squeak. It really is nice. It used to be the normal way of using computers; before memory protection, it was sort of the only way of using computers. There wasn't another memory space for the monitor to run in, and the monitor was what you used to do things like load programs and debug them. This approach continued as the default into many early timesharing systems like RT-11 and TENEX: there might be one virtual machine (memory space) per user, but the virtual machine you typed system commands into was the same one that ran your application. TENEX offered the alternative of running DDT (the debugger) in a different memory space so bugs in the application couldn't corrupt it, and that was the approach taken in ITS as well, where DDT was your normal shell user interface instead of an enhanced one. All this seems very weird from the Unix/VMS/Win32 perspective where obviously the shell is a different process from your text editor, and it's designed for launching black-box programs rather than inspecting their internal memory state, but evolutionarily it was sort of the natural progression from a computer operator single-stepping a computer (with no memory protection) through their program with a toggle switch as they attempted to figure out why it wasn't working. One of the nicest things about this way of working is halt-and-continue. Current versions of Microsoft Visual Studio offer sometimes halt and continue. In MBASIC you could always halt and continue. ^C halted the program, at which point you could examine variables, make arbitrary changes to the program, GOTO a line number, or just CONT to continue where you'd interrupted it. Smalltalk, SLIME, or ITS allows you to program in this way; if you like, you can refrain from defining each method (or function or subroutine) until the program tries to execute it, at which point it halts in the debugger, and you can write the code for the method and continue. This is an extremely machine-efficient approach; you never waste cycles on restarting the program from the beginning unless you're going to debug program initialization. And in Smalltalk there isn't really a beginning at all, or rather, the beginning was something like 50 years ago. Myself, though, I feel that the hard part of programming is debugging, which requires the experimental method. And the hard part of the experimental method is reproducibility. So I'm much more enthusiastic about making my program's execution reproducible so that I can debug faster, which conflicts with "you're in the running environment". (As Rappin says, "Code could depend on the state of the image in ways that were hard to replicate in deploys." I experience this today in Jupyter. It's annoying to spend a bunch of time trying to track down a bug that doesn't exist when you restart from scratch; worse is when the program works fine until you restart it from scratch.) So I'm much more excited about things like Hypothesis (https://news.ycombinator.com/item?id=45818562) than I am about edit-and-continue. Paul Graham wrote somewhere (I can't find it now) about how in Viaweb's early days he would often fix a bug while still on the phone with the customer who was experiencing it, because he could just tweak the running CLisp process. But you can do the same thing in PHP or with CGI without sacrificing much reproducibility—your system's durable data lives in MariaDB or SQLite, which is much more inspectable and snapshottable than a soup of Smalltalk objects pointing to each other. (#CoddWasRight!) Especially since the broad adoption of the Rails model of building your database schema out of a sequence of "migrations". |
| |
| ▲ | arnsholt 13 hours ago | parent | next [-] | | I found the Smalltalk way of working in the running environment to be very programmer efficient too, and that it was by far the smoothest development experience I’ve had, even in a pretty dated and clunky Smalltalk at that point. And debugging wasn’t really a problem in my experience, but we stored application state outside of the image in an SQL database (initially Sybase, then MSSQL), which probably removes some «haha, the image has some weird data saved in the dark and dusty corners» issues. | |
| ▲ | toast0 13 hours ago | parent | prev [-] | | > But you can do the same thing in PHP or with CGI without sacrificing much reproducibility PHP is similar, but not the same. You can't (or at least I can't) stop a request in progress and change its code; but you can rapidly change the code for the next request. Make a change in the editor, hit reload in the browser is a productive short loop, but stop at a breakpoint, inspect the state and change the code is a more powerful loop. Stopping at a breakpoint is challenging in systems with communication though, and I've learned to live without it for the most part. | | |
| ▲ | kragen 13 hours ago | parent [-] | | Yes, I agree. I meant that you can edit code on the production web server so that the customer you're on the phone with sees their application start working. PG had the advantage that he could tweak the Lisp process for that specific user, reducing the risk of breaking the site for other concurrent users. Database transactions bridge some of the gap between "change the code for the next request" and "stop at a breakpoint and change the code": as long as your request handler code keeps failing, it will abort the transaction, so the database is unchanged, so you can restart the transaction as many times as you want to get to the same point in execution, at least if your programming language is deterministic. By providing a snapshot you can deterministically replay from, it allows you to add log entries before the point where the problem occurred, which can be very useful. Stopping at a breakpoint can be more productive, especially with edit-and-continue, but often it isn't. A breakpoint is a voltmeter, which you can use to see one value at every node in your circuit; logs are a digital storage oscilloscope with a spectrum analyzer, where you can analyze the history of millions or billions of values at a single node in your circuit. |
|
|
|
| ▲ | rbanffy 11 hours ago | parent | prev | next [-] |
| > and I remember telling them that Smalltalk programmers were paid more. Also much happier. C++ back then is not the C++ you use today. |
|
| ▲ | endlessvoid94 9 hours ago | parent | prev | next [-] |
| In 2013 I built a smalltalk-esque system browser using ruby and TCL. It was fun: https://www.youtube.com/watch?v=2xC5B5t5Rq8 |
|
| ▲ | jaymce 13 hours ago | parent | prev | next [-] |
| thank you for this great post. my nostalgia for the late 90's ParcPlace IDE is heavy. |
|
| ▲ | shevy-java 12 hours ago | parent | prev | next [-] |
| I kind of like Smalltalk. Unfortunately syntax-wise Smalltalk is a huge set back and step back compared to Ruby. But Alan Kay's ideas are still epic today. I still don't think any language came close to his vision either; smalltalk definitely not. Ruby got closer but also no dice. Elixir kind of got close too (prettier "erlang") - to have fault-tolerant mini-CPUs ("objects", aka similar to biological cells). The problem is that even people with grand ideas, such as Alan Kay, are not automatically great language designers. Matz is a better language designer than Alan Kay, for instance, whereas Alan Kay has the better ideas. It's a trade-off. Note: I myself would not know how a language should look like that would follow Alan Kay's vision closer. It is definitely not smalltalk; it is also not ruby, though ruby is very good. I know I would suck as language designer, but as an improvement I would have a language similar to ruby (no, not crystal - crystal is a worse "ruby"), with a stronger focus on speed (perhaps have a second language that can be as fast as C here and be similar) and with a much stronger focus on what erlang brought to the table; that would get us close to, say, around 85% or 90%. And then add the rest that could fulfil Alan Kay's vision. Of course we need a specification too, because just saying "90% of his vision" is also pointless. I would perhaps start from erlang, retain the good bits, make it a modern variant of OOP (and OOP is also defined differently in different programming languages, so we need to define that term too, in the specification). |
| |
| ▲ | NetMageSCW 7 hours ago | parent [-] | | How is the syntax a step back? Smalltalk is the ultimate orthogonal language - everything is consistent. Famously the Smalltalk grammar fits on a postcard and tells you everything you need to know to understand the system from the source code. | | |
| ▲ | travisgriggs 27 minutes ago | parent [-] | | Yeah, I have no idea what shevy-java is talking about either. I would accept “huge step too far”, but not backwards. Unless your belief is that on the 8th day God gave mankind Algol syntax and said “let all languages look like this”. I’ll give that it can feel pretty foreign, like forth, lisp, erlang also do. These languages, imo, all use syntax where the form of the syntax binds nicely, reinforces even, with their computation models. |
|
|
|
| ▲ | bowsamic 10 hours ago | parent | prev | next [-] |
| I always found it too fragile. There’s a reason why smalltalk VMs have such good recovery features, it’s incredibly easy to brick your system when it’s all a network of objects, and I’m sure anyone who has worked in smalltalk has done so many times |
| |
| ▲ | shwaj 8 hours ago | parent | next [-] | | I used to find it amusing that you could say `Smalltalk := nil` in the early days of Squeak, and poof! all the classes in your system are garbage collected. (I’m not sure that’s exactly what happened, probably the system crashed before garbage collection could happen. But it was definitely a guaranteed insta-crash). | |
| ▲ | igouy 8 hours ago | parent | prev [-] | | How can it be fragile if there are "such good recovery features"? Just restore unsaved changes when you launch the same image again. That's robust not fragile. https://drcuis.github.io/TheCuisBook/The-Change-Log.html |
|
|
| ▲ | behnamoh 14 hours ago | parent | prev [-] |
| Rants like this about languages which have little/no code snippets are the worst because they often sell you an idea w/o actually showing how it works in practice (because often times it doesn't work well in practice). talk is cheap, show me the fucking code, else don't waste my time. |
| |
| ▲ | Jtsummers 13 hours ago | parent | next [-] | | > Rants like this What about this makes you think it's a rant? Is the author making an impassioned plea for people to use Smalltalk? Is he going off on a tirade about something? | |
| ▲ | Philpax 13 hours ago | parent | prev | next [-] | | The post is about the conceptual underpinnings of the system, not about the specifics of the code. It would be like judging the Linux kernel by the UI running atop it: it's largely immaterial to the discussion at hand. | |
| ▲ | kragen 13 hours ago | parent | prev [-] | | This article is more about the development environment than it is about the programming language, so it would be misleading to focus heavily on example code. A UI screencast video would be much more helpful. |
|