Tag Archives: programming languages

Interest bandwidth

Highlight from the #scala IRC channel:

13:21 < DRMacIver> I have a somewhat unfortunate theory. I suspect the amount one cares about programming issues is inversely proportional to how inherently interesting one's work is.
13:22 < DRMacIver> Or at least negatively correlated
13:22 < ijuma> DRMacIver: is this based on personal experience? ;)
13:22 < DRMacIver> Yes
13:22  * DRMacIver finds it much harder to get worked up about language issues these days
13:23 < DRMacIver> Which is in large part because I'm doing a lot more interesting borderline computer sciencey work
13:24 < dgreensp> yeah, I do a lot of interesting work and only rarely stop to think about languages
13:24 < ijuma> yeah, I noticed. I think it makes sense. People have limited bandwidth and if work is interesting, it's likely to take quite a bit of it
13:25 < DRMacIver> I think the other issue is that people want to find what they do interesting. And so if *what* they do isn't interesting they have to become interested in *how* they do it.
13:25 < DRMacIver> But yes, the bandwidth thing is also a big part of it
13:26 < dgreensp> bandwidth minimum, bandwidth maximum :)
13:26 < DRMacIver> ?
13:27 < ijuma> DRMacIver: agreed
13:27 < dgreensp> er, the two points seemed related -- people need to be interested in something, but they can't be interested in too many things at once
13:28 < DRMacIver> Oh, right.
13:28 < DRMacIver> Yes. That's a good way of looking at it.
This entry was posted in programming and tagged , , on by .

Writing things right

OO has contributed many big and important innovations to programming. Among these, the foremost is that you write functions after rather than before their argument.

No, really.

It’s not just OO languages of course. Concatenative languages do the same thing. There’s a long history of mathematicians doing it as well (though we don’t like to talk about them. The cool mathematicians all write their functions on the left).

It’s funny how attached people get to this fact though.

Consider the following piece of Scala code:

object StringUtils{
  /** 
   * Trims whitespace from the end of s.
   */
  def rtrim(s : String) = ...
}

We can invoke this as StringUtils.rtrim(myString). Or if we import StringUtils, just rtrim(myString);

People get very upset if you ask them to do so though, and they go to all sorts of lengths to avoid it.
Consider the following three examples from different languages:

Scala:

object StringUtils{
   implicit def string2RTrim(s : String) = new { def rtrim = ...; }   
}

Ruby:

class String
  def rtrim
  ...
  end
end

C#:

class StringUtils{
   public static String rtrim(this String s) {
     ...
   }
}

What do these achieve over the previous version? Simple: You can write myString.rtrim instead of rtrim(myString). That’s it. (Actually the Ruby and Scala versions both *can* allow you to do different things than that. It’s just that here and in 90% of the use cases they aren’t used for anything else. The C# version literally doesn’t do anything else).

The thing is, while I’m making fun of this to a certain degree, it’s actually a perfectly reasonable thing to want to do. Designing things in noun-verb order is a good principle of UI design, and it works for programming as well. Things chain better – when you want to add new functions to a pipeline you add them at the point your cursor is naturally at and it matches well with thinking of it as a pipeline of “take this thing, do this to it, do that to it, do this other thing to it, get this value out”. Also you write far fewer brackets. :-) (compare Haskell’s foo . bar . baz $ thing idiom for a similar bracket avoidance tool).

Of these, I’d say that the Ruby solution is the most obvious (it just uses the fact that classes are open to add a new method to String), but it comes with the possibility of amusingly non-obvious runtime errors when someone else defines a conflicting method. The C# solution seems the best to me – it’s relatively little overhead over writing the utility method as you would otherwise and comes with the option to invoke it either as myString.rtrim or StringUtils.rtrim(myString), so when namespacing conflicts inevitably occur you have an easy fallback. But of course it uses a language feature specifically added to do this, while the other two are functions of more general language features. The Scala solution is, to my mind, decidedly the worst of the three.It’s syntactically noisy and comes with a significant additional runtime overhead.

But honestly I’m not particularly happy with any of these solutions. The Scala and Ruby solutions come with disproportionate costs to the benefit they give and the C# solution requires an additional language feature. Moreoever, each of these solutions requires effort at each definition site in order to make something available that you always want at the use site. Wouldn’t it be better if for every utility function you automatically had the option to write it on the right?

Let’s take a digression. What language is the following (rather pointless) code written in?

[1, 2, 3].sort.length

Ruby, right?

Actually, no. It’s Haskell.

Wait, what?

Well, it’s Haskell if you do something slightly evil and redefine the (.) operator (which normally means composition):

Prelude Data.List> let (.) x f = f x
Prelude Data.List> [1, 2, 3].sort.length
3

I saw this trick a while ago (the author was amusingly apologetic for it). It’s evil Haskell code because of the way it redefines an operator that normally means something else (this is totally typesafe of course – existing code will continue to use the old operator definition). But it’s a perfectly valid operator definition, and a rather nice one.

It works well with additional arguments to functions too:

Prelude Data.List> [1, 2, 3].sortBy(compare).length
3

The reason this works is that sortBy takes the list argument curried as its last argument, so sortBy(compare) gives something of type [Int] -> [Int] which we can then apply as above (Haskell’s precedence rules make this work).

So this is a nice trick, but how is it useful to you? Well, it’s probably not. I can’t think of any low noise way of making it work in any of the other languages mentioned so far (the best I can come up with is an evil evil hack in Ruby that would make god go on a kitten killing spree and a mildly nasty hack with operators and implicit conversions in Scala that’s much too noisy to really use), and using it in Haskell will make other Haskell programmers very unhappy with you. But it’s an interesting trick, and I’ll be sure to bear it in mind if I ever get around to creating DRMacIverLang.

This entry was posted in programming and tagged , , , , on by .

Scala syntax change proposal

I came up with a neat idea for changing the syntax for call by name parameters recently (it turned out that it’s actually a reversion to an older syntax for it! The new one was there to resolve some problems, but I like the old syntax better so would rather resolve those problems directly). In the discussion of this some problems were pointed out and the feature list sortof spiralled out of control and collided head on with a previous proposal by Andrew Foggin. Here’s a summary of the current state of the proposal.

  • Any of the modifiers currently allowed for local variables is allowed as either a function argument or a constructor parameter. i.e val, lazy val, var or def.
  • A parameter marked as def has the same semantics as call by name parameters currently do. It replaces the old syntax (or, rather, the new syntax).
  • A function taking N arguments is equivalent to a function taking a ProductN (modulo compiler optimisations). So given def stuff(val foo, var bar, def ba z) the invocation stuff(x, y, z) is equivalent to the invocation stuff(new Product3{ val _1 = x; var _2 = y; def _3 = z; })
  • In order to take into account the need to make call by name parameters constructor local, and generally improve the behaviour of constructors, we introduce an additional privacy modifier, “local”. Conceptually, things marked local are only visible within the constructor. It’s basically a stronger form of private, and is the scoping modifier that constructor arguments with no qualifiers currently have. local variables and defs are not visible outside the body of the class. Unlike private members, you may not access the local variables of another member of the same class. Edit: Seth Tisue has pointed out in the comments that you can already do this. The notation for it is private[this]
This entry was posted in programming and tagged , , on by .

Anyone willing to put a word in for Groovy?

Groovy seems to come up in conversation a reasonable amount. People appear to be doing some interesting things with it. But every time someone tries to advocate the language it leaves me completely cold. Basically all the advocacy seems to come down to:

  • It has “closures”
  • It looks like Java…
  • …but it’s dynamically typed.

Yay?

It has a few features that seem a bit more interesting. It has named (and default?) parameters, which is nice (not exciting, just nice). What little I’ve seen of its metaclass stuff gives me a simultaneous “yikes” and “ooh, that’s kinda neat” reaction.

This isn’t really intended to be a bash at the language. I just don’t know much about it, and none of the information I’ve seen seems terribly compelling. I’d like to hear some stuff about why it’s actually a nice language to use. I probably still won’t use it – I have enough languages on my plate as it is – but I’d like to be a little less ignorant about it.

This entry was posted in programming and tagged , on by .

Tell us why your language sucks

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

This entry was posted in programming and tagged , , on by .