onsdag 24 augusti 2011

Scala Perspective Does Not Show Up in Eclipse - Solution

I just wanted to share a painful lesson so that, hopefully, nobody has to repeat it.

I tried to install Eclipse and the Scala plugin, but after I installed the Scala plugin it wouldn't work. The Scala perspective just didn't show up after the restart. Googling on the problem did not help. It turns out that the problem wasn't with Scala - the problem was that I incorrectly tried to run a 32-bit Eclipse on Mac OS 10.5.8, which is 64-bit. Eclipse will not give an error message of the type "You are trying to run 32-bit software on a 64-bit OS". Things will just randomly stop working with no error messages.

söndag 30 januari 2011

My First Haskell Program

I finally found the time and energy to do some hobby programming (which has been sorely lacking the last few years, unfortunately). The target of my efforts was Haskell this time around. I've meant to look into pure functional languages since i think even high-level OOP engineers such as myself can benefit from a lot of the ideas in functional languages. Additionally, functional languages are becoming increasingly interesting in highly threaded and distributed environments. And as we all know, that is pretty much where we are heading.

Just to try Haskell, I wrote a program that takes an integer between 1 and 999 and reads it out as you would speak it in Swedish. E.g, 100 -> etthundra, 765 -> sjuhundrasextiofem, and so on. This is a good exercise which forces you to use basic flow control, functions and recursion. This is the result:

module Main (main) where
import System (getArgs)

speak :: Int -> String
speak 0 = ""
speak 1 = "ett"
speak 2 = "två"
speak 3 = "tre"
speak 4 = "fyra"
speak 5 = "fem"
speak 6 = "sex"
speak 7 = "sju"
speak 8 = "åtta"
speak 9 = "nio"
speak 10 = "tio"
speak 11 = "elva"
speak 12 = "tolv"
speak 13 = "tretton"
speak 14 = "fjorton"
speak 15 = "femton"
speak 16 = "sexton"
speak 17 = "sjutton"
speak 18 = "arton"
speak 19 = "nitton"
speak 20 = "tjugo"
speak 30 = "trettio"
speak 40 = "fyrtio"
speak 50 = "femtio"
speak 60 = "sextio"
speak 70 = "sjuttio"
speak 80 = "åttio"
speak 90 = "nittio"

speak n = let 
            hundreds   = floor(fromIntegral(n) / 100)
            tens       = computeTens n hundreds
            single     = fromIntegral(n) `mod` 10
          in
            if hundreds > 0 then 
                speak(hundreds) ++ "hundra" ++ speak(tens * 10 + single)
            else
                speak(tens * 10) ++ speak(single)

computeTens n hundreds = 
            let withoutSingle = floor(fromIntegral(n) / 10)
            in withoutSingle - hundreds * 10

parse args = read (head args)::Int

main = do
    args <- getArgs 
    print (speak (parse args))

I think the program ended up being quite nice in Haskell. Writing it was not entirely easy, though. Haskell is statically typed and uses type inference, and this system can be quite hostile to newcomers. I think it is a system which pays off more as you learn the language since you don't have to clutter your code with type declarations. As a beginner, though, it can be quite puzzling. For instance, I never quite understood why I have to use fromIntegral in the let block or why the fromIntegral calls seems to produce different types depending on if it goes into a division or modulo expression.

I think certain parts of the language design causes the compiler to be confusing. For instance, computeTens initially took one argument. I added another argument later while developing. Unfortunately, I forgot to change the caller to provide the second argument. In most languages you would have gotten something like 'function computeTens expects 2 arguments, got 1'. In Haskell, it will say 'expected Int, inferred t -> t1'. The reason for this is that Haskell uses function currying in all invocations, so calling a function with too few arguments will just produce another function. This shows that you need certain skill to decrypt what the compiler tells you.

Also, Haskell has some annoying idiosyncrasies. For instance, there is an Int and an Integer type, and they are NOT the same thing.

Other than those gripes, I thought it was quite fun to use and seems to be really good system. Now that I have the basics nailed down I will start looking at Monads and other interesting ideas Haskell brings to the table. I'll see if I can rediscover some of the techniques with lazy evaluation and higher order functions I learned in school as well. More on that later!