The improved process is not in how it can emulate the way you've done things for decades with file-based tools. It's in the conceptual nature of programming, as well-explained by Bret Victor: https://youtu.be/8pTEmbeENF4
- Software development using files and folders is absolutely antediluvian. Smalltalk does everything in a universe of objects; source code is organized spatially rather than in long reams residing in text files.
- Live coding and debugging done right is an enormous and unparalleled productivity booster.
- Persisting execution state is extremely convenient for maintaining continuity, and hence the high velocity of development.
Governments and enterprises have long used Smalltalk to write massive applications in large team environments using Smalltalk's own tooling for collaboration and version control. There's no question that historically Smalltalk has not played well with the outside (file-based) world, and this has been a major point of contention.
If you insist on using Git and similar tools with Smalltalk, then yes, this is problematic. The point is, if you view software development from only one perspective, you deny any possibility of improving the process in other ways that can lead to dramatically improved productivity, accelerated development, and lowered cognitive stress.
Sorry, I am at work right now and don't have time to watch videos. Can you tell me more about "Smalltalk's own tooling for collaboration and version control"? Are you referring to Monticello? I am not insisting on git, but Monticello seems pretty limited in term of collaboration. I see commit, diff, checkout, and remote pull/push.
Specifically, let's imagine this scenario: we have team of tens of programmers working on a project. A new team member joins and accidentally breaks the code in non-obvious way. He pushes the code to main repository. Next time, everyone else checks out the latest version of the code and starts having weird problems. If you had 20 people on team, and they each wasted 2 hours because the code was broken, well, you just wasted a week of programmer time. How do you prevent it?
In file-based word, the answer is tests and CI. What is the smalltalk way? And please do not say "It's in the conceptual nature of programming" -- if the scenario makes no sense in the smalltalk world (maybe you are not supposed to have 20 people working on the same project?) please say this.
Pharo Smalltalk, in particular, when it comes to VCS, it's very similar to git actually. It uses source code files, it distributes them via zip files, it works locally instead of centralized, it supports merges, etc.
Pharo works well also with usual VCS because it can export code into source code files.
The image plays no role in VCS whatsoever because VCS is about code, not data, and image is mostly about live data and less about live code.
So any tool will and does work with Pharo outside the image. Problem arises with a majority of people that prefer to stay in the image; in that case you gain more control because you have more Pharo code to play with, but you lose a lot of power because we are a small community not able to compete with behemoth projects like git.
Another interesting thing which Pharo does emphasize is remote debugging: though not a Pharo monopoly by a long shot, we do have several libraries that can achieve this, and because the image format retains live state and live code execution, it's easy to resolve issues.
Besides the image format, the Fuel format has the advantage of storing only a fraction of the image. You can email this or share it via git or Dropbox. Like an image, a Fuel file is a binary file and, like the image, it can store live state and live code execution. This way, you can isolate live bugs and share them with your team, each one in its own Fuel file.
STON is also another alternative format which feels familiar for those that have worked with JSON.
So you see, you get the best of both worlds. You have the fantastic Smalltalk image, and you have ways to deal with the file-based world.
1. Breaking code is nothing specific to a language. The usual weapon also
in Smalltalk is to monitor if something breaks - for instance by using CI.
Continuous integration only makes real sense when you have tests.
One should remember that "test first", "unit testing" and "Extreme programming" (XP)
like many other things had their roots in Smalltalk. Because in dynamic
languages testing using code was and is part of the culture (ranging from lively verifying
with workspace expressions and inspectors up to fully written tests).
The first unit testing framework "SUnit" was written by Kent Beck for
Smalltalk (SUnit), later he ported it to Java with Erich Gamma on a flight
to OOPSLA OO conference. Java helped to push the popularity afterwards.
Meanwhile also static language enthusiasts have understood that it is better to
rely on tests than type checking compilers and they now hurry up to follow
what Smalltalk already had years ago.
One last thing you should try: try to query your system how many test methods were
written. When you solved this easily with a Smalltalk expression retry
this in Java ;)
2. Commercial Smalltalks which are often used in big projects provide solutions
which are repository based like the famous ENVY (written by OTI, was
in VisualAge for Smalltalk from IBM, now VAST) or Store (VisualWorks). For
more details try the commercial evaluation versions or read [1] or [2].
A screenshot of Envy can be seen in [3]. I worked with ENVY and it is really
good - but mostly only for internal work/teams. If I remember correctly
ENVY once was also available for VisualWorks (VW) ... but later got replaced
for business or license reasons. I'm not sure about that point.
Cincom developed Store for VW as a replacement which is also nice as it allows to work
in an occasionally-connected mode, so work offline and push packages/versions later to
a central team repo.
In the open source world there are different solutions (including Monticello
which is available for nearly all Smalltalk derivates) or newer solutions
like FileTree or Iceberg allowing to work with Git.
The workflow depends on the tool and your requirements.
3. Often it makes sense to automatically build and regular distribute a fresh daily
developer images to the members of your team. This helps in later merging
code.
For instance Kapital (a big financial project from JP Morgan) works that
way and I've seen that model very often. See [4]
Again nothing special to Smalltalk. In more file based languages it also makes
sense to stay close to the main line and merge as well as resynchronize with the
team.
In Pharo for instance we have the PharoLauncher that allows you to download
any (fresh or old) image built provided by the open source community.
3. Versioning can be done on many levels. Simplest level is the image itself.
Smalltalk not only has an VM and image concept - but also the concept of a changes
file. If you evaluate a code expression, create or modify a class or method
in the system this gets logged there.
It prevents you from loosing code and it is easy to restore quickly for instance
an earlier method versions/editions that one has implemented.
Most Smalltalks now also work with packages and you can define package
dependencies as well as declaring versions that fit together to provide
a project, goodie or app (for instance with a Configuration class in Monticello)
While in file based languages this is often done in an XML file (Maven for instance)
or a JSON file in Smalltalk this is usually expressed with objects and classes again.
This also makes it more flexible as you can very easily do queries on it or
use refactoring tools to even restructure or reconfigure.
4. Usage of shared code repositories is very common also in Smalltalk. While you
now can also use GitHub, GitLab, Gogs and others with Iceberg and friends in Smalltalk
there are also repository systems implemented in Smalltalk itself like
- SqueakSource (http://source.squeak.org, http://squeaksource.com)
- SqueakSource3 (http://ss3.gemtalksystems.com)
- SmalltalkHub (http://smalltalkhub.com)
5. Beside repositories where code and goodies are hosted one often finds registries
with infos about loadable components.
Pharo for instance has http://catalog.pharo.org which is accessible also
directly from the image.
5. If you work in a team you can also use a custom update stream. This is how
for instance open source projects like Pharo and Squeak are managed.
So anyone can hit an "update" button to get the latest changes.
In Pharo http://updates.pharo.org is used and you can have a look at UpdateStreamer
class to see how easy that works over the web or how to customize it for own needs.
7. If one requires not only collaboration for the development team (coding) but
would like to collaborate also with other projects members on other artefacts
(Excel, project plans, documents, ...) then one should have a look at tools like this
http://www.3dicc.com
which is implemented in - guess what: SMALLTALK.
This list could be endless ... the first few points should only give a glimpse on
what is there and available.
Monticello is Smalltalk's most common source code versioning system. It was developed several years ago and implemented in several Smalltalk dialects. Monticello lets you commit a new version, update to a new one, merge, diff, revert, etc. This is also how you can share code.
Managing large complex applications is always a major pain. There is no shortcut, no ideal solution. For all of its imperfections, class-based OOP is the best tool we have today to aid in this onerous task.
The popularity of class-based OOP is undeniable. People understand that there is no perfect solution. What would you use in its stead?
Well, OOP abstracts data, but to do it mutates many shared states across many functions, causing side-effects, breaking context of mutations, forcing to think about unpredictable order of mutations, etc., which leads to a tremendous amount of accidental complexity, hard to understand and hard to test code.
There is an inverse approach, that abstracts state mutations instead of data itself. Which means no more shared mutations, no more side-effects, no more breaking context of mutations, no more uncontrolled mutations, everything is in exact order it is supposed to be used, everything is easy to understand and easy to cover with tests, etc. And it's just as flexible in Javascript, since it supports higher-order programming, but doesn't lead to nearly as much accidental complexity. However, it's not popular and not taught at schools, like OOP.
Excellent piece! The author makes a number of strong points about software engineering. I looked at some of his other articles at JavaScript Non Grata, and he consistently recommends using transpiled languages instead of JS, at least on the front end. On the back end, there are many solid alternatives to JS. (Unless you really, really want to use Node.js.)
- Software development using files and folders is absolutely antediluvian. Smalltalk does everything in a universe of objects; source code is organized spatially rather than in long reams residing in text files.
- Live coding and debugging done right is an enormous and unparalleled productivity booster.
- Persisting execution state is extremely convenient for maintaining continuity, and hence the high velocity of development.
Governments and enterprises have long used Smalltalk to write massive applications in large team environments using Smalltalk's own tooling for collaboration and version control. There's no question that historically Smalltalk has not played well with the outside (file-based) world, and this has been a major point of contention.
If you insist on using Git and similar tools with Smalltalk, then yes, this is problematic. The point is, if you view software development from only one perspective, you deny any possibility of improving the process in other ways that can lead to dramatically improved productivity, accelerated development, and lowered cognitive stress.