Learn another languge

This is a discussion on Learn another languge within the A Brief History of Cprogramming.com forums, part of the Community Boards category; I whole heartedly recommend Haskell. I've been playing with it more and more and have come to really love it ...

I whole heartedly recommend Haskell. I've been playing with it more and more and have come to really love it (you can't beat cabal and quickcheck for packaging and testing code.) The expressiveness is great. It works as a scripting language pretty well too. Other than Haskell, there's also OCaml which is pretty interesting in itself, although I never got into it.

If you're not interested in functional programming languages, check out Ruby or Perl instead (I've been getting interested in trying out perl 6 recently, I experimented with it once and it wasn't bad at all.)

And of course, the language I think every programmer should learn (or at least try a little): Lisp.

I whole heartedly recommend Haskell. I've been playing with it more and more and have come to really love it (you can't beat cabal and quickcheck for packaging and testing code.) The expressiveness is great. It works as a scripting language pretty well too. Other than Haskell, there's also OCaml which is pretty interesting in itself, although I never got into it.

I found the following resource pretty helpful when teaching myself Haskell. It's called "Haskell for C Programmers" and it helped me sort out a lot of stuff that had me stuck before:

My personal vote goes to Python. People hate it because of the whitespace thing, and because it is only "pseudo-functional" but I think it's a perfect match of an imperative backbone with some carefully chosen functional concepts.

It really isn't, it just seems totally mind-blowing when you first get into it (and it really is when you've never done functional programming before.) It took a while of just writing random and interesting little code snippets before I got a good handle on it.

While learning Haskell, I probably wrote more little dumb programs and snips of code to get the hang of it than any other language I've done the same with, because I find programming in Haskell quite fun and interesting. You'd be really suprised at what you can make using some of the languages features.

Is there anything that one might acomplish faster or at all with Haskell than they would with c/c++?

Or if you wanted every line in the file reversed and outputted in regular order:

Code:

module Main where
main = interact (unlines . (map reverse) . lines)

Once you get used to it, you really, really begin to appreciate things in functional programming like higher order functions and monads. And there're even other benefits that're simply side effects of a functional programming language such as Haskell. Example: due to Haskell being a pure functional programming language, i.e. it eschews side effects (no global variables), haskell code is referentially transparent (which basically means that "f(x) = f(x)" in all cases), which is a factor in parallel execution of code on things like multiple cores.

One thing you could learn is regular expressions. They can be really useful, and like KONI mentioned, it's something that can be used in many languages for many things. I first used regular expressions in Perl, but Python and probably Ruby and C or C++ with the right libraries (<regex.h>) support them too. It's just easier to say

"Simplicity does not precede complexity, but follows it." -- Alan Perlis
"Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
"The only real mistake is the one from which we learn nothing." -- John Powell

Is there anything that one might acomplish faster or at all with Haskell than they would with c/c++?

I'd like to apologize in advance for this ramble.

Um, everything? :-) Well, not everything. Maybe.

It's a good language for making window managers. I have recently enjoyed writing a patch for xmonad, a 3-week-old baby written in Haskell. And it's apparently good for version control systems (darcs). And programming language interpreters (pugs). The last one is an example of "at all". It's also great at parsing, which is trivial in the language. (It's near trivial in Scheme or O'Caml, too.) It's used for a bunch of computer sciencey, research type things, too.

It's probably a bad language to use for a text editor extension language, but some people are trying...

If you were to have a months-long race between a C or C++ person and a Haskell person for the creation of some non-trivial application, I consider it a fact, without exaggerating at all, that the Haskell person will finish it more quickly. And the C++ program will be more buggy, and the Haskell version will run faster. If you had a really good C++ programmer, they'd run at the same speed. And if you were to force the Haskell programmer to stop and wait for the C++ programmer to catch up, and at that point change the specifications of the task, the Haskeller will fix things more quickly than the C++ programmer. I say all this without evidence. Well, besides the contrived evidence given by the ICFP programming competition. One reason I act sure that the Haskell version will run faster is that even if there's some operation like image manipulation that Haskell code won't do quickly, the Haskeller could always just drop down in C for that one particular algorithm. Which is sort of a cheap reason, but hey, it's a practical advantage.

The main problem with Haskell, I think, is learning it. When it comes to relying on past experience, it's just one big nsry. There are a few mental transitions I'd say you have to make.

1. Thinking that a function "does" something vs. thinking that a function "is" something. Instead of thinking in terms of algorithms, you have to think in terms of mathematical equivalence. Well, you don't want to have to think that way, but you should (in combination with all other ways of thinking) if you don't want to suck.

2. Tail recursion. Some people are familiar with the notion, but that depends on what language you're coming from. If you're coming from C or C++, it's the notion that the stack doesn't grow on tail recursion. If you're coming from Scheme, it's the notion that the stack actually does grow on tail recursion.

3. Monads. They just have a weird name, don't they? I don't really know what a Monad is: it's like asking what .NET means. But the stumbling block is not the idea that you can have 'do print 3 ; putStrLn "Hello, world!\n"' in a program and make it work, without really knowing what you are doing. You think, "okay, do notation is for actions, which are just things." But then you see it used for lists, or for nondeterministic execution, or to make parsers, or for abstract state transformation machines, or for transactional memory... There is a monad epiphany that you have to go through, and then you get it. It's a very strange pattern of abstraction.

4. Higher order functions. This one wasn't a problem for me because I already knew Scheme. Some people have had a taste for it in Scheme, or even C++. (But doing higher order programming in C++ is like dressing up a three-year old as Marilyn Manson). Most people are okay with 'map' -- it's foldl that gets them. Of course, you shouldn't use foldl. Use foldr. Why? Laziness.

5. Laziness. This one isn't so bad. It's when people use it for things like fibs@(_:fs) = 0 : 1 : zipWith (+) fibs fs that it gets you. If you're used to writing Haskell, you'll just want to curse other languages when they won't let you get away with infinite loops. And laziness isn't just good for writing infinite lists -- it's also good for say, writing parsers or anything involving infinite datastructures. (It's why writing parsers in Scheme and O'Caml is a bit more work than writing them in Haskell.)

6. Typeclasses. They're a new thing.

7. The hardest thing is the Whole New Ways Of Doing Things. You simply _don't_ use arrays. Or vectors. If you want to use an array, you should stop, think, and say, "What, am I mad?" They just aren't seen. The only time you do see them is if the data you're working on is itself array-like, such as images. Or if you're really desperate and need to use some array based algorithm. Or if you're interfacing with C. But, if you want to use them, you have to use some kind of monad. As an example, the window manager xmonad doesn't use any arrays. You'll never see hash tables, either; it's always Maps, because you can insert an element into map, creating a new one, without destroying the old one, in O(log n) time. And you never see iterators -- you can just convert your datastructure to a list and apply maps and folds. And hope the compiler will sort things out so that no list nodes actually get allocated.

There are 10 types of people in this world, those who cringed when reading the beginning of this sentence and those who salivated to how superior they are for understanding something as simple as binary.