Freedom languages
(August 23rd, 2005)
I’ve never met a coding God who didn’t know at least one “freedom language” that they thought was great. Many know several. Some refuse to program in anything else.
What, pray tell, is a “freedom language”? Freedom languages are those languages that put the individual programmer at the center of their philosophical world. They work hard to remove any language constructs that reduce programmer freedom, and add the most powerful constructs available. Many are post-modern languages and most tend to be syntactically dense.
The other kind of language is the “safety language.” Safety languages think first about the creation of contracts between modules, objects and functions. They focus on teams rather than individuals. They remove language features that are confusing or frequently misused so that there are fewer opportunities to make mistakes and so there can be clear separation of concerns and maximum verifiability. These languages are full of barriers and check-points and well-defined paths and they tend to be syntactically verbose.
Right now the “hottest” new freedom language is Ruby with Python second, but the most heavily used freedom language is Perl with Smalltalk second (my estimates, no science involved). The popular safety languages are C++, Java, C#, VB and Delphi. These collectively dominate modern programming. Other less popular safety languages include Haskell and Nice.
Can’t we all just get along?
I picked the terms freedom and safety because they represent a philosophical split that I’m not sure some of the advocates of these languages realize is present. You can sense this split when you listen to the words that the various pundits use when discussing the merits of different languages.
The advocates to safety languages tend to deride freedom languages as “scripting” languages or “fringe” languages. They are only fit for hacking out small projects and putting together demos and whatnot. They focus on static-type-safety as one of the most fundamentally critical elements for ensuring program completeness. They may also talk about execution efficiency (memory, speed, etc). They tend to view freedom languages as improper for a larger team of programmers with mixed skill sets. The heart of their arguments is basically that these languages are not “safe” for large projects.
The advocates of freedom languages tend to talk first about the speed and efficiency of the individual programmer. They discuss the expressive power of different constructs and focus on all the powerful features that the safety languages lack. They point out complex patterns and show off twenty-line systems that do the same thing. They talk more about the ease or purity of things than the safety of things. They are dismissive of static-type-safety and compile-time validation in general.
Tell me when I break it
The preeminent dividing issue is the dreaded “strongly-typed” debate. For a long time almost all of the freedom languages were labeled as “weakly-typed” by the safety advocates. This is inaccurate technically. Most tend to be dynamically-typed, but for many people this is a distinction without a difference. The safety advocate wants the “compiler” to tell him that function X wants an int but function Y is passing it a string. None of the freedom languages do this.
This seemingly simple request (static-typing) is, of course, impossible to achieve 100% of the time, and the closer you get to achieving it the more energy you waste. It has a logarithmic complexity curve. Casting is largely a tacit acknowledge of this complexity.
A language that is completely statically typed is also limited in what features it can implement. Features like an “eval” statement, or dynamic function replacement, or a host of dynamic polymorphic behaviors become nearly impossible. Many templating and function-passing features also become extremely cumbersome in statically-typed languages. As a result safety languages have eschewed a wide variety of very powerful features as being unsafe or overly hard to use (and hence unnecessary).
Const-ness and checked exceptions (which have natural appeal in a safety language) have similar qualities. Creating systems that manage them with strong guarantees also creates systems that are difficult to use. In C++, the const qualifier has resulted in massive duplication of methods and increased use of templates. In Java, checked exceptions have lead to the worst excesses of code bloat.
Freedom languages have decided that the value of static-type-safety (and static-const-ness and checked exceptions) aren’t worth the cost (in missing power and flexibility) and abandoned these notions altogether.
Protect me from myself
Another place that the difference in philosophy has impacted implementation is in what you are allowed to change. Safety languages tend to restrict what kinds of components can be extended or altered. Freedom languages do not. Smalltalk is, in many ways, the ultimate example of this:
“Where does the user code end and the system code begin?” asks the novice.
“There is only code”, answers the master.
“But how then shall I know what is mine?” continues the novice.
“There is no me and there is no they”, is the reply.
In Java, on the other hand, it is not possible to extend the Integer or String classes (they are final). In Ruby not only can you extend them it is possible to change the behavior of the parent class itself. It is open for extension and (in a sense) modification!
This is no small matter. If you can’t extend things, replace factory methods, or do other ‘dangerous’ things then you are forced to use some pretty fishy workarounds. This is especially true for testing (which is ironic). In C# or Java, you may find yourself turning unnecessarily to dependency injection because you have no other way to replace a behavior with a mock behavior in a test. In Ruby or Perl you probably won’t (which will let you use your constructor parameters for setting the state of the object and not the state of its environment).
Me too
There is one other strange quality to the safety languages. They all look the same. The safety ideal has manifested itself in even the simplest elements of syntax. The providers of safety languages want constructs and syntax that will be comfortable to people who write code in other “major” languages. They want companies to be safe from an inadequately small developer pool. Many languages that started out looking different (Basic or Pascal) have over time morphed to take on the look and feel of the other safety languages. It’s very easy for someone familiar with C++ to read C# or Java or VB or Delphi>. They have a lot harder time figuring out Ruby or Smalltalk or Python. Think I’m exaggerating?
What language is this snippet from?
int calculate(int count, int value) {
int i;
for (i = 0; i < count; i = i + 1) {
value = value + value;
}
return value;
}
How about this one?
def calculate(count, value)
count.times do
value += value
end
value
end
If you can’t tell which language the first snippet comes from, it’s legal syntax in (at least) six safety languages. The second example is Ruby.
Writers of freedom languages are, by their very nature, iconoclastic (sometimes to an annoying degree). In these languages there is no fear about changing an element of syntax that might be common in other languages. Throw and Catch in Ruby, for example, have a much different meaning than in most other languages.
Safety isn’t safe and freedom isn’t free
Both sets of languages are making tradeoffs about what they view as the most important features of a language. The freedom languages are choosing powerful feature sets and the safety languages favor clearer contracts and commonly readable syntax. These are choices about how best to achieve the goals of programming.
Unfortunately, the safety languages get very little of the safety they seek. In the end, anyone who is writing code can bypass the “security” features associated with making the String class final, and not having multiple inheritance hasn’t yet prevented anyone from writing bad class hierarchies.
Type-safety is likewise meaningless if the code subverts types in order to get around difficulties stemming from static-type-safety (an extremely common practice). I’ve probably seen a dozen database systems where the integer id values associated with the various “objects” are left as integers thereby subverting both compile time type safety and run time type safety. These coding practices are much more common in systems where there is a dividing line between values that are objects and values that are not.
Strangely, even the safety in numbers of having a huge base of knowledgeable language experts provides less safety than people believe it does. In practice the bulk of the learning that a new employee goes through (for large systems) is related to either the domain or the specifics of the code base. If the code base is massively bloated and complex, being the best C# expert in the world wont make any difference. The real expertise required when crafting code is much more about design than it is about syntax.
If safety isn’t safe, freedom isn’t free either. Languages like Smalltalk or Python do come with risks. People can do bizarre and “inspired” damage with any language. You will eventually face a hard to figure out dynamic-type issue, and someone will eventually modify a value that was “supposed” to be const. The price of freedom is eternal vigilance. You need to understand complexity and scale in the application and provide people tools to eliminate it. If your project is large you may need pair-programming, code review, extensive unit testing, and continuous refactoring.
Ring the bell for freedom
All other things being equal, I think I’ll choose freedom (if I have the choice). I can risk having to debug an occasional run time error if I can keep my class structures simple. I’m not afraid of confusing someone by strange use of iterators, and bandwagons are noisy and full of hay. The next time I have a large program to write I’ll take a closer look at the available freedom languages and pick the one that fits my needs the best. Maybe Ruby, Martin Fowler thinks it’s pretty hot
[P.S. I have added a meta discussion of this article here.]


March 1st, 2006 at 5:11 pm
[…] Warning: if you haven’t read my “Freedom languages” article this may not make much sense. Hmm, skipping forward it may not make much sense if you have. Perhaps I should have used MRML instead of HTML […]
December 29th, 2006 at 3:34 pm
[…] “it breaks the ‘for in’ loop” - no it doesn’t - you were probably using ‘for in’ where you shouldn’t have. Javascript is a flexible, powerful freedom language, and its okay if your framework uses that to the full extent. That means you and your development team need to be educated and aware of the ramifications of it if you want to play ball. The stuff that Prototype did to Object in earlier versions, btw, was a bit too much and has been removed in the latest versions. (related reading here) […]
December 31st, 2006 at 10:45 am
Thanks you. Great article. Gives another way of looking at languages and systems in general.
By the way, i am a long-time lover of Perl who recently seen just how bads things can be when the price of freedom is paid with “technical debt” - it’s turning me into a fascist advocate of safety
January 4th, 2007 at 6:35 pm
[…] Co dosyć dokładnie opisuje moje wrażenia związane z ewolucją AS i promocją pewnych w nim rozwiązań. Heh, kiedyś nawet rozmawiałem sobie z Bartkiem Goldynem na webesteem na temat poukładania nowych rzeczy w AS3.0 , gdzie stwierdziłem że nie podoba mi się to zmuszanie do pewnych ścisłych zachowań od strony języka (czyli dyskusja z serii typowanie statyczne vs dynamiczne i silne vs słabe - jakby ktoś pytał) Zdecydowanie wolę luźniejsze podejście, vide cytat. Wolę Freedom languages jak to ktoś ładnie nazwał. […]
January 9th, 2007 at 2:15 pm
[…] “it breaks the ‘for in’ loop” - no it doesn’t - you were probably using ‘for in’ where you shouldn’t have. Javascript is a flexible, powerful freedom language, and its okay if your framework uses that to the full extent. That means you and your development team need to be educated and aware of the ramifications of it if you want to play ball. The stuff that Prototype did to Object in earlier versions, btw, was a bit too much and has been removed in the latest versions. (related reading here) […]
January 26th, 2007 at 5:24 pm
I concur. However, it is quite similar to the distinction between Languages Designed For
Others and Languages Designed For Oneself (http://www.paulgraham.com/vanlfsp.html makes a
similar point).
Which brings me to the question, is OCaml (or Haskell) a freedom language or a bondage and
discipline^W^W^Wsafety language or both or neither? Or did I just lose my buddha nature?
February 3rd, 2007 at 12:40 am
This blog post dates back to my old site, so most of the comments are there, this came up a couple of times. Basically they are safety languages, but nowhere near the way java is (even though in practice they are much safer) since they offer a huge array of powerful feature and the only area the tie your hands is forcing you away from state and tightly enforced contracts.
Like any categorization, this on has its limits.
February 6th, 2007 at 7:51 pm
I agree that languages have different advantages and disadvantages - but what initially struck me in your article was your labeling of the “freedom” languages. I just thought it was bizarre, because in some of the languages you label as “safe” allow you to do things that none of your “freedom” languages do.
Don’t get me wrong; I like some of the “freedom” languages: LISP, Python, and Perl are all in my toolbox. I just thought your distinction between “free” and “safe” was weird.
March 13th, 2007 at 2:51 pm
[…] Freedom languages […]
March 15th, 2007 at 5:35 am
I’d say Haskell especially isn’t a “safety” language. It’s something else entirely - an exploration language. It’s not about taking features away, but rather, about giving you the ability to think in a mathematical way you can’t about ordinary languages. People literally don’t know how to program it yet. New ideas are being discovered all the time, and the better ones get baked into the standard. Firstly, Haskell’s types are there to give you those mathematical guarantees. Second, they’re a sanity check. When exploring the unknown, you need to be certain you’re actually doing what you think you are. And thirdly, types in Haskell allow you to explore the problem in a formal way. If you think you ought to be able to do something but you can’t get it to type-check, it often turns out there’s a good mathematical reason why not. Or conversely, if you can formulate an abstraction as a type, writing a valid implementation may actually have some practical use. Either way you’ve increased your knowledge.
March 30th, 2007 at 8:45 pm
Julian: I’m fairly new to Haskell, but I disagree completely, and in fact I’ve come to very similar conclusions as Kevin based on my differing experiences with Perl and Haskell. Haskell is a safety language par excellence; the polymorphic typing et al merely postpone the pain a little. Everywhere throughout the language and the community the attitude “You can’t do that! Bad Things might happen!” seems pervasive. I’ve written some more about this here. This may allow a greater degree of formalizability: that’s a separate question.
In fact, I’d say that Haskell (and presumably O’Caml) is interesting precisely because it’s a Language For Smart People that’s also a safety language.
March 31st, 2007 at 5:53 am
The debate here over Haskell confuses extensibility with type safety. Haskell is extremely extensible. In an involved project nearly all types are the invention of the programmer. Part of the coding effort involves designing types, but this information is used to generate significant quantities of code automatically; the type specification is a central part of the design, and not simply a seat belt that gets in one’s way. More generally, a good Haskell program looks like a specification for a program, that happens to run.
I love Ruby, but I’ve settled on Haskell for everything. I’m reminded of the first moon landing. Neil Armstrong was chosen because he’s not the kind of guy to abort. Good thing: As they landed, their computer displays were showing trig errors that were only intended for programmers to see in development, and this wigged everyone else out. Neil ignored the screen and landed the thing.
With Ruby’s duck typing, a program can fail to work in unexpected circumstances, years after it is written. If astronauts depended on duck typing, they’d end up in situations where they were seriously ducked.
April 24th, 2007 at 2:22 am
[…] Code Craft had an extremely intuitive post about Freedom Languages vs Safety Languages. He covered what is popular vs what is fringe, where the party-lines are drawn and (imo) almost made an analogy for safety within the USA. […]
April 24th, 2007 at 2:23 am
Enjoyed this. I made an attempt to relate your post to systems on my blog. I think this post is full of truth, following the concept of “In one thing, know all things”.
http://squarism.com/2007/04/23/freedom-systems-vs-safety-systems/
-milk
May 14th, 2007 at 6:55 pm
Nice article Kevin. But I reckon C++ is not exactly a “safety language”. There are more than
1001 ways to shoot yourself in the foot with C++.
June 10th, 2007 at 10:43 pm
[…] http://codecraft.info/index.php/archives/20/ Tags: programming, languages, philosophy, perl, ruby, python(del.icio.us history) […]
September 24th, 2007 at 5:38 pm
Great article Kevin. Gives another way of looking at languages and systems in general. I have increased my knowledge.
November 12th, 2007 at 12:03 am
Thanks for sharing this information with us.
November 27th, 2007 at 12:15 pm
People literally don’t know how to program it yet. New ideas are being discovered all the time, and the better ones get baked into the standard. Firstly, Haskell’s types are there to give you those mathematical guarantees. Second, they’re a sanity check. When exploring the unknown, you need to be certain you’re actually doing what you think you are. And thirdly, types in Haskell allow you to explore the problem in a formal way. If you think you ought to be able to do something but you can’t get it to type-check, it often turns out there’s a good mathematical reason why not.
February 5th, 2008 at 4:54 am
New ideas are being discovered all the time, and the better ones get baked into the standard. Firstly, Haskell’s types are there to give you those mathematical guarantees. Second, they’re a sanity check. When exploring the unknown, you need to be certain you’re actually doing what you think you are. And thirdly, types in Haskell allow you to explore the problem in a formal way. If you think you ought to be able to do something but you can’t get it to type-check, it often turns out there’s a good mathematical reason why not.