Code Craft Code Craft
 
 
 

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.]

20 Responses to “Freedom languages”

  1. Code Craft » Blog Archive » Free but not rigorous Says:

    […] 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 […]

  2. Ajaxian » Prototype Sucks 2.0 Says:

    […] “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) […]

  3. Matisse Enzer Says:

    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 :-)

  4. inou blog » Blog Archive » (umiera (studiował LISP (całą noc))) Says:

    […] 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ł. […]

  5. Prototype Sucks 2.0 Says:

    […] “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) […]

  6. Zickzack Says:

    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?

  7. Kevin Barnes Says:

    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.

  8. Benjamin Collins Says:

    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.

  9. Code Craft » Why my “REAL programmers” article sucked Says:

    […] Freedom languages […]

  10. Julian Morrison Says:

    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.

  11. Miles Gould Says:

    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.

  12. Dave Bayer Says:

    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.

  13. squarism.com » Freedom Systems vs Safety Systems Says:

    […] 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. […]

  14. milkfilk Says:

    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

  15. Harish Prabhu Says:

    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++.

  16. Code Craft » Blog Archive » Freedom languages Says:

    […] http://codecraft.info/index.php/archives/20/ Tags: programming, languages, philosophy, perl, ruby, python(del.icio.us history) […]

  17. Reklama internetowa Says:

    Great article Kevin. Gives another way of looking at languages and systems in general. I have increased my knowledge.

  18. yellowpages Says:

    Thanks for sharing this information with us.

  19. Hip Hop Klamotten Says:

    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.

  20. raffyman Says:

    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.

Leave a Reply