1, 2, 3, 4, 5...
Back in October I started my latest programming project. Not some game or utility or mobile app. This project was to learn a bunch of different programming languages all at the same time. After writing the mandatory "Hello Worlds" I set about my first real task. Something simple, something easy...
What could be easier than getting a computer to do some arithmetic? After all, it’s what those ones and zeros are best at. Two and a half long months later and I’ve discovered just now easy this task really wasn’t.
I set eight CS 101-style problems revolving around arithmetic but they also included peripheral skills like user input, functions, recursion, iteration, etc. All stuff that I can rattle through in no time at all with a few Googles: "If statement in Smalltalk" and the like should give me the answers I need quick enough. Well, except that there is no "if" in Smalltalk; no sane representation of Strings in Erlang; and the uses of "return" and "echo" in BASH functions were so alien to my Java mindset, I had to ask a colleague for help!
It’s not all doom and gloom though. I was able to rattle through a lot of the languages and those that did trip me up were the ones I learned the most. Here were my eight tasks:
- Add two numbers entered by the user.
- Fizz Buzz.
- Implement the smart power algorithm.
- Calculate Fibonacci numbers recursively.
- Calculate Fibonacci numbers iteratively.
- Use Newton’s method to solve an equation.
- Print a vertical sine wave out of asterisks.
- A function to calculate the digital root of a numbers.
Ruby and Python were both easy. I’d say that Ruby was more fun to write in but Python looks easier to read and maintain. Haskell was fairly straightforward too but I googled a lot and asked for some advice on here. Of course, an iterative solution isn’t possible in Haskell but you can define the sequence using zipWith which is much faster than the usual recursive definition:
module Main where fib = 1 : 1 : zipWith (+) fib (tail fib) main = putStrLn (show (take 50 fib))
I thought Erlang might be a simple be a case of changing the syntax of the Haskell programs I had already written. It was, to an extent, but the syntax I was finding with Google made less and less sense to me as I went along. In the end, I paused and read the first few chapters of learn you some Erlang for great good! It’s an excellent introduction to the language and explains some alien [to me] concepts in a very accessible way. After rewriting my Erlang solutions without looking at my Haskell ones, I came out pretty happy with the syntax.
// In Java I might do this: for(int i = 0; i < 10; i++) // C wants this: int i; for(i = 0; i < 10; i++)
BASH had me pulling my hair out. I gave up on Google and online tutorials, and got a friend to sit down and show me how it was done. Part of the problem was the numbskull idea of trying to learn BASH by getting it to do maths. It is designed to automate tasks and do a bit of text processing. Earlier versions didn’t even have the capability to do maths. Even now, it is limited to integer maths invoked with a special syntax. For floating point calculations, you have to invoke another utility (often bc).
Then there were echo and return. I would have expected echo to write to the console and return to pass a value back from a function, and those assumptions were often correct, "often" being the operative word. Rather than passing back a value, return passes back an exit code: 0 for success and anything else for a failure. It took me the longest time to realise why all my calculations were coming out as zero.
Echo prints to the console, or rather stdout. So, when used in a function, the value goes back to the caller a bit like piping. In other words this is the return I was looking for. Actually, I’m not sure I’m 100% happy with this explanation. I think there is something important I’m missing here. Something to look out for on the next iteration!
Smalltalk went a lot better. I had no idea where to start though, and wasn’t sure Squeak was the implementation I wanted. The IDE had nowhere obvious to start writing code and the whole thing looked a bit childish. I reached for a tutorial and started working my way through it.
It turns out that the whole thing is a live Smalltalk program. The browser uses the reflective qualities of the language to navigate the classes and methods. You can change anything on the fly, and roll back when you break things. Methods tend to be small and unit testing is built in.
There is not much in the way of control structures. Instead of an if statement, you create a Boolean object (usually from a condition) and send an ifTrue: or ifFalse: message. Loops are similar. It’s all whileTrue: on Boolean closures or internal iterators on lists. It’s a nice way to program but I didn’t believe there is no conditional logic somewhere in the language. The beauty of Smalltalk is that I can go and check. I dug out the Boolean class and found the ifTrue: method was abstract. The two subclasses (True and False) have rather obvious implementations. An instance of True evaluates the block of code you pass it, False does nothing. Looks like the flow control is down to the evaluation of Boolean expressions and is handled by the interpreter.
"A line out of my recursive Fibonacci method." (n = 1 or: n = 2) ifTrue: [^1].
Far from my initial impressions of the language, I’m very impressed with Squeak, and look forward to using it for a project one day. My main reservation is deployment. I still need to look into it but I think anyone who wants to run my programs has to run them from Squeak.
Finally, I did my assignments in Lua. It was perfectly straightforward, a refreshing change.
This exercise turned out to be less to do with maths and more to do with getting to grips with the fundamentals of the languages. I think I’m in more of a position to sit down and be able to write something in each of the languages here. At least I’d know where to look for help. I’ve had a tour round all the languages’ documentations and a flick through several tutorials.
Although I’ve learned a lot, ten weeks is too long for iterations. It’s been ten weeks since I’ve looked at Ruby. To put it in perspective, the teaching part of a semester at my university is 12 weeks! It’s too long. I’m going to look at some String handling next but I’m going to set a smaller task, maybe one or two programs in each language. I hope to be back sooner with a blog article proclaiming my success!
Thanks for reading!
29 December 2011