Discussion:
The two ways to keep a language lean
(too old to reply)
trijezdci
2015-10-25 19:59:21 UTC
Permalink
Raw Message
I'd like to talk about two approaches how to keep a language lean so as to make it easier to understand the rationale behind design choices in our Modula-2 revision.

It needs no reminder that Wirthian languages are all about simplicity, or shall we call it leanness.

Yet even Wirthian languages have grown over time, some have outgrown their simplicity moniker.

How did this happen?

There is a proverb that sums this up rather well:

"When the cat's away, the mice will play."

It seems that sustained simplicity occurs only for as long as there is a champion, a grey eminence watching over the language and remind its practitioners to stay faithful to simplicity as the be-all and end-all. Once the champion no longer watches over it, the language starts growing. At least such was and is the case with Wirthian languages.

There are other examples though: Forth, Scheme, Smalltalk.

Even in the absence of the grey eminence, they didn't grow, at least not by any significant measure.

So, what's the magic sauce?

The reason these languages don't grow is that they don't need to. They are extensible in such a way that any user defined object will behave as if it had been made part of the language itself. This is the magic sauce.

The Wirthian approach, preaching simplicity as be-all and end-all and hope that people will stick to it even after one isn't watching anymore does not have a good track record. All of Wirth's languages started and continued to gain weight without supervision of the grey eminence.

Before this background we asked ourselves "Who is going to be the diet enforcer when we are no longer around?". Let's be honest, the Wirthian approach to sustained leanness is not a winning strategy.


We therefore decided it was time to try a different approach for our Modula-2 revision. The kind of approach that worked for Forth, Scheme and Smalltalk: Extensibility via first class user defined objects.

With languages such as Forth, Scheme and Smalltalk, this was much easier to achieve because there is not much syntax for user defined objects to "learn" to mimic. The downside with Forth and Scheme is that the languages are lesser readable. Smalltalk is just as extensible and very readable but more complex than Forth and Scheme.

There is a trade-off. Simplicity, readability and extensibility need to be balanced. You can't get the maximum for all three. In the case of Forth and Scheme, simplicity and extensibility are at maximum, readability is not. In the case of Smalltalk, extensibility and arguably readability are at maximum, but simplicity is not. This doesn't mean the language is complex. It is still a lean language, just not as lean as Forth and Scheme.

For our revision of Modula-2 we thus had to balance these three variables. We chose the same trade-off as Smalltalk: maximise readability and extensibility at the expense of simplicity. Again, it does not mean that our revised Modula-2 is complex. It is still a lean language, just not as lean as it could be had we not aimed for flexibility that is designed to ensure sustained leanness.

In order to accommodate first class user defined ADTs and do so in a safe and consistent way which also discourages abuse, we had to add certain features. However, we also removed certain features, most importantly local modules which cuts quite a bit of weight. As a result of having first class user defined ADTs we could then afford to reduce certain features and move others into libraries, thereby recovering at least part of the initial investment in added complexity.

These things are difficult to quantify, but overall, the complexity of our revision is roughly comparable to that of PIM4, depending on how heavy the impact counts that local modules have on complexity of implementation. The reduction in complexity from removal of local modules may or may not make up for the increase of other changes, but if there is a difference, it is relatively small. Our design is certainly leaner than ISO Modula-2.


In some of the discussions in this group some people have expressed concern about some limitations or reductions of built-in types or types declared with built-in type constructors. However, it is the philosophy of the dialect to let you roll your own custom data type and use it just as if it was built-in.

The most important use cases are covered with built-in (think pre-fabricated) facilities. Other use cases can easily be satisfied with library built facilities (think custom made) and it won't look nor feel any different.

I read there are science fiction novels that describe so called maker machines or makerbots. These are described as machines that make objects on demand. You ask for a cappuccino, and it makes a cappuccino, but it can also make a wiener schnitzel or sushi, whatever. Needless to say, there is no longer any cappuccino button on the front panel like there was on your contemporary coffee machine. You'd couldn't possibly put everything the machine does on that panel, so you don't. It's probably got some kind of brainwave interface or so I would guess.

Although it doesn't make cappuccino, nor wiener schnitzel nor sushi, M2 R10 is not dissimilar. You can let it generate libraries on demand that do things that your built-in type constructors in classic Modula-2 never could. You can build new recipes for generating even more libraries on demand that do even more things. Or you can write your libraries yourself and let them do more things. But all of that is now library. As a consequence, built-in facilities no longer need to cover as much ground. The front panel is much smaller. In turn, nobody will come along and suggest to put yet another button on the front panel. You no longer need those buttons.
Chris Burrows
2015-10-26 10:04:18 UTC
Permalink
Raw Message
Post by trijezdci
the language starts growing. At least such was and is the case with Wirthian languages.
You have missed the point. There is nothing wrong with extending a lean language like Oberon for different purposes (e.g. additional Object-Oriented features OR vector processing OR component frameworks etc. etc.). The time when problems occur is when an implementer omits an original feature, or even worse, changes it. i.e. supersets of the base language are OK, subsets are not.

The more a programmer restricts themselves to the base features then the easier it is to port a system to other platforms. By adopting this principle, we regularly switch code from Oberon to Oberon-2 and Component Pascal on ARM-based, FPGA-based and Windows-based platforms with minimal effort.

However, if a programmer is not interested in portability but wants to exploit the characteristics of his chosen platform then he is free to use any available platform- or application-specific extensions.

On the other hand, implementers of obese languages are more tempted (or forced) to drop features than add them as they struggle to get a working reliable system going. The consequence is that the developer using those languages has no idea what features he can rely on.

If, as it appears, you have a wish to maintain some sort of control over the growth of the language you might be able to have the best of both worlds. You could specify a genuinely lean core language (e.g. a subset of original Modula-2) that would be easily implementable on all possible platforms and then specify a number of optional language extensions to be implemented when useful and feasible.

Regards,
Chris Burrows

CFB Software
http://www.astrobe.com
http://www.cfbsoftware.com/gpcp
trijezdci
2015-10-26 23:19:21 UTC
Permalink
Raw Message
Post by Chris Burrows
You have missed the point. There is nothing wrong with extending a lean language like Oberon for different purposes (e.g. additional Object-Oriented features OR vector processing OR component frameworks etc. etc.). The time when problems occur is when an implementer omits an original feature, or even worse, changes it. i.e. supersets of the base language are OK, subsets are not.
One word: Balkanisation.
Post by Chris Burrows
However, if a programmer is not interested in portability but wants to exploit the characteristics of his chosen platform then he is free to use any available platform- or application-specific extensions.
We are interested in both portability and extensibility. Having to choose between the two is not acceptable.
Post by Chris Burrows
On the other hand, implementers of obese languages are more tempted (or forced) to drop features than add them as they struggle to get a working reliable system going. The consequence is that the developer using those languages has no idea what features he can rely on.
I cannot say that I have witnessed such a thing. It is rather the opposite I see everywhere, everyone packs more and more stuff on top, even with large languages. The only time I saw a temporary subset was when Clang initially had missing C++ features while it was being implemented but already released along the way. Strictly speaking it was pre-release software, and as such missing features were to be expected until the proper release comes out.
Post by Chris Burrows
If, as it appears, you have a wish to maintain some sort of control over the growth of the language you might be able to have the best of both worlds. You could specify a genuinely lean core language (e.g. a subset of original Modula-2) that would be easily implementable on all possible platforms and then specify a number of optional language extensions to be implemented when useful and feasible.
We did both. The core is leaner than ISO M2 but extensible, and we have made provisions for domain specific supersets, for example we reserved certain identifiers / reserved words for Parallel Modula-2.
Loading...