Posts Tagged ‘rants’

Tell us why your language sucks

Monday, February 18th, 2008

Let’s play a game. Take your favourite languages and tell us what you hate about them. Like I’ve said before – all languages suck. Don’t pretend yours is perfect. If there aren’t things about it which annoy you you’re not trying hard enough.

Note: This should not be about bashing languages you don’t use or like, or even languages which you use and don’t like. Everyone does that already. I don’t want to hear yet another rant about why Ruby sucks from a Java programmer, why Java sucks from a Factor programmer, why Lisp sucks from a Javascript programmer, etc. I’m not even interested in hearing about people who are forced to use Java|C|C++|Javascript|Whatever and hate it. Tired, been done to death. It specifically has to be a language you use at least semi-regularly and like. Feel free to post here, to your own blogs, to the inevitable reddit thread, etc. But wherever you post it, have fun. Go on, rant. Get it off your chest. You’ll feel better for it. :-)

I’ve already started with Scala. Now I’ll do Haskell. Hopefully someone more experienced with the language will follow up, as I’ll freely admit it’s not my best language.

So, things I hate about Haskell:

Let’s start with the obvious. Monad tutorials. No, not monads. Specifically the tutorials. They’re endless, overblown and dear god are they tedious. Further, I’ve never seen any convincing evidence that they actually help. Read the class definition, write some code, get over the scary name.

Now we’ve over the one sociological issue, let’s get to some actual language ones.

Modularity. Haskell’s module system is about the minimum possible you can get away with and still claim to have a module system. Anything less and you basically have C style header files. Now, this isn’t a huge problem. To a certain degree type classes mitigate the need for anything functorial. But there are examples where it’s an issue. Take ByteStrings for example. Lazy and strict ByteStrings have essentially the same module signatures, but there’s no way to write code which is agnostic as to the type of ByteString it uses. They don’t live in a type class because it was considered that the type class signature would be too long. This is probably fair, but life would be a lot nicer if you could write functors over the ByteString modules.

In general, Haskell has very poor namespacing. If two modules define something of the same name you have to redefine one of them or refer to one of them qualified. It’s not a huge issue, especially as you *can* rename and Haskell modules are anyway not as long as Java packages. It’s not like you have to refer to org.haskell.data.collections.map.mypetcat.lookup. M.lookup isn’t too onerous. This mainly causes problems with symbolic operators, because things like Foo.++ look a lot worse as infix operators than Foo.bar does. I don’t know of a good solution to this problem. Object oriented languages provide a solution to it by basically making the type of the first argument responsible for namespacing. I don’t find this especially satisfactory, but it does work.

On a similar note, Haskell type classes basically live in global scope. There are good reasons for this, and it avoids you having to write a whole lot of painful sharing constraints (The example that is thrown at me every time I complain about this is what do you do if you want to unify two Data.Sets, each of which uses a different instance of the Ord type class)? It can be a real pain though.

There’s another issue related to type classes. Let’s pick an example. Data.List defines both sortBy and sort. The difference is purely that sort uses the standard ordering on the Ord type class while sortBy uses a provided ordering. And you need to define different functions every time you want to be able to use either a type class or something user configurable. Because you can’t redefine type classes locally or pass them as first class instances there’s basically no way around this. You can normally avoid the issue with selective use of newtype and careful choice of your types, but it’s definitely there.

Which brings me to another point – type classes are not first class. The Scala encoding of type classes is clunky in many ways, but a very nice feature is that the things you’re using as type classes are real first class members of the language, and you can bring to bear all the usual tools you have for manipulating stuff.

10,000 compiler extensions. GHC introduces so many compiler extensions, and everyone goes wild about them. This is understandable. Some of them are really useful. Some of them it’s amazing to manage living without (No multiparameter type classes in H98? Yeargh. Getitaway!!). I really like most of these I’ve used, but it sometimes make it feel like you need to employ deep and profound type system voodoo to get anything done. It would be very nice to get these unified into something sane and consistent, but Haskell’ seems to have stalled.

Tuples and records. There’s basically no good generic handling for either of these. Each of the different sizes of tuples is a totally different type (with no common type classes for abstracting over them), records are just a thin wrapper over normal datatypes with no extensibility or namespacing. Your record accessors will clash just as much as any other function name.

Something which has bitten me in the past is sharing code between monadic and non-monadic contexts. You essentially need to write pure and monadic versions of a number of functions. It would be nice if generic monadic code could automagically be specialised to the identity monad in a way that didn’t uglify pure code using it, or pure code lifted to monadic versions (this is harder I think). This doesn’t come up too much, but it means that there’s often functions like foo and fooM for pure and monadic versions.

The prelude and standard type classes are a bit painful sometimes. Things which you’d expect to be overloaded into type classes aren’t (Data.Monoid defines a function mappend for example, which in the List instance is ++. Why isn’t ++ on Data.Monoid?) and sometimes the type classes which are there are poorly thought out (Num shouldn’t extend Eq, and it would be nice if + was factored out in order to provide better support for things like vector spaces). I believe there is some work on alternate numeric preludes.

Plus lots of other little things which don’t spring to mind at the moment.

Also, one final disclaimer. Please please please don’t take this as a “Haskell sucks, don’t use it!!!” post. If you do I’ll… I don’t know, give you a really devastating hurt puppy look or something.

I’d also appreciate it if you don’t use this post to start a language war. Remember – you’re only allowed to say bad things about languages you actually like. Otherwise you’re cheating. :-)

Where lies the problem?

Saturday, June 16th, 2007

The intersection between my facebook friends and people who read this blog is probably (relatively) large, but for completeness and historical record I’ll post my current facebook status:

“David is considering at what point he should start to wonder whether the problem might not be with the rest of the world.”

I get into a lot of arguments, or at least heated disagreements. Sometimes it’s because I’m wrong, but most of the time it feels like the world has reflexively thought “Oh, David has an opinion. Let’s disagree with it!”

This is very frustrating. Especially when I’m clearly right. Or, at the very least, when those I am arguing with are mouthing gibbering nonsense and ignoring my refutations of it.

This isn’t new either. It happens in whatever area I’m working. More so in programming than it did in maths, but I think that’s a function of which side of the discipline I interact with more than it is of the discipline itself.

Example points on which I’ve had arguments in ##java.

  • First class functions are a good thing.
  • Java’s type system is crap.
  • Random access strings are a poor design choice for an immutable data structure.
  • The non-trivial import features Java provides (* and static imports) are actually a good thing.
  • JEE is bloated nonsense (ok, only about half of ##java disagrees with me on this point).
  • Large scale ORM is a stupid idea, and causes the most amazing amount of grief.
  • XML may be standard, but it’s still a rubbish format and should be avoided at all costs (*waves to the RSS readers*).
  • Most recently (and inspired by this) the minor suggestion that being allowed to override void methods with non-void ones would be useful (response: Garbage arguments as to why this would be horrificially wrong and unsafe. It’s not.).
  • Endless stylistic arguments that basically boil down to “Why the Java standard approach of writing procedural code and calling it object oriented because it lives in a class is a bad one”.
  • Endless philosophical arguments that basically boil down to “Why ‘That’s not OO’ is the most useless criticism of an approach in the history of programming”.

As per the earlier quote, eventually I have to start wondering whether the reason I disagree with everyone might just not be because everyone else is wrong.

But then I come to my senses.

Firstly, these are mostly Java programmers. There are certainly competent Java programmers, but the average Java programmer is the very definition of blub. “Oh noes. It’s an anonymous function? What’s a function? How do I write that with a for loop???”. Even the good ones tend to be very set in their ways. Admittedly some of these arguments are with people who I’d otherwise have believed to be competent. However I’m going to perpetrate a no true scotsman fallacy^H make a highly reasoned distinction: If they were competent, they wouldn’t be spouting nonsense and then ignoring a detailed explanation of why they were wrong.

Secondly, the state of the the world in general and of technology in particular gives me irrefutable empirical evidence that the vast majority of people are idiots. It therefore stands to reason that a sizable proportion of the people I interact with are idiots. Not coincidentally, I get into arguments with a sizable proportion of the people I interact with.

So, in conclusion, I am correct. The problem is not with me, it is with the rest of the world. I should stop letting the opinions of idiots bother me.

By the way, this is not a deliberately over the top rant. You may be tempted to think that I’m being tongue in cheek or making some metaphorical or otherwise not entirely serious point with this post. I’m not. Deal with it.

Javascript

Friday, May 25th, 2007

As you may know, Javascript is the world’s most misunderstood language. As a language it’s pretty nice – prototype OO, decent functional support, (almost) proper lexical scoping, etc. Some warts, but generally not too bad.

But dear god is the web browser an awful platform to develop for, and some of this is Javascript’s fault. The single threaded event model is a nuisance, it’s really hard to debug, and everything just gets in the way of everything else to produce really non-trivial interactions which break everything. Attempts to layer libraries on top which make this less awful are definitely valid, and to some extent work, but they just add new levels of incompatibilities and grossness.

Job applications

Wednesday, April 18th, 2007

It has occurred to me that this blog is eminently findable when starting from my name, and that consequently the companies who I’m interviewing with at the moment will no doubt see several rather annoyed rants on computer related subjects attached to said name.

Rather than retract these, I wish to quote the words of a great man on this subject:

Fuck that shit

(Hotlinking done with permission)

I do hope the existence of these rants doesn’t put you off. If it does, then we’re probably not compatible anyway. Sorry.

David

Static vs. Dynamic Typing

Monday, April 16th, 2007

Rah. Dynamic typing is evil. It lets you do totally unsafe things.

Err, no. Wait, that’s not right. Static typing is evil. It’s ugly and gets in the way and real programmers don’t make type errors anyway, do they? Are you saying you’re not a real programmer???

No, wait. Umm…

I’m so confused…

Want to know what I really think about static vs. dynamic typing? (no you don’t. I’m going to tell you anyway).

I wish the entire goddamn argument would go away.

Seriously, shoo. Buzz off.

There’s no reason there should be a one true language in which you do everything. None. Sometimes language Foo is better, sometimes language Bar is better. Given this, there’s no reason Foo can’t be dynamically typed and Bar statically typed.

Neither is better. Each have their strengths and weaknesses. People have their preferences, tasks have their requirements. Sometimes you’re better off choosing one or the other, sometimes you’re more comfortable choosing one or the other. When there’s a compelling reason to make a decision between the two (which is so much less often than the fanatics on both sides of the argument want you to think), follow that reason. When there’s not, use whichever you prefer.

But, in the mean time, shut the fuck about it. Far too many good and interesting discussions about languages turn into poo flinging between the type system monkeys. Shut up, grow up and get over it. There are more interesting things to talk about in the subject than whether certain operations should fail at run or compile time.

That is all.