Archive for January, 2008

Learning Scala

Thursday, January 17th, 2008

Some questions for people who are learning / have learned Scala: What languages did you know beforehand, and how easy did you find learning Scala in comparison to these? Are there any languages which you found knowing particularly helpful when picking up Scala?

An explanation follows:

Scala seems to be a relatively hard language to learn for some people, not so much for others. Part of this is its complexity - it really does have a lot of little features - but I’m wondering if more of it might be its approach. It’s a language with two major inspirations - object orientation (in the peculiar flavour of it Java practices) and statically typed functional programming, and I’m not sure how easy it is to understand the language unless you understand where it’s coming from in this regard.

In particular one thing we’ve observed in #scala from people learning the language is that if you know both Java and Haskell (I presume an ML would work as well?), learning Scala becomes significantly easier. I had almost no trouble picking it up, but I know both. Ricky Clarkson seems to be in a similar boat in terms of Haskell + Java having helped. I presume others are too. On the other hand, people with Java background but not much FP seem to have more trouble and people coming from a predominantly ruby or python background have a harder time yet. (I don’t know what happens to people coming from a Haskell with no Java background. I’d expect a similar degree of confusion to the Java with no Haskell background).

Some of this is probably in terms of material - a lot of Scala tutorials, etc. out there seem to assume you already know Java. This is probably largely accurate but seems like a mistake in the long-term to me. On the other hand, I’d be really uncomfortable teaching Scala as a first language, so what languages *should* they be learning to prepare the way? Anyone tried learning it on the basis of, say, Ruby + OCaml?

So, what do we want people’s path into Scala to be? Should we suggest they learn Java first if they don’t want a bit of a rough start, or is there a better way?

Java collections and concurrency

Monday, January 14th, 2008

This is a general tip about Java collections and concurrency. I’m not the best person to write about this, so I’m going to keep this post limited to a simple note, but it’s an important point which far too many people get wrong.

There are various methods in Collections such as synchronizedList, synchronizedMap, etc. These are for wrapping non threadsafe collections in a way that synchronizes important operations.

Don’t use them. Ever.

In a similar theme, never write code that looks like the following:

synchronized(myMap){
  doStuffTo(myMap);
}

Concurrency is not an afterthought. If you’re going to be doing concurrent programming you should be using datastructures designed for concurrent use. java.util.concurrent has a number of good ones. Further, you should avoid explicitly synchronizing if at all possible and have your structures be internally threadsafe. If you try to ensure thread safety by synchronizing on the structures you’re mutating you will

a) Make a mistake. Almost certainly. This will introduce bizarre bugs which you will have a serious headache tracking down.
b) Have worse concurrent performance than using a properly designed datastructure - e.g. a ConcurrentHashMap has finer grained locking, so it actually is possible for multiple threads to write to it in a safe manner.
c) Have really ugly code with synchronization logic spread all over the place. This is not a minor point - if your threading code is simple, it’s much easier to determine if it’s correct (although still not easy).

More Asus hilarity

Thursday, January 10th, 2008

So, Asus have managed to accrue some more black marks this week.

I called on monday to say “Hi, now that you’ve had a look on it could you give me a more useful answer about how long it’s going to take to repair my laptop?”

Their answer: “We can’t find anything wrong with it. Could you send us your power supply?”.

Ok, that’s something at least. I tested on every conceivable combo of power supply and battery, but I suppose it’s possible that the power supply conked out and the battery ate itself as a result and couldn’t recharge from it.

Anyway, I said no, could they just send me the laptop back, I’ll buy a new power supply. (Subtext: These people are so fucking slow that if we get into the sending random parts back and forth game I’ll never get my laptop back). And, incidentally, had they been planning to tell me this at any point?

“Oh, yes, we would have called you today”.

Fuck they would have. Asus and their subsidiaries have not once volunteered information without me having to drag it out of them. Anyway, they agreed to send it back.

Fast forward to today. They managed to score two black marks.

a) They delivered the power supply I purchased. To the wrong address. I very explicitly gave my work address as the delivery one, so they cheerfully delivered it to home instead. ‘Fortunately’ I overslept dramatically (I was at work till 11:30 laat night. :-( ) and was still there when the package arrived.

b) I still don’t have a laptop returned, so I called them up today. After much being on hold, getting randomly hung up on, and general intense annoyingness of their phone system it was confirmed that no they had in fact not made any note whatsoever of an intent to send it back. They claim it will be sent out today and should arrive tomorrow. We’ll see.

At this point I’m almost tempted to just buy a second laptop from Dell even if the new power supply works perfectly. The benefits of never having to deal with these people again are surely worth the price of a laptop…

Minor revelation about Scala existential types

Wednesday, January 9th, 2008

So, I’ve just realised why Scala’s existential types are several orders of magnitude more powerful than Java’s wildcards.

   def swap(xs : Array[T forSome { type T; }]) = xs(0) = x(1);

The type is not completely unknown, and is persisted across method invocations, so for a given fixed instance you can make use of that to perform operations that would be impossible with wildcards. In particular the following can’t work:

  public void swap(List<?> xs){
    xs.set(0, xs.get(1));
  }

This can’t work, because Java has no way of determining that the two wildcards in xs.set and xs.get are the same.

Dereferencing operators

Sunday, January 6th, 2008

I’m writing a small library for mutable reference cells. This has spawned a heated debate about what to call the dereferencing operator. Possible options for dereferencing foo are:

One of the big questions is whether it should be postfix or prefix. If it’s postfix, using them as properties becomes much more readable. foo.bar! vs. !(foo.bar). But it also runs into weird precedence issues. On the other hand, the set of characters which can be used in a prefixy manner is really limited and they all seem to have significant meaning.

!foo

Pros: Historical precedent. It’s what ML uses.
Cons: Very easy to confuse with negation. Suppose foo is a reference to a boolean. if (!foo) { } is potentially really confusing.

foo!

Pros: Same as !foo. Less confusing - it’s not currently used by anything major.
Cons: Retains misleading association with negation, although less easy to write confusing code.

foo&

Pros: Historical precedent. Looks almost like C (prefix & isn’t legal).
Cons: Similar confusion to !. & more normally means and. On the other hand, C programmers seem to have gotten used to it.

@foo
Pros: Nice distinctive character. Easy to get used to.
Cons: It isn’t legal Scala (this is kinda a big one :-) ).

~foo
Pros: Same as @. Legal Scala. :-)
Cons: Prefix operator, so doesn’t work well with properties. Somewhat non-obvious.

foo<> (credit to Bob Jones… err. I mean Jan Kriesten for this one)
Pros: Visually distinctive and appealing.
Cons: Looks vaguely directional.

foo^ (credit to Martin Odersky)
Pros: Um. Beats me.
Cons: Confusion with xor. Looks weird.

foo deref

Pros: Fewer weird precedence issues because it’s not an operator. Some people seem to like wordy operator names.
Cons: Visually distracting, overly verbose. Scatters meaningless words throughout the code. Core operations should have nice symbolic notation.
Additional cons: Over my dead body.

foo() (credit to Eric Willigers)

Pros: Interacts much better with precedence rules than any of the others. You can write foo() == “Bar” whereas you’d have to write (foo!) == “Bar”. It seems intuitively obvious what invoking a reference should mean.
Cons: I don’t really have a good argument against this except that it feels wrong. It looks a little weird when you have a reference to a function. e.g. if you had a Ref[() => Unit] it would be potentially easy to write myRef() and think you’d invoked it, when in fact you’d merely returned a function.

Any of the above with an implicit conversion from references to their contents
Pros: The mainline case is syntax free.
Cons: No no no no no no no. This creates *exactly* the sort of confusion between reference cells and their values that I’m trying to avoid, and opens up the possibility of huge classes of subtle bugs where you passed a reference to an object and meant to pass the object. I initially thought it was a good idea, and it has a strong intuitive appeal to it, but I’m convinced it would be disastrous. A slight conciseness advantage in no way offsets the introduction of perniciously evil bugs.

On balance I think foo() is going to win. The precedence issues seem to prohibit the use of any sort of postfix operator. This seems to leave ~foo as the only good alternative, and I think it’s less obviously meaningful and the prefix nature would annoy the properties people.