Stefan has brought up a very good point. There is ...
# thinking-together
e
Stefan has brought up a very good point. There is some great older work that has been ignored almost completely, and the work for example by Prof. Wirth who worked not on objects but on improving data structuring power, in MOdula-2 and Oberon has been ignored. And when you bring it up, its age automatically disqualifies it. Even though for example, the module system of Modula-2 which allowed separate compilation without reprocessing header files is years (if not decades) ahead of what C++ promises.
d
I'm looking for an alternative to the overwhelming complexity of modern programming languages. How simple can a language be while still remaining viable, and how do we make languages easier to use? Some of my inspiration comes from research of the 1960's and '70s, before everyone was infected by the OOP virus. (The OOP fad led to a big increase in language complexity.) You mention Wirth: his Euler language is largely forgotten, but is simpler and more powerful than Pascal, which focussed more on efficiency.
k
@Doug Moen What makes you think that OO was a major cause of the explosion of complexity? I tend to see the two phenomena as simultaneous but not causally related.
g
I wrote apps in Modula-2. What is special about Modula-2 modules vs Java or C# or any other modern language that doesn't use header files? C++ has different goals IMO than many other languages which is one reason I value it. One of its goals is to generate optimal code. You can write very complex type safe classes with lots of methods and know that even though they've been specialized via templates and even though they're using all kinds of other classes as helpers the code they generate when optimization is on is 1 or 2 instructions. I don't know which other languages can make guarantees like that. AFAIK Java, C#, Swift, Modula-2 etc can not. The only way to do that that I know of is either to use header files (or precompiled header files) since you need tons of knowledge at the time of code generation to do it, OR, put tons of code generation logic in the linker since it would be the only other place that kind of optimization would have access to enough knowledge to be able to do similar optimizations. If you don't care about perf to that level suddenly you're open to a whole lot of other solutions. When I'm doing game dev or OS dev or driver dev I do care about that level of perf. When I'm doing app dev or web dev or server dev usually don't
d
Header files are widely recognized as creating a lot of problems. That's why C++20 will have modules. Read more about the problems with header files: https://clang.llvm.org/docs/Modules.html#problems-with-the-current-model
e
Modula2 was unique in that it used 2 different files for each module: one was the definition file, which is the exported to the outside world functions, types, constants, variables that are exported from a module, could be compiled, which emitted a .MSYM file, which could then be used by some other programmer who is going to use that module, without having access to the source code. And as long as the definition part didn't change, you could rebuild a huge program without recompiling the headers. It meant that someone could promise an interface, and as long as those promises didn't change the clients could be unconcerned with the internal workings. It doesn't pay off until you make a huge program, but as you know the N-squared aspect of programming complexity is present, and large Modula-2 programs were typically half of the the equivalent C program (and faster too, with many times lower nesting levels than Java programs). In Oberon he abandoned the practice of having a second separate file which did mean extra typing. But it did make compilation speedy, as you typically only change 1% of a program, and without any fancy incremental compilation features in the compiler (which can have errors) meant that compilation speeds were incredible compared to large C programs. I built some humongous products with it, like IBM DisplayWrite 5 Composer, Flying Colors, and Discus labeler, worked well on WIndows and Mac platforms. But again the module feature was just one aspect of Modula-2 that was great; it also had a much clearer definition syntax for a pointer to an array of functions that return a function that returns an integer. Try doing that in C, it is a mind-bender, while in Modula-2 it was clean and clear. The larger the program, the better Modula-2 looks, as its simplicity was born of clean logic. All of Wirth's work is elegant and very mathematical in its foundations.
g
Hmmm, I shipped an app in Modula-2. I didn't notice the code was any smaller than what I was used to before. Maybe I was using it wrong.
As for C++ modules vs headers I get it. Header files and the preprocessor have their place though. Without them you'll end up having to write code generators to solve certain kinds of common problems. One example is using macro lists to generate enums, strings for those enums, dispatch tables to handlers for those enums, etc.. In most "modern" languages like C# or Java or Swift it's just assumed you're going to waste memory having code generate data at init time. In C++ it's entirely possible to get much of your data generated at compile time and just loaded at runtime. Those kinds of issues might not matter on my 16gig mac but they matter quite a bit on smaller devices.