On Friday, 8 July 2016 at 21:24:04 UTC, Walter Bright wrote:
All useful computer languages are unprincipled and complex due to a number of factors:

1. the underlying computer is unprincipled and complex (well known issues with integer and floating point arithmetic)

2. what programmers perceive as logical and intuitive is often neither logical nor intuitive to a computer (even Haskell has wackadoodle features to cater to illogical programmers)

3. what the language needs to do changes over time - the programming world is hardly static

4. new features tend to be added as adaptations of existing features (much like how evolution works)

5. new features have to be worked in without excessively breaking legacy compatibility

6. no language is conceived of as a whole and then implemented

7. the language designers are idiots and make mistakes


Of course, we try to minimize (7), but 1..6 are inevitable.

Letting consequences of those just happen is like a being a sailor and happily going the wrong way when the wind is not perfect. There are techniques both from the project management point of view and from language design point of view that can be applied to minimize and prevent those effects and aren't applied.

So, some examples:

About 6, 3 and 4. There's a thing called the MVP (minimal viable product) approach. You implement the minimally useful bare bones and leave as much wiggle room as possible for future changes. This doesn't need to be applied to the whole language, it can be applied per feature as well. Yes, you can't predict the future, that's not an excuse for not preparing for it and for possible change. When you're happy with the MVP you can accept it and do more experimentation with the knowledge you got from doing the MVP. See also: agile methodologies.

About 2 and 7. Some positive changes happen here, still listing possible solutions won't hurt. Have more peer review. Release more often, so people won't be bothered if their feature won't make it (it's weird that Andrei worked at facebook, yet he doesn't push for faster, less feature heavy releases). Release new features under feature gates (like -dip25 and std.experimetal), don't stabilize until people provide feedback and are happy with the result (yes there's an issue with people not testing the feature because of small D adoption - don't include the feature for it's own sake if people can't be bothered to test it). We're all idiots - so we need to experiment before we commit to something.

About 4 and 5. Those are partially combated by the MVP approach mentioned earlier- leaving as much as possible flexibility for as long as possible, so you can make decisions when you have the most information(i.e. as late as possible).

Another way to combat this is to build language from independent parts that can be composed together. As an example of this done right: concrete code, templating mechanisms and conditional compilation are all independent parts of the language that can be put together, so the effective number of features is a cross product of those 3. Deadalnix gave some examples of that done wrong in this thread - as he's implementing a D compiler from scratch he can see the unorthogonal parts easily. SDC is probably worth looking into. With independent features it's much easier to keep the feature set adaptable.

Another language design trick is to look at the whole language and try to hit as many birds as possible with as few (but not too few) stones as possible. There are numerous cases of problems being solved using different means each time a problem comes up. Look for a way to merge these categories of solutions into something coherent and deprecate the old mess. You don't have to drop the old ways, but new users will be glad to have a simpler model to learn, as old "special" solutions can be defined in terms of the new one. Do you really need pragmas, special variables and special constants when you could have nice namespaced intrinsics modules defined with existing and understood language rules? Do you need alias this when you could have opImplicitCast returning ref?

I didn't just make those up, there are languages which do all of those and more and they work within the same domain as D.

Reply via email to