The notion of the function point metric is explained in [1]: "the amount of business functionality an information system (as a product) provides to a user". The IFPUG report in the article explains it further and also mentions the inaccuracies across different variations of that metric [2].
As a Smalltalk programmer I certainly agree with having an increased productivity when programming in Smalltalk. But in my opinion this does depend less on the language and much more on the development environment. Having worked with multiple Smalltalk-like environments for JavaScript I can (anecdotally) report the same kind of productivity for programming in JS.
I think the right tooling around a PL influence productivity a lot, maybe even more than the language itself. Of course, certain tooling features depend on meta interfaces of the programming language and its runtime.
Hmm... Smalltalk isn't quite as productive as MUMPS. The numbers seem pretty suspect.
If the business functionality being provided is "deliver networked application to customer" then JavaScript would probably do well. If it's "create 3D rendering engine" then other language orderings are likely. How can you normalize the fact that different languages are appropriate for different domains? Do you have to come up with numbers that compare the business value of very different tasks.
>How can you normalize the fact that different languages are appropriate for different domains?
There's nothing that makes Javascript especially appropriate for web apps, except for the fact that it's bundled as the default and only language on web browsers.
So there's always that. Such accidents of history play more important role on what ecosystem and thus perceived suitability a language has, than the language's own merits.
Judged purely on language merits, Smalltalk would have made an excellent language for web apps and more over JS.
Take Smalltalk, throw away the image, or go over further and throw away the standard library (it's important that JavaScript never really had one), and what would you have? Take the database away from MUMPS and it's not even MUMPS.
Languages and runtimes can't be separated, because you can't just transplant a language to a different runtime and maintain the same experience.
>Take Smalltalk, throw away the image, or go over further and throw away the standard library (it's important that JavaScript never really had one), and what would you have?
Still a damn fine language.
That said, I don't think it's necessary to drop the standard library to make Smalltalk a web language, nor that it's "important that JavaScript never really had one".
It would have been much better if it came with a better "batteries" for all basic stuff (parsing urls, string manipulation, making requests, etc) from the start.
Ditto for the image -- one could very easily have web images, in fact that's part of what WASM would eventually achieve.
Function point analysis is best suited to line-of-business CRUD and batch processing applications with limited algorithmic complexity. Of course it can be applied to other domains but then the numbers get a lot more subjective and comparisons are less accurate.
There is a small but growing movement in PL academia to study programming experiences rather than just programming languages. Many of us are basically cyborg programmers these days, reliant on our tools and information resources for increased productivity.
Smalltalk has a meta API that is designed to allow introspection and modification of both static and dynamic code entities [1,2].
Static entities such as classes and methods (and depending on your Smalltalk implementation namespaces and object versions) can be modified at runtime, i.e. while your program is running you can make a change and get an immediate effect. This is now known as "live" programming, however, it is notably different from your typical "hot reload" implementation in that it knows how to apply changes for individual code entities. E.g. if you modify a method you don't need to reload the entire class or module or entire runtime. For me, this feature alone makes for a big productivity increase.
Dynamic entities such as stack frames can also be reified by the meta interface. This allows to inspect and modify runtime processes, e.g. inside a "debugger" [3]. Note that the debugger allows to modify and create new code while your are debugging. This is a powerful feature because it means that you get access to runtime objects inside of it. Ever wondered what object gets passed into your method at a certain point, what methods it knows, what properties it has? Just try it out and see for yourself!
An interesting analogy to describe this experience: [4].
For a deeper description about the ideas behind that see Design Principles Behind Smalltalk [5].
Also, most Lisp implementations provide the same kind of meta interface, and CLOS arguably provides a more flexible and higher level abstraction of these ideas [6].
As for similar environments I have worked on, there is Lively for JavaScript [7] and cloxp for Clojure [8]
These points about modifying things at run time are important, and not all Smalltalk programmers do this nor even understand it, simply using it as another language and writing something like C in it.
Another thing you can do that isn't explicitly mentioned above is "dropToFrame" where you can point to any one of the calling methods out of the call stack and have the process revert to a state so it is like it only just entered that method. I occasionally have debugged bugs that only surfaced rarely simply by having a tester call me when the problem manifests, and I spent a few hours with that function call live, repeatedly taking runs through to see what happened then reverting to a state where the problem was about to manifest but not so early that everything was lost.
You can also write debugging code of arbitrary complexity. You could write a 20-line query to do consistency checking of some data structure that is being operated on to satisfy yourself of various things you assume are true. You can make a special debugging subclass of some ubiquitous class, tell one particular instance of the class to become of the subclasses type which will then do all sorts of extra bookkeeping (perhaps recording stack frames every time it is invoked to see who asks it to do things).
You can execute a windowUnderMouse call to get an inspector on whatever widget is under your mouse pointer to make sure that the button you are looking at is in fact the one you think you are looking at. I used this to find a problem once where someone had subclassed some complicated window to add some functionality, and one of the buttons didn't work any more: turned out they were creating the same button again in the subclass constructor, which was overlaying the original's button (the one with all the event handlers).
I think some of this stuff might be more common in other languages now, but it wasn't in the mid-nineties. I know Java had a limited version of drop-to-frame a number of years ago, but it had some pretty cramping restrictions.
>These points about modifying things at run time are important, and not all Smalltalk programmers do this nor even understand it, simply using it as another language and writing something like C in it.
I don't think that's the case.
For one, the design and semantics of the language and overall environment force you to understand this and leverage those kind of features.
Second, Smalltalk being a niche language, it attracts programmers for its particularities and overall merits, and those are more likely to know and leverage those things than not. It's not like random corporate programmers are told to use Smalltalk and they use it like a C or Java. It's programmers who have sought after Smalltalk against the current trends that are using it today, and those know very well what it is.
I'm actually speaking from experience here. I used Smalltalk during the resurgence of the mid-nineties, and I programmed professionally in it at two different companies. The first was where I learned the language, and it was staffed by the type of programmer that did not really understand the interactivity of the system. They really did write a lot of stuff that looked like C, translated into Smalltalk syntax. Not completely, there were some objects, but they did not really get it.
I had to learn the interactivity stuff from people at the other company, which was staffed by people who'd been Smalltalk programmers for quite a while, and also people who had experience with other dynamic languages, particularly Common Lisp. That was where I really learned how to do the interactive stuff I mentioned above.
You might consider Smalltalk niche now, but in the short period of time before Java came around, it looked like Smalltalk was the future of enterprise computing. That is the period I am specifically talking about.
Yes, the reified execution stuff is so powerful and fun. You can take a "process", turn it into an object, inspect it, copy it, save it, resume it later, ship it to other VMs and run it there and so on and forth.
> "if you modify a method you don't need to reload the entire class or module or entire runtime. For me, this feature alone makes for a big productivity increase."
Would you expand on this? From a theoretical standpoint I can see how reloading only a single method could be more performant (and therefore more productive) than reloading an entire class or module. From a practical standpoint, if reloading a method ends up reloading a class or module to effect the reload, is there a noticeable difference or improvement? Or am I just misunderstanding?
(I happened to have spent part of day looking at cloxp and lively. Nice to come across you here as well. Nice work!)
In Smalltalk reloading a modified method will not reload a class or module to effect the reload. This is fundamental to the way Smalltalk works: a modified method cannot alter the way anything outside the method is defined. Note that Smalltalk has no notion of anything like inlining or anything like that.
I think that what the OP must have meant about this was that you can update a method without interfering with the program's current state, so while at a breakpoint say, you can fix a minor bug or perhaps add some debugging code or whatever, then resume, and all subsequent invocations of that method will use the new definition.
Hot code replacement (smalltalk’s fix and continue) is available on many platforms these days (Java since forever, MS C# and C++ for awhile though it was broken for a few years). It is strange that most JavaScript dev environments lack this.
The people that originally brought hot code replace to Java were smalltalk people (well, strongtalk, but same diff). Yes, it was never meta reflective as smalltalk, but it was useful enough. It still wasn’t as nice as full on live programming since the replacement was never retroactive (as it wasn’t in smalltalk either). We’ve definitely moved on since then.
> Static entities such as classes and methods (and depending on your Smalltalk implementation namespaces and object versions) can be modified at runtime
You are right, my usage of the term static does not go back to a well defined notion, I used it for brevity. What I meant is to make a distinction between entities describing the (runtime) system's state (classes, methods) vs. the entities used in the system's execution (stack frames, message sends).
Then again it's not static. In programming language semantics, there is a distinction between “static semantics” (e.g., lexical scope, type checking) and “dynamic semantics” (execution). Not having a static semantics (or, rather, having a trivial one) is fine, but it doesn't suddenly allow you to call parts of the dynamic semantics “static”.
What's with kids again not knowing basic computer science?
- Indium adds JavaScript tooling support and runtime interaction to Emacs and brings a few Smalltalk features such as object inspection (the project creator and maintainer is a Smalltalker and author of Amber): https://github.com/NicolasPetton/indium
- Lively provides a Smalltalk-like environment (code browsing, editing) as well as object(-graph) persistence, similar to the Smalltalk image idea, and mixes in some ideas from Self: http://lively-next.org/
Here's a video for you :) https://www.youtube.com/watch?v=9mrBH_a0eIs A (very super duper early and hoping to be) Smalltalk-like env for a JS runtime for touch interfaces (currently React Native + Expo) -- already has prototype of a windowing system and an AST renderer (+ basic editing, working on adding more) editor with live eval.
As a Smalltalk programmer I certainly agree with having an increased productivity when programming in Smalltalk. But in my opinion this does depend less on the language and much more on the development environment. Having worked with multiple Smalltalk-like environments for JavaScript I can (anecdotally) report the same kind of productivity for programming in JS.
I think the right tooling around a PL influence productivity a lot, maybe even more than the language itself. Of course, certain tooling features depend on meta interfaces of the programming language and its runtime.
[1] https://en.wikipedia.org/wiki/Function_point
[2] page 9, http://www.ifpug.org/wp-content/uploads/2017/04/IYSM.-Thirty...