Thursday, December 27, 2007
  If you cannot change your language, change your language
You want to strive to make sure every single line of code has some value or meaning to the programmer. Programming languages are for humans, not machines. If you have code that looks like it doesn’t do anything useful, is hard to read, or seems tedious, then chances are good that Python has some language feature that will let you remove it.
—Ryan Tomayko, Getters/Setters/Fuxors

Generalizing this, I would say:

You want to strive to make sure every single line of code has some value or meaning to the programmer. Programming languages are for humans, not machines. If you have code that looks like it doesn’t do anything useful, is hard to read, or seems tedious, then introduce an abstraction that will let you remove it.

If your language’s mechanisms for abstracting away accidental complexity are so laborious that you cannot remove the useless, the hard to read, and the tedious from your programs without introducing code that is even more useless, harder to read, and more tedious to your framework, then change languages.

Comments on “If you cannot change your language, change your language:
And the Python seems unnecessarily complex to me, because there are explicit language features in place to deal with the "magic" attribute setters. Now programmers coming to the language get one that's less coherent than it would otherwise. Python concepts needed for this example:
* objects have attributes and methods
* public object attributes can be directly accessed by calling object.attribute (=)
* you can create special get_attr/set_attr methods for each attr to overrise calls to obj.attr (=)

The latter two facts are knowledge of limited use outside this specific topic. Instead in Ruby, the issue is solved as part of the core language feature - everything is just messages between objects. I think the desire to solve individual problems on a microscopic level - rather than simplify and empower the language - leads down the path of an increasibly complex and convoluted syntax with diminishing(if not negative) returns on each new feature added
Interesting point, thanks.
"introduce an abstraction that will let you remove it."

I had the same thought as I read Mr. Tomayko's version. Good catch.
Thanks for inspiring me to write tonight, when I had no intention of doing so otherwise.
convoluted syntax with python or ruby????

The thing is - just because a feature exists in a language does NOT mean you HAVE to use it.

Every feature you use makes the code more complex (on the other hand, a good feature might save you a lot of lines of code).

It simply is that, the better the human, the better his language, the better the results will be (if that human wants to achieve good results). Most of the time this means to be very concise.

That being said, I really think that exactly the OOP is where ruby shines compared to python.
Sorry this is probably going to come out as a rant but I really like your blog and know you welcome constructive criticism (which I hope this is going to be).

I tend to dislike the way you overuse the term abstraction. You make a very valid point here: a good language should have the constructs you need to express your algorithms without accidental complexity (a.k.a. code bloat). Otherwise ,either you chose the wrong language for the job or the language itself is wrong.

However, I don't see why you'd consider these language constructs abstractions. They are, in fact, very concrete implementations. Just one choice of implementation against another. We, computer scientists, tend to like abstracting away, removing ourselves from practical difficulties. The overuse of "abstraction" encourages this (IMHO) bad tendency.

We have too many abstractions and not enough efficient and practical techniques. Introducing language constructs that express exactly what you need is good language design, it's not abstraction.

And thanks a lot for your blog.

I try to use abstraction in a very specific way, as explained here:

Abbreviation, Accidental Complexity, and Abstraction.

In that sense, there are ways to remove accidental complexity that are not abstractions, and it is appropriate to use them as well.

If I am overusing the word, it is entirely possible that I am overly enthusiastic about abstraction.

Thanks for the perspective check.
So this reminded me of a recent experience, sort of from the other direction....

Recently I had to maintain some Pascal code in our Rails project, and I was struck by the stiltedness of the language. All your vars have to be declared outside the function--or procedure, which is a different type of method call...

I really felt like I was "Writing Pascal" rather than "making the project work". The kicker came when I left a colon off of an assignment statement (for those who have been spared a Pascal-based education, writing = instead of :=) and the compiler reminded me of this.

"Oh yeah," I said aloud. "I remember when we were really proud of assignment."
I wish Rubyists and Pythonistas would stop taking every (perceived) opportunity to try and cut down the other. As someone who thinks both are great I'll be the devil's advocate here and point out that Ruby has just as much potential for obtuse magic with things like method_missing and friends. Rubyists will step up an point out that in 99.99% of cases you shouldn't be using method_missing whereas Pythonistas will say the same thing about Python's "magic" methods.

The purpose of having Python's magic methods exposed to the user, er, programmer, is not for them to override existing behaviour, thus confusing semantics of what should be perfectly clear code, but rather to be able to define those semantics where it's not perfectly clear as well as to be able to use those operations in a functional context as you can't pass a '.' or '+' to functions like map.

Both Python and Ruby should be blushing and avoiding people's eye contact when it comes to the potential for abusing their metaprogramming constructs. That being said, I'm a big fan of crazy metaprogramming :)
Erik: Just so we're clear here, they're the ones who are bigoted and dumb.
I couldn't parse your title the first time around. How about this, for a more chiastic formulation:

"If your language cannot change, change your language."
I couldn't parse your title the first time around. How about this, for a more chiastic formulation:

"If your language cannot change, change your language."

Part of why I like the title is that the reflection also works, as in:

"If you cannot change languages, change your language."

This version of the title explains why I was writing XSL style sheets to generate Java interfaces and classes in 2003 :-)
crayz: Python unifies all access as attributes, just as Ruby unifies all access as as messages. Python objects do not have "attributes and methods", they only have attributes. The way you describe it is one way to learn it, and in practical terms it'll tell you what you need to know, but it's not an accurate reflection of how Python works and what is actually happening. Note that Python has no special syntax for property support, it's built entirely on top of the generic attribute access mechanism, just as Ruby's "attribute" lookup is built on top of it's message passing mechanism.
> Programming languages are for humans, not machines.

I think this attitude is one of the reasons there is so much bad software. Software is where the rubber meets the road. It is a communication from the programmer to the machine, and the programmer needs to understand the machine to effectively communicate.

Abstraction is a leading cause of code bloat. The layers of glue code (linking one layer of abstraction to the next) tend to get deeper and deeper, till the person at the top of the stack has no idea what is going on underneath. It is more meaningful to talk about simplification than abstraction. Sometimes simplification can done through abstraction. But it is better to refactor the data and code to eliminate the need for the complex code, not just hide it away where it only looks simple.

In fact, too much abstraction can be a reason to change languages. A good example of this is the OpenGL shading language. OpenGL 1.3 is an abstraction of 3D hardware. But as the abstraction layer is moved closer to the actual hardware, via GLSL, then suddenly the programmer gains a great deal of power to do complex and specific tasks in a very simple manner.

<< Home
Reg Braithwaite

Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /