Live data from Hacker News

The New Haskell Homepage

new-www.haskell.org

101–110 of 258 posts

Re: The New Haskell Homepage

#101

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

[deleted]

Re: The New Haskell Homepage

#102

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

I feel that this is a result of many Haskell users (and, likely, the writer of that example) being more familiar with mathematical notation than the average programmer. With the correct unicode replacements set up in your environment, it's sometimes hard to remember that you're actually writing code! (IHaskell has these by default)

For a declarative language like haskell, mathematics is arguably a much saner inspiration for notation than C/C++. I recommend avoiding any temptations to relate the two. When you see "return" or "class" in the code, treat it as a completely new idea.

Re: The New Haskell Homepage

#103
post #51
post #12

Neat! A nitpick: I haven't used Haskell, so I'm trying to read the prime sieve example in the corner, but there's very little contrast between the background and the nonalphanumeric characters. Some brighter syntax highlighting would be a better choice against that dark background.

Also maybe pick a simpler example and not play into the stereotype that Haskell is for people who think they are smarter than everyone else.

I think it's fine, but could use an "explain" link like on the http://racket-lang.org/ homepage.

Re: The New Haskell Homepage

#104
post #62
post #59

Earlier quoted context omitted.

Could you suggest a simpler example? Finding primes is something that is taught in the first programming class in Indian high schools. I guess I've never thought of it as something hard. I looked at nodejs.org, and their first example is a web server! Python has the Fibonacci as it's second example (the first one show's numeric operations). Ruby does simple string operations on it's home page. While I think that is i…

Well, for one, it's a bad sieve algorithm. I think a neat algorithm to demonstrate laziness and Haskell clarity would be enumerating the Calkin-Wilf rationals. [0] It's quite a bit longer but demonstrates a number of neat ideas. I'll start first with a derivation which demonstrates all of the structure of the algorithm and then go through a series of mechanical transforms so that by the end I have a one-liner and a c…

To be honest: This would turn me off even more than the current example which is also hard to read/understand as a non Haskell programmer. The fibonacci example in another comment in this thread however is very easy to understand and would fit much better.

Re: The New Haskell Homepage

#105

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

I agree, especially about the ":: Num a => a" stuff in the tutorial. berdario's comment above is illuminating, but it was pretty confusing and distracting while doing the tutorial. Not to say it shouldn't be there (I'm guessing it's important) but it should be explained.

Some acknowledgement would go a long way-- in the first "slide" after you see that, a sentence about the output format seems appropriate.

Re: The New Haskell Homepage

#106
post #94

Well, it sure looks nicer, I'll give you that. I'm more interested in the content, though. I was just trying here and there over the last week or so to learn some Haskell - people always seem to be raving about how cool it is. I found my way to the CIS 194 class link, the first one on the page, and I find that it really isn't very good for learning. I went through the first page, trying to run some of the stuff. I fi…

It sounds like you're looking for Learn You A Haskell. Great book, free too read online, tells you how to start with Haskell step by step. http://learnyouahaskell.com/chapters

Re: The New Haskell Homepage

#107

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

Being a god in C++ won't give you anything regarding foreign paradigms. Are you familiar with other FP languages such as ML, Miranda or even Lisp ? More than syntax it's the semantics that differs a lot. Laziness, Immutability...

Re: The New Haskell Homepage

#108

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

Ok I'll take a stab at a super high level crash course:

A note! Haskell has weird syntax. But it actually uses this syntax in cool ways, as opposed to some languages that have weird syntax in an effort to be different.

Let's consider the basic unit of Haskell programming -- the function!

Here is a function which returns its input:

    f x = x
Notice that there are no parens or types or anything. Since functions are used so heavily, polluting them with parens would make your code look uglier than lisp.

Now notice that I didn't include a type signature. In haskell, you can omit them if you want. The compiler will figure out the most general type. Think of this as C++11 `auto` keyword on steroids.

If I were to include the type signature, it would look like this:

    f :: a -> a
    f x = x
Let's break down those symbols.

`::` just means "is of the type". So `f :: ...` is "function f is of the type..."

`a` is a type variable. Think of this like C++ templates! In C++, an equivalent function is

   template 
   T f(T x) { return x; }
Where `T` is the same as our `a` in Haskell. In Haskell, it's common to use the first few letters of the alphabet for type variables.

The `->` syntax is a bit funny, but it makes sense when you learn about function currying, which I will not explain now because it can be intimidating to some. For now, just think of the type signature as

    arg1Type -> arg2Type -> ... -> argNType -> ResultType
So for our function `f` of type

    f :: a -> a
That means "The function f takes some argument of type `a`, and returns a value of the same type `a`"

Now let's consider a more complex function.

    f x = 2 * x
As you can see, this is a doubling function. It takes a value and doubles it. We can imagine that the value it takes can't be any arbitrary type, because not all types can be doubled! So it doesn't make much sense to pass in a string.

In Java style, we might say that the type must implement the interface `Multipliable` or something. It turns out, Haskell has a system that is very roughly similar to Java interfaces or in C++, a class with a bunch of virtual methods.

Haskell calls these Typeclasses. So there is a typeclass that specifies that types in the typeclass must implement some basic numeric methods, such as +, -, etc. This typeclass is called `Num`.

So we can imagine, our doubling function only takes types that implement `Num`. Our type signature reads:

    f :: Num a => a -> a
    f x = x * 2
So everything between the :: and the => is typeclass specifications. So in this one, I just specify that type `a` must implement `Num`. Let's say I also required `a` to have the equivalent of a Java `toString` method, I would say:

    f :: (Show a, Num a) => a -> a
So now `a` must have a `toString` style method and must have numeric methods.

Now we are ready to approach the `primes` bit.

The first foreign looking thing is [2..]. This is an infinite list from 2 to infinity. How can one have an infinite list? The answer is laziness.

Whenever I go and ask for the 10000th value, the list must extend itself to that value if it hasn't yet. So the list only grows for as much as you ask for, but in theory it will grow until you run out of memory.

The [m..n] syntax is just nice syntactic sugar because it's used so much. [1..10] == [1,2,3,4,5,6,7,8,9,10]

[1..] == [1,2,3,4,5,....infinity]

So this is what we know so far:

    primes = sieve [2..]
Which means "primes is equal to the function sieve, called on an infinite list from 2 to infinity"

Now you ask, well what the hell is the function `sieve`?

Haskell has a nice sugar for defining scoped functions within other functions with the `where` keyword.

Consider the doubling function. I could instead do:

    f x = x * (three - one)
      where
        three = 3
        one = 1
So it just let's you define values that get used in the function body in a convenient place. This is akin to math jargon where people say "blah blah x something blah where x is blah".

So `sieve` is a scoped function (cannot be accessed from outside of `primes` that takes a list as an argument and apparently produces the primes that are in that list. How does it do it?

We see some weird syntax in the definition of `sieve`:

    sieve (p:xs) = ...
What is this? It's pattern matching. Let me use fake C++ as an example. Consider the recursive factorial function:

    int fact(int n) {
        if(n == 0) return 1;
        return n * fact(n-1);
    }
Now imagine if C++ let you do this instead:

    int fact(0) { return 1; }
    int fact(int n) { return n * fact(n-1); }
That is, you make a special case function body when the argument is 0. At runtime, if the arg is 0, it uses the special case body, otherwise it falls through to the general body.

So in Haskell, we could implement factorial like

    fact :: Num a => a -> a
    fact 0 = 1
    fact n = n * fact (n-1)
Very clean and sexy! But now you say "Yeah, but I could just use an if statement or a switch..."

Now we go into the funny syntax and power of that funny syntax! Not only can pattern matching match on values, but it can decompose those values. What do I mean? Again, let me use some fake C++ as an example.

Consider the C++ function

    int f(pair my_pair) {
        int x = my_pair.first;
        int y = my_pair.second;
        return x*y;
    }
Ignore that there is no real reason to pull the values out into `x` and `y`. In a more complex function, I'm sure you can understand why it would be tedious to type `my_pair.first` over and over again and we would want to pull it into `x` or something.

Now imagine if C++ let us do this:

    int f(pair) {
        return x*y;
    }
That is, f takes a pair, and in the type declaration we decompose the pair into its first and second parts, assigning them to the variables `x` and `y`. In Haskell, this is trivial.

Consider a direct translation of the C++:

    f :: (Int, Int) -> Int
    f my_pair = fst my_pair * snd my_pair
Now the idiomatic Haskell, with pattern matching decomposition:

    f :: (Int, Int) -> Int
    f (x,y) = x*y
Slick, right?

So what is `sieve (p:xs)` decomposing?

In Haskell, the default [] list is a linked list (there are random access arrays in various libraries). That means we can stick a value onto the front of the list in O(1) time. The way we stick a value onto the front of the list is with the `:` operator.

So

    x = [1,2,3]
    y = 0:x
`y` is now [0,1,2,3]

Just like we can compose lists with the `:` operator, we can decompose them via pattern matching with it.

So consider the function (I'll omit the type signature for brevity)

    f (p:xs) = print (p, xs)
Let's say we give `f` the argument [1,2,3,4]. What call to `:` would we have to make to get this list?

    [1,2,3,4] == 1:[2,3,4]
So when we send [1,2,3,4] into `f`, it gets decomposed into ` 1:[2,3,4] ` where 1 gets put into `p` and [2,3,4] gets put into `xs`.

This is a very common idiom in Haskell. Let's say I wanted to make a function that added 1 to every value in a list. Ignoring that there are much cooler/efficient ways to do this in Haskell, let's make a specialized function for it.

    addOne (x:xs) = x+1 : addOne xs
So let's read through that. In our pattern matching decomposition, we pull off the first value of the list and store it in `x`, and we take the rest of the list and store it in `xs`.

Now in our function body, we recompose a list with different values. Those values are `x+1` for the first value, and `addOne xs` for the second value. So we add one to the first value, and stick it into the front of the rest of the list after the rest has had 1 added to its values. You might notice now, that there is no bottom-out case for this recursion. So let's add one.

    addOne [] = []
    addOne (x:xs) = x+1 : addOne xs
So we pattern match to catch the special case of the empty list, which returns the empty list, and then we decompose the general case as previously explained.

So `sieve` is pulling off the first value, storing it in `p`, and taking the rest of the list and storing it in `xs`.

It is returning...

    p : sieve [x | x 
So, that is `p` stuck onto the front of...

    sieve [x | x 
And we know that sieve returns all of the primes within its argument, so in English...

    p stuck onto the front of all the primes in [x | x 
So now what the hell is [x | x Hackernews said my comment was too long. Read the rest here: http://pastebin.com/UesYMjjJ

Re: The New Haskell Homepage

#109

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

Being a god in C++ won't give you anything regarding foreign paradigms. Are you familiar with other FP languages such as ML, Miranda or even Lisp ? More than syntax it's the semantics that differs a lot. Laziness, Immutability...

Not really. No. And that's the problem! You're right that semantics are what make the languages truly different. However it is literally impossible to even begin to understand semantics if you don't know the syntax. That's what is so frustrating. It might as well be written in Kanji. That's how meaningless it is to me and, I believe, most programmers.

Re: The New Haskell Homepage

#110

I get paid to write C++ code. I'm pretty good at it. I understand it's normal usage syntax very well. I don't fucking know what a god damn thing means in Haskell. λ 5 + 7 12 :: Num a => a What the christ? The 12 I get. Got it. The colons? Not sure. I think it's just a dumb separator. Num is type! What the hell is a => a? I have no idea. In the top they have an example. primes = sieve[2..] where sieve (p:xs) = p : sie…

Ok I'll take a stab at a super high level crash course: A note! Haskell has weird syntax. But it actually uses this syntax in cool ways, as opposed to some languages that have weird syntax in an effort to be different. Let's consider the basic unit of Haskell programming -- the function! Here is a function which returns its input: f x = x Notice that there are no parens or types or anything. Since functions are used…

Thanks for the reply. Some good stuff there. Very meaty and it's gonna take time plus a few read through a to chew through it all. Thanks!
Post reply on HN