So it seems Giles Bowkett is upset about use of the word “magic”. I’m happy to agree with the general consensus from various fora that the specific article he’s complaining about is, well, pretty much content-free. I could read that post over and over and still have no idea what actual things the author liked about Django or didn’t like about Rails. But I’ve pretty much learned to ignore content-free hype, and that’s what I did in that case.
I’m also quite happy to grant that not all programming languages do the same things in the same ways. Usually, I’m even willing to overlook the sorts of predictable comments which have so endeared Lisp and Smalltalk programmers to the world in general (see: “Lisp had that forty years ago”, “Smalltalk is the only real object-oriented language”, “this would be so much better with macros and tail recursion”, “we invented refactoring, you insensitive clod”, etc.).
But that word, “magic”. It keeps coming up over and over again. Now, I’ve written (at some length) about this topic, and generally endorsed the viewpoint that the sorts of things typically described as “magic” are often just applications of simple principles or techniques, and so really just require some background knowledge to understand and use effectively. And, really, I think the advantages or disadvantages of such “magic” are — except in extreme cases — largely subjective and have more to do with experience and preference than anything else.
I think that’s not too far from what Giles was trying to say, but I could be wrong. So I’ll see if I can explain where I’m coming from.
Django, of course, famously underwent a “magic removal” (immediately preceding the 0.95 release) which was hugely backwards-incompatible and is a motherlovin’ pain to migrate through if you happen to be upgrading really old Django installs (see: my life at the moment). What was this “magic”?
Well, let’s say you want a blog application which, in the grand tradition, we’ll call blog. You want a way to store, retrieve and represent entries, so — since you’ve got this object-relational mapper lying around — you want to use a model class to do this. In any Django release since 0.95, you’d have a directory (a Python module) named blog, in it a file named models.py and in that a class named Entry. Want to interact with it? from blog.models import Entry and away you go. Simple.
In Django releases prior to 0.95, you have a directory (a Python module) named blog, in it a directory (also a Python module) named models, in that directory a file named blog.py and in that file a class named Entry. Oh, and the models module needs to explicitly export that in its __all__ declaration. Want to interact with it? Well, the obvious thing would be, say, from blog.models.blog import Entry, which is a bit redundant but still serviceable. Except that won’t work.
What you actually want is from django.models.blog import entries. You can get at the Entry class through that (entries.Entry), but what you almost always want is the collection of other stuff in entries, which is to say all the helpful functions for retrieving entries from your database, exceptions related to entries, constants related to entries, etc., none of which you ever actually wrote and all of which were generated on-the-fly rather than, say, being inherited from some suitably-generically-written parent class.
Understanding why it worked that way is easier if you have some knowledge of the prehistory of Django; originally, the Django ORM was, literally, a glorified code generator. You’d feed it a definition of your data model, and it would churn for a bit and then spit out a Python module, containing your model and a bunch of utility functions and other stuff. Then you’d stick that somewhere on your Python import path and go to town. And if you needed to make changes, no problem: just re-generate the code.
Based on advice from the outside world, that went away before the first public release of Django. Sort of. What actually happened was that instead of generating a module you’d save somewhere on your filesystem, the ORM just generated that whole module of code on the fly, kept it in memory and hacked sys.path to make it importable. This is not as hard as it sounds and can be a neat parlor trick (ladies and gentlemen, I have no .py files up my sleeve! Now watch carefully…). So, really, it was still a glorified code generator, it was just wearing a mask and a fake moustache and hoping nobody would notice.
This was “magical” in the sense that a whole bunch of stuff you’d never written appeared in a module you’d never created and was supposed to be used in place of the code you had actually written. And although the level of dynamic programming and cleverness involved was, to borrow Giles’ phrase, “Palookaville, Omaha bullshit” compared to the types of things you see in, say, Lisp or Smalltalk, it was pretty much universally condemned.
But — and this is important — it wasn’t condemned because dynamic programming or cleverness are bad in themselves; it was condemned because, well, there are situations where that stuff’s appropriate and situations where it’s not. More on that in a moment.
Many circuses and travelling shows involve a particular feat wherein one or more performers set up some thin poles and set plates or other round-ish objects spinning upon them, balancing them and keeping them rotating fast enough that they stay — seemingly in defiance of natural law — perched atop the poles rather than crashing to the ground. Keeping in mind the fact that all analogies for programming are inherently bullshit, this can be considered an analogy for programming: you’ve got some plates, and you have to keep them spinning or you get crashes.
Some languages, libraries and/or frameworks require you to keep track of a larger number of plates than others. For example, in C you have to manage memory yourself, and remember to free anything you’ve malloc‘d when you’re done with it, and to remember what you’ve already freed so you don’t try to follow a pointer down the rabbit hole. There are programmers who consider this to be a character-building experience. Personally, I just look at it as adding a bunch of plates that I have to keep spinning.
Other languages, libraries and/or frameworks try to reduce the number of plates you have to keep track of. For example, many languages have now come around to the idea of automatic memory management and garbage collection; this has, by and large, been a boon to programmers everywhere (see: jwz, “Java doesn’t have free(). I have to admit right off that, after that, all else is gravy.”). In my experience, reducing the number of plates you have to keep track of makes programming simpler and programs more robust. So this is generally a good thing.
What does this have to do with “magic”? Well, sometimes programmers decide to do clever things, often in the name of convenience. They set things up so that, say, some variables will be automatically defined and populated without you having to do anything. Or so that certain modules of code are automatically loaded and made available to you without lots of tedious import statements. Or so that the return value from A ends up rendered by B, based on some convention of similarity of names between the two. Or so that a two-line class declaration ends up producing lots of members which were never explicitly defined in that class or any of its ancestors.
These sorts of things are, in certain circles, referred to as “magic”. They are, without a doubt, quite clever in their way. And in many cases they do, without a doubt, offer some level of convenience to the programmer who uses them.
But they can also introduce whole new batches of plates that you’ve got to keep an eye on. And they won’t be plates that you personally set spinning, and sometimes they’re not plates that you can easily watch or run over to if they start getting wobbly. They’re just a bunch of plates that got added to your act, and they’ve got to keep spinning or else they’ll crash and ruin the show, and figuring out why that happened or how to prevent it may prove rather difficult (see: Brian Kernighan, “debugging is twice as hard as writing a program in the first place. So if you’re as clever as you can be when you write it, how will you ever debug it?”).
In my opinion, designing good languages, libraries and/or frameworks consists of finding a balance between providing clever and convenient things, and asking programmers to keep too many plates spinning at the same time. When so many clever things are going on that it’s hard to track all those plates, people tend to call it “magic” . When so few clever things are going on that everyday tasks get cumbersome, people tend to call it “dumbed down”.
Every language/library/framework has its equivalent of “magic”. Python, for example, has functions and classes as first-class values, (non-mutable) closures, the decorator pattern baked into the language, generators, comprehensions, properties, special methods you can implement to enable language-level syntactic constructs, dynamic code generation and all sorts of other stuff. These features are extremely important in Python, but use of these features often appears “magical” to people coming from languages which don’t have them (like, say, Java).
And every language/library/framework has its own conventions on when and how to use the “magic” it offers. For example: I am not a Lisp guru, but I’ve seen plenty of people who are point out that you should never write a macro when a plain old function will suffice. Sure, you’ve got all that fantastic dynamism that lets you bend the language in clever ways, but cleverness for cleverness’ sake is not a virtue; it’s just spinning up a bunch of extra plates, for no other reason than “because I can”.
To put it concisely, I think that’s what a lot of critiques of “magic” really boil down to: the notion that just because you can do something doesn’t mean you should. Accepting this can be tough, but I think it’s a necessary part of becoming a good programmer. If you don’t have a certain sense of discipline and respect for the power you’re wielding, well, you might end up cloning dinosaurs and getting eaten by them when the power goes out.
Of course, there’s quite a lot of room for subjectivity here. If you grew up, metaphorically speaking, in a family of acrobatic plate-spinners, you probably don’t mind handling a bunch of extra plates in your act, because you’ve been spinning lots of plates your whole life. If you didn’t, well, you might take a different view of things. And I think we also have to account for taste; there are, I know, people who can keep dozens of plates spinning but who choose not to, because that’s not what they like to do. And I’m sure there probably are people who can’t but would love to if only they could.
I’m not entirely certain that there is just one point here. It’s a bad thing to reflexively call stuff “magic” just because it does something you don’t yet understand. But it’s equally a bad thing to use “magic” just because you can. The right thing, if there is one, consists of a willingness to learn how stuff works even if it’s unfamiliar or seems complicated, but also consists of learning to solve problems in a way that’s clear and useful to people who’ll read and use your code.
Often, that means learning and abiding by the customs and conventions of the particular programming community you’re part of. Python and Ruby, though surprisingly similar as languages, have communities of programmers whose norms are significantly different from each other. And even within a language there can be large variations (and, as with so many other language features, Lisp has arguably been doing that longer than anything else).
It also means that long after you’ve mastered the syntax, concepts, patterns, libraries and frameworks of the languages you work with, you’ll still be working to master the discipline (in multiple senses of the word) of programming. In fact, if you do it right you’ll always be working on that part, you’ll always be learning to find the right amount of “magic” in both the languages you use and the programs you write, and sooner or later you’ll have to accept that it will never be a fixed quantity.
And don’t listen to these modern pundits who think you can rush into all of that; ten years is nowhere near enough time.
Comments for this entry are closed. If you'd like to share your thoughts on this entry with me, please contact me directly.
The obvious example of ‘magic’ in Rails (beyond all the activerecord stuff) that I always mention, is that the controllers (equivalent to Django’s views) don’t take a request parameter in the function definition. They also ‘magically’ render the relevant template without you have to do it explicitly.
Normally this approach is fine and dandy and means your code is very lean, but sometimes you want to access the request object or you want to have more control over the response. At this point you have to dive straight into the deep end of the documentation (which historically has been very poor, though I’m informed that this has improved of late.
With Django you deal directly with request and response objects, it’s more verbose but it’s also much more intuitive. It allows me to invent that ‘magic’ to abstract away request/response objects for myself, if I want it (probably using a simple decorator). I think this has always been my issue with Rails (I’ve developed numerous sites in both), the framework impresses you with how fast it is to get up and running. But as soon as you want to deviate from the ‘build your blog in 15 miniutes’ path, you hit a very steep learning curve which usually ends up requiring you to reintroduce all the stuff that was abstracted away in the first place.
I do like a bit of magic and clever abstraction, I think the level of magic Django has at the moment (major example would be generic views) is the sweet spot for me.
Excellent observations, James. I would also agree with Andrew in saying that Django has the right level of what people are calling ‘magic’ to make it useful without being extremely difficult to do anything other than the bog-standard included functionality (see: Plone, Zope3).
Though I don’t consider things like generic views or or built in decorator functionality to be magic, but to be utilities. The sorts of things that first attracted me to Zope and then convinced me to move to django is that the framework handles the boring stuff you’ll need in every application (db connectivity, sessions, users, security) and lets you focus on the things that are specific to your application.
Does anyone really listen to Giles Bowkett anyway? I don’t know the guy, but he writes so many pointless sentences where the implicit message — in fact the entire “point” of the pointless sentences — is to say “I think I’m a better programmer than you.” Most people who write things like that are better at inflating their own egos than at programming. He so transparently masks his insecurity in pseudo tough programming talk, not to mention he never says anything useful beyond stirring up drama.
Anyway, I love the Django. I don’t care about Django versus Rails (yawn). I agree “magic” should be applied very carefully. Every layer in the programming stack from assembly to Django has always included magic in some way, but I agree it should be as clear as possible what’s happening for the next person who comes along at whatever level in the stack you’re dealing with. ORM frameworks are particularly tricky here, and that’s why I think about 1/2 of Hibernate, for example, — lots of the magic parts — hurt more than they help. Ditch “HQL,” “JPA-QL” etc and just let me map SQL return values to objects. Done.
I agree with Andrew — how intuitive the framework is vital to how productive you can be with it.
Adam:
I don’t understand what your or my opinion of Giles as a person or of his other writing has to do with whether this one piece of writing had a valid point or not. If he writes 999 pieces of dreck, does that automatically make the 1,000th piece dreck? Perhaps it is statistically likely. But we don’t have to bet: We can simply read the article and refute his arguments on their merits.
Please comment again, I am interested in hearing what you have to say about his post rather than his character.
Reg Braithwaite:
I don’t understand what your or my opinion of Adam’s post has to do with whether this one piece of writing had a valid point or not.
Please comment again, I am interested in hearing what you have to say about James Bennet’s post.
Captain Obvious:
My name is spelled “Bennett”, and does appear multiple times on this page.
Please comment again, I am interested in seeing you spell it correctly.
^^ p0wn3d ^^
Andrew Ingram: “but sometimes you want to access the request object”
The request object in Rails is called “request” and is available in your controller if you need it. For example, “request.remote_ip” gives you the remote ip. Sure, it’s “magic” but so what? It’s REALLY easy to customize Rails or dive in deep if you need to. 99% of the time I don’t care about the request object and I’m glad it’s hidden away.
http://www.PhilipBrocoum.com
After 4+ years with Rails, it was very refreshing to read this insightful post. All the spinning plates is the reason the Rails Way is larger than most of my Java books, and about equal in size to my Spring in Action (2 ed) book. Rails has simply baked too much magic in, and keeping track of it is a nightmare. It might be helped somewhat if the docs were better (and the guides are making this much better), but it’s still painful. Combine that with an inconsistent API and a codebase that takes advantage of virtually every magic trick ruby has to offer, and you have a framework that excites you at first but wears you down over time. I’ve developed very large systems with Rails and it’s served me well, but it’s also made me very weary.
This is the reason both Python in a Nutshell and the Definitive Guide to Django now sit open on my desk. I come seeking clarity, explicitness, and productivity. I’ve shied away from Python for years because of some awful inconsistencies in the language and lack of closures (I <3 closures), but if it keeps things straightforward and clean, I’ll overlook them.
I’ll probably always prefer Ruby as a language in general…as a tool with which to perform magical displays of power and light…but I’m very close to giving up on it for day-to-day real work.
Some of you folks seem to think this is a debating contest rather than a conversation. If this is about “owning” each other, count me out. I simply encouraged Adam to move beyond the ad hominem. Not to “score off him,” but because in addition to disliking Giles, he may have an interesting refutation of Giles’ piece.
As someone who liked the original post, I’m most interested in opposing viewpoints, they have the richest and most fertile source of new ideas for me.
That is all.
@Reg, lighten up dude. It was joke. And it also referred to the spelling remark.
There are two different definitions of magic in play here.
The use of advanced language features in a manner that might be confusing to a novice programmer.
The use of ANY language feature to automate some process that a programmer would not expect to be automated.
For example, the request object in Rails is basically a global variable. Most programmers have had global variables beaten out of them by the second year of college. So it seems “magical” that this object is available to you in the middle of a method. It’s using programming language features that are as old as computing. But it’s magic because it is unexpected automation. Similarly with Rails’ translation of model names and table names from singular to plural. There is no advanced Ruby feature involved. It’s just silly automation for no particular purpose.
Giles brought a shitstorm onto his head by presuming that the complaints about magic (unexpected automation) came from programmers who are too lazy to move beyond the novice stage.
Paul -
The translation of table names from singular to plural does have a reason. It’s much more natural. The table is the data of every Model, whereas an instance of class Model is a particular Model. The table having the name “models” reflects this.
Also, in no way is the ‘request’ object global, in the sense you’re speaking of. Why bother making every single action take a request object explicitly? You know it’s always there, why waste the time to type it out? It’s a question of philosophy. I’d much rather not type the same thing over and over and over again. The conventions are regular, and make sense. Other people want to see it each time. Neither is better or worse.
@Anon, and how quick/easy is it to find which variables are implicitly there? It’s nigh impossible in the awful api.rubyonrails.com…
Your blog software told me my resonse was too long, so I put it on my own blog. It’s here: http://gilesbowkett.blogspot.com/2009/07/blog-comment-for-james-bennet.html
@ Rufugee - Python supports closures. Look at the Python section here:
http://en.wikipedia.org/wiki/Closure_(computer_science)
Since Giles Bowkett’s blog won’t let me post a comment, I’ll write my response here:
You completely missed the point of what I was saying, but thanks for making me crazy famous! Yes, the request object is conveniently accessible by calling ‘request’ in the controller, but it could just as easily not be. Rails could have gone with a completely different approach and abstracted the request away completely (believe me, I’ve used frameworks where literally the only way to access the raw request was via a convoluted series of deprecated methods, therefore it’s far from implicit that the request is easily accessible), whilst the right answer was in line with my educated guess, it was far from obvious.
I like my methods to visibly take parameters and return a result - without side effects, and I like that to be explicit, and I like scope to be explicit. I like someone to be able to look at a single method in my code and know exactly what it does. Python very controversially uses a ‘self’ parameter on instance methods, and whilst I’m not a huge fan of the extra typing, I like that it’s explicit. If someone has to spend time learning an entire framework just so they can debug a single method of my code, something has gone very wrong.
I do like Ruby as a language, I do find that it’s cleaner than Python in many ways. But, I think there’s a lot to be said for the part of the Zen of Python about how explicit is better than implicit.
Rails is a very fine framework, but it demands that you indulge in it fully and appreciate all the gifts it showers upon you. Django is more verbose (at first), but it’s more forgiving of partial learning. Partial learning isn’t something to be dismised either, not everyone is destined to be a full time coder, but anyone who can contribute to the code in some way is valuable.
It’s at least worth noting in passing that the assertion this is “natural” is pretty subjective. CakePHP does automatic pluralizing in a Rails-like fashion, and frankly it’s awfully easy to boff up the names between the model code, controller code, and SQL tables. We have
ordersanditemsas tables, but the foreign key is namedorder_idrather thanorders_id, the models areOrderandItemand the controllers are back toorders_controlleranditems_controller. I understand why all these things have been chosen, but one could just as easily argue that a more “natural” convention would have been to have everything be singular, which would have the added bonus of not requiring the convention to include both pluralization rules and a mechanism for overriding them in order to use its own ORM.Of course, Django goes off in an entirely different direction from this, rendering it all rather moot, but that’s a discussion for another day…
Watts:
While I agree that “natural” can be subjective, I really don’t think it is in this case. In this case “natural” refers to “plain English”. If you have a basic grasp of the English language it should be pretty obvious why a foreign key which relates to a single Order record gets a named the singular order_id, or why a controller which is responsible for managing many Orders gets a plural orders_controller.
I like Django but I’m doing a lot more grails recently and I like how grails provides both generated in-memory and code templates. I find both useful first when I’m modeling my domain and second when I’m coding views and controllers.
I don’t know if rails has a plugin to do this, seems trivial with ruby/groovy/python dynamic nature. It’s probably something easy to do either of rails or django so why chose one or the other?
Giles says: “And certainly asking this question, about when you have chosen to use unusual programming features, is it not reasonable to expect other things in your approach to programming to change as well, this question is just so much more interesting than all these ridiculous people waving their arms and peeing their undies over “magic.” ”
But his blog doesn’t allow comments so I’ll comment here.
Giles: you are obviously using a definition of “magic” that involves metaprogramming using tools like method_missing, dynamically generated functions, etc.
Now please tell me: who are these “ridiculous people waving their arms and peeing their undies” over magic so-defined? We could start to have a reasonable conversation if you could point to a single such blog post as an example.
Until then, you’re just engaging in a straw-man. Magic is unexpected automation. No more, no less. It could be suspicious use of a global variable or a naming convention that drives software behavior. You keep bringing the argument back to metaclasses and method_missing. But there is nobody arguing that these features of Ruby are bad: especially not Python programmers. Python has the same features.
Thanks for the great back story on the magic removal stuff! Even though I’ve heard Adrian tell the tale a few times at conferences, I never get tired of it.
I’ve been trying to learn Rails lately to gain a more balanced view of the universe or something. Coming from Django I understand a little bit why it feels magical - the absence of a list of imports, less clear documentation, and not as many variables getting passed around.
Rails can feel nearly impossible to master - like you need to know a secret code or something. A good book (the online documentation is getting better, though still meh) really is the key to finding how to do stuff in Rails. And for beginning web developers, Rails’ hand-holding and “this is the way you do it, ask questions later” attitude is probably not too intimidating.
So yeah, I don’t think Rails is really “magical.” Then again, I don’t really trust my own judgment of tolerable complexity these days - I kind of liked Google Wave.
Paul - of course I’m using a definition of “magic” that revolves around so-called metaprogramming. I said so in my blog, over and over again. How can my use of the original definition be irrelevant in a discussion that I started with that definition?
Anyway, in terms of who are these ridiculous people waving their arms, etc., well, now that I come to think of it, it wasn’t in a blog post, it was in a semi-private online discussion and I think it’d be rude to name names. So, sorry, you’ll just have to wonder.
Your point about Python having the same features is not only irrelevant in this context, but also something I myself brought up in one of the many epic tangents on Reddit, at a moment when it was relevant. I think I also said something in the original rant along the lines of “Python and Ruby are almost the same fucking language.” It’s probably reasonable to assume that if two languages are almost the same language that they may in fact share some of the same features, but thanks for articulating that explicitly, because someone might have missed it, somehow. Thanks also for re-iterating my own point while presenting it as if it were new information, accusing me of straw-man tactics, and redefining terms on me. I almost fell for it, and I admire your boldness.
A story about ‘magic’.
‘request’ is an attribute of ActionController::Base that holds the request object for the action that created the controller. It is 100% vanilla by-the-book OOP that you can do in any language. What in god’s name does anybody consider “magic” about it?
I think you’re getting caught up on the specific example rather than the basic argument which is this:
I like to be able to look at a method and know exactly what it does.
Just because something is legitimate OOP and just because it doesn’t involve any fancy metaprogramming, it doesn’t mean it is a good way to do things, it all comes down to personal preference.
When I saw the first Rails screencast, I was suprised. I literally had no idea this little stub of code somehow turned into a fully interactive web app. It was impressive to be sure, but I didn’t like it. I like to learn something by continually expanding my mental model of how it works, Rails works counter to this because you have to learn quite a lot in order to understand all of what it does for you. In many ways it’s like how quantum computing was taught at university, you just had to take the lecturer’s word for it that this was how quantum logic gates worked. It was an extremely unintuitive course because you had to take so much as fact without ever really understanding why it was that way. There is no way to walk into a quantum computing exam and use good old intelligence to compensate for gaps in your knowledge, it was raw fact-learning - the worst kind of learning in my opinion.
I don’t know about you, but even though I know it isn’t, quantum physics does seem quite like magic.
I’ve read both the original post and Giles’ post. Loosely, in the original post, it was nothing more than “there exists smt about Rails that’s too magical about it for me full stop”—Giles, how you’ve managed to use it to write a long opinionated post and also comment on his post about language features strikes my amazement. Not? Well at lest it’s amazing to my that you think the use of the word ‘magic’ by the writer came from him being confused by Ruby’s language features. You need to discern when people aren’t able to understand what code does (lack of comprehension) with code that causes non-localized unexpected behavior at runtime (magic), because your post was just a useless ramble of the former and an attack on peoples intelligence.
I’m also disturbed that you disregarded treating metaprogramming as anything more than just plain programming itself. I believe the term reflective programming came to be for the the very purpose of identifying such programming styles that use the language itself to evolve the language itself. Once we know what we’re talking about, we can discuss the dos and don’ts and the whens and when nots.
Ouch:
“Lighten Up.”
You are spot on, I was not taking it lightly enough. I blame a lack of coffee. I am putting out a call for a Firefiox plugin or Greasemonkey script that uses the computer’s camera to detect whether the user has finished either two full cups of coffee or one espresso and blocks all reddit/HN/digg downvoting and blog commentary of any kind before this has taken place in its sight.
Might not be a bad idea to block publishing new blog posts either.
Thanks for reminding me to smile!
Filip said: “Giles, how you’ve managed to use it to write a long opinionated post and also comment on his post about language features strikes my amazement. Not? Well at lest it’s amazing to my that you think the use of the word ‘magic’ by the writer came from him being confused by Ruby’s language features. You need to discern when people aren’t able to understand what code does (lack of comprehension) with code that causes non-localized unexpected behavior at runtime (magic), because your post was just a useless ramble of the former and an attack on peoples intelligence.”
I think this expresses quite well my feelings on this. I read Giles’ blog avidly, and find him on the mark quite a lot of the time, but this latest rant was a complete straw-man argument.
I’m still at a loss over what magic means. This reminds me of how DSL became an overloaded term.
Django is simpler than Rails yet more capable. It’s an obvious choice. Python vs Ruby is a legitimate, interesting discussion.
Rails is intentionally complicated and is a pain to code in. Because Django requires explicitness, overriding defaults is very easy. In Rails, it’s painful. Django is permissive where Rails is restrictive.
Oh, and the admin is great. Whoever pushed for getting rid of dynamic scaffolding in Rails is a fool.
Giles says: “Anyway, in terms of who are these ridiculous people waving their arms, etc., well, now that I come to think of it, it wasn’t in a blog post, it was in a semi-private online discussion and I think it’d be rude to name names. So, sorry, you’ll just have to wonder.”
So the blog post was intended to refute an argument by a person you cannot name. And this person somehow represents a larger class of people, although as far as you have demonstrated, the set of people in this class is 1 (and that’s giving you the benefit of the doubt).
Also: as far as this debate goes you think that Ruby and Python are basically the same, so there was no reason to mention either in your post.
And you don’t know anything about Django, so you actually don’t know whether it supports or refutes your point. But you mentioned that in your post too.
And you’re surprised that people consider this a straw-man argument?
So Giles’ argument is:
There are language features that make code harder to read and/or understand. Using them as a hammer is cool. If you complain about the fact that it obscures the intent and predictability/outcome of the code, you’re stupid.
Right…
The longer I am a programmer, the more I value simplicity and readability. Once upon a time, I did “clever” things for the sake of it, but when it comes to writing code that I’m possibly going to be debugging a couple of months or years down the line, I prefer to make things as clear as possible…
FTFY. Unless you want your writing to look like legalese, lay off the and/or. Natural language and and or are quite flexible. Try them out.