InfoQ

InfoQ

News

My Bookmarks

Login or Register to enable bookmarks for unlimited time.

The content has been bookmarked!

There was an error bookmarking this content! Please retry.

Andrej Bauer on Language Design

Posted by Jonathan Allen on Apr 15, 2009

Sections
Development,
Architecture & Design
Topics
.NET ,
Programming

Andrej Bauer starts essay, On programming language design, with a simple premise, “Programmers are just humans: forgetful, lazy, and make every mistake imaginable.”

Therefore, it is the task of the designer to make a programming language which counters these deficiencies. A language must not be too complex, lest the programmer forget half of it. A language must support the programmer’s laziness by providing lots of useful libraries, and by making it possible to express ideas directly and succinctly. The language must allow good organization of source code, otherwise the programmer will use the copy-paste method. The language must try really hard to catch programming mistakes, especially the mundane ones that happen to everyone all the time. When it finds a mistake, it must point to the true reason for it, preferably with an error message that humans understand.

The first section he applies this theory to is unknowns. He writes,

The principle tells us that it is a bad idea to allow invalid references because programmers will create them. Indeed, most recently designed languages, say Java and Python, do not allow you to write obviously risky things, such as

int *p = (int *)0xabcdef;

Unfortunately, many designers have still not learnt that the special NULL pointer or null object is an equally bad idea.

This is especially true in .NET programming. Not only does it have the same “null reference exception” that Java had, with generics we also were given the problems with Nullable value types. There is hope here with Code Contracts, but that technology is still far from being production ready.

After a discussion about strongly typed objects versus list-based data structures, Andrej moves on to definitions verses variables. He raises some interesting points on the issue that could be applied to .NET programming.

If you observe how variables are typically used, you will see several distinct uses:

  • often a variable is only assigned to once and is used as an (immutable) definition
  • a variable in a loop or list comprehension ranges over the elements of a list, or a collection of objects
  • a variable stores the current state and is genuinely mutable

Should loop counters be mutable? I think not. Code that changes the loop counter in the body of the loop is confusing and error prone. If you want to fiddle with counters, use the while loop instead. So in two out of three cases we want our variables to be immutable, but the popular programming languages only give us variables. That’s silly. We should design the language so that the default case is an immutable value. If the programmer wants a mutable value, he should say so explicitly.

Could this be done in C# or VB? Certainly, and it wouldn’t be hard either.

For assign-once variables, we can leverage the existing type inference. For C# you would write “def x = …” instead of “var x = …”. Or perhaps we could simply reuse the existing keyword “Const”. That would certainly fit with VB’s “do what I mean, not what I say” philosophy towards other issues like early vs. late binding. The important thing is that the keyword is short; if you use something long like “readonly”, developers will tend to avoid it.

The next one is even easier. One simply has to emit a compiler warning when a loop variable is being changed.

The final option, the one using legitimately mutable variables, should then become a rarity. Not entirely disallowed of course, but simply not used unless actually needed.

The other issues such as compile-time vs runtime checking and undefined identifiers don’t really apply to mainstream .NET programmers. But if you are looking to pick up IronPython or IronRuby, you would do well to familiarize yourself with some of the issues that arise from them.

All in all, Andrej Bauer’s On programming language design is a good introduction to the kinds of problems the next generation of programming languages should seek to address.

No comments

Watch Thread Reply

Educational Content

New-age Transactional Systems - Not Your Grandpa's OLTP

John Hugg discusses high volume transaction processing applications with high and low frequency profiles, and how VoltDB can be used for that purpose.

Cool Code

Kevlin Henney examines code samples to see what can be learned from them starting from the premise that one won’t write great code unless he knows how to read it.

Collaboration: At the Extremities of Extreme

Jason Ayers share the observations he made watching a team of developers collaborating in real time on the same code base, pushing XP, pair programming and continuous integration to their extremes.

Yesod Web Framework

Michael Snoyman presents Yesod, a web framework written in Haskell and containing a web server, templating, ORM, libraries (templating, gravatar, etc.).

Transactions without Transactions

Richard Kreuter and Kyle Banker on how to avoid classical RDBMS transactional systems by using compensation mechanisms, transactional messaging or transactional procedures.

Attila Szegedi on JVM and GC Performance Tuning at Twitter

Attila Szegedi talks about performance tuning Java and Scala programs at Twitter: how to approach GC problems, the importance of asynchronous I/O, when to use MySQL/Cassandra/Redis, and much more.

10 tips on how to prevent business value risk

One category of risk that project teams need to ensure they address is business value failure – delivering a product that fails to provide value for the business investor.

Interview: Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives

InfoQ spoke to the authors of Software Systems Architecture on a couple of new topics, the System Context viewpoint and Agile, which have been added to the second edition.