Live data from Hacker News

The New Haskell Homepage

new-www.haskell.org

231–240 of 258 posts

Re: The New Haskell Homepage

#231
post #191

Earlier quoted context omitted.

I too dislike tutorials focused around the REPL, because it's rarely how you write code in practice. The REPL is more of a debugging tool for quickly testing and manipulating code you've already written. I'd jump directly into creating code files/modules - begin by creating simple programs using `main` as you would in other languages. Create a file with ".hs" extension, (Haskell filenames start with capital letters b…

Thanks for the help, though Vim is already my choice for insanely-powerful text editor with 2k+ page user manual :) I tried emacs, but the dependence on the control key for everything makes it kinda painful on every keyboard I have. I suppose I could probably remap a bunch of keys or something, but Vim seems to work much better in the default configuration. I know this tends to be a big flamewar subject, so it is wha…

So, write the same thing but in Vim macros...

Re: The New Haskell Homepage

#232

Earlier quoted context omitted.

For a function f and a value x, foldr f x [a,b,c] gets turned into f(a, f(b, f(c, x))) '(:)' is list concatenation, so the result is 1 : (2 : (3 : [])) (Here we are writing list concatenation in infix notation, rather than the customary prefix notation). '[1,2,3]' is shorthand for 1 : (2 : (3: [])) in Haskell.

Thanks, I appreciate the walk through. So it's essentially just copying an array (in this particular example). I'd still argue that the syntax is not natural - since you have to have specific knowledge of the operator and the function.

Syntactic naturality seems like it's mostly a function of familiarity. That said, the example has, for a lot of mathematical reasons, a great deal of semantic naturality.

It's far from immediately obvious, but `foldr (:) []` is the way to copy singly-linked lists. In particular, if you look at a linked list as a degenerate tree then what `foldr f z` does is replace all of the nodes with `f` and the single leaf with `z`. Since cons, i.e. (:), creates a node and nil, i.e. [], is that single leaf then `foldr (:) []` is a very natural way to do nothing at all.

So it's kind of the most boring interesting example imaginable.

Re: The New Haskell Homepage

#233
post #179
post #52

Please, get rid off the primes example, as it is horrible inefficient (in the sense of, "Ok, let's find the first n primes by a simple well-known algorithm, like the Sieve of Eratosthenes") and a simple (non-pure) array-based approach will kick its ass. Such a toy-example just contributes to the wrong belief that Haskell is just useful in academics or teaching. Some time ago I did implement the sieve in several langu…

> Please, get rid off the primes example, as it is horrible inefficient (in the sense of, "Ok, let's find the first n primes by a simple well-known algorithm, like the Sieve of Eratosthenes") and a simple (non-pure) array-based approach will kick its ass. The primes example may be a bit awkward for people with no background in math but it's also an excellent example to demonstrate lazy evaluation in Haskell. The inte…

Even though it's a good example, I think extra care should be taken to avoid the stereotype that Haskell is elegant for math and academic stuff but not for the real word.

Re: The New Haskell Homepage

#234

Earlier quoted context omitted.

I'd like to see the Documentation, Community and News content on the front page, rather than hidden away on those separate pages. The new design adds an extra, unnecessary level of indirection in order to get to this useful information.

Fair enough, but as other posters have noted there's no reason why those contents need to be placed directly at the home page; they could be located at an inner page that you'd bookmark for reference. The purpose of a good landing page is not to serve as an index for all the content (that's what site maps are for), but to explain the concept and structure of the site to someone that haven't seen it before. The new pa…

I don't want to deal with numerous bookmarks to internal pages, or site maps, or any crap like that.

I want to be able to type "haskell.org" into any browser, and from there be able to quickly get to the standard library documentation, to the language spec, to Planet Haskell, to the downloads, and so on, without having to dig through subpages of subpages of subpages, and without having to scroll.

The Rust website at http://www.rust-lang.org/ is a good example of how a programming language home page should be laid out. There are many relevant links at the top. I can almost always find what I want within the first inch or two of the page. Yet it still shows all of the marketing junk for those who want that stuff, but it's placed well below the useful content.

The new Haskell design is the complete opposite of that. It puts a lot of useless junk front and center, and almost totally discards everything that actually is useful.

Re: The New Haskell Homepage

#235
post #155

Earlier quoted context omitted.

I love the tutorial! I couldn't help writing down some notes while going through it, here they are if you're interested in reading: - Really would love to return to previous steps to review things (for example, reviewing what the difference is between a list and a tuple) - "You just passed the (+1) function to the map function." But didn't I also pass [1..5] to it too? It's unclear to me whether map is a function whi…

Not sure if you would like to know some answers to your questions, here are they anyway: - It's unclear to me whether map is a function which takes two arguments ... or if the first part "map (+1)" evaluates to a function which acts on [1..5] The latter is true. In Haskell you can pass arguments to functions one at a time each time the result could be a function that takes another argument. You might even say that Ha…

- You might even say that Haskell functions always take one argument

This is exactly true. Every Haskell function takes either zero arguments, or one.

Re: The New Haskell Homepage

#236
post #172

Earlier quoted context omitted.

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.

Even the one-liner form at the end? This comment was really bad at exposition, but I think it got somewhere nice.

Well the one-liner form I probably have overseen. It's a lot better than the other variations but I do think that the fibonacci example does show Haskell in a much more understandable way than the allRationals one-liner.

But maybe that's a bit me: I don't particularly like one-liners because as an outsider it takes usually a bit more time to understand it than more lines..

Re: The New Haskell Homepage

#237

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…

What is pattern matching really used for? The way it's presented in these examples it feels like a complicated version of Python slicing.

Re: The New Haskell Homepage

#238
post #205

Earlier quoted context omitted.

That's still the same problem, isn't it? You still have to track down where the empty list originated, just as the null value in C. I'm not a Haskeller, but do the language and tools make that easier than in other ecosystems?

What makes it easier is immutability - if given an empty list, the only place that could've made this list empty is the place it was constructed - because there's no way some other function can come and delete items from it. A function which "removes" items from a list doesn't actually do such thing - it creates a brand new one and adds all the same elements except the items you requested being removed. In this way,…

And there is a billion ways how to construct an empty list. You can't just grep for '[]'. It can be hidden inside of a 'catMaybes', 'tail', or any other function which returns a list and makes no guarantees about it's size, of which there are plenty.

Re: The New Haskell Homepage

#239

Earlier quoted context omitted.

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…

What is pattern matching really used for? The way it's presented in these examples it feels like a complicated version of Python slicing.

Well, you can use it to match on any value. So it's more useful than just slicing up lists.

Python has a primitive form of pattern matching in the form of unpacking, for example, this is legal code:

    def tuple_decomp( (a,b) ):
        return a+b
You pass in a 2-tuple (1,2) and 1 gets put into `a` and 2 gets put into `b`. It will error on anything but a 2-tuple.

As I showed in my examples, which I think you might have overlooked if you only saw the list slicing example, it provides a nice way of writing base cases for recursive functions:

    factorial 0 = 1
    factorial n = n * factorial (n-1)
as opposed to

    factorial n = if n == 0 
                    then 1
                    else n * factorial (n-1)
It's also really useful if you have a special case that you can provide a better implementation for:

    multiply 0 _ = 0
    multiply _ 0 = 0
    multiply n m = n * m
The _ means "ignore this argument, I won't use it". So in the case that either arg is 0, we just fast-fail and return 0. Since Haskell is lazy, if I say

    multiply (f (g (h 999))) 0
where f(g(h 999))) is going to be some huge time consuming computation, the call will return instance because it will see the 0 and never even evaluate the first argument.

In C et al, the arguments to a function are evaluated before they are passed in, so if I say

    multiply( f(g(h(999))), 0);
It will calculate the value of f(g(h(999))) and send it in. In Haskell, you just send in a sort of pointer which points to the unevaluated expression, which, if you ask for it, will be evaluated.

Using pattern matching for decomposition is particularly useful in Haskell because of the custom datatypes. In Haskell, you can sort-of think of a data type as a C-union of C-structs. Let's say I define a datatype for Pets.

    data Pet = 
        Cat {
            color :: String,
            breed :: String,
            annoying :: Bool
        } |
        Dog {
            breed :: String,
            trained :: Bool
        }
So I can make a Cat or a Dog, but both are still of type Pet. They contain different parameters within them. So I can't ask a Cat if it's trained, and I can't ask a Dog if it's annoying.

Let's say I want to make a function to determine if I like a pet. My criteria are: I only like trained dogs. If a Dog is trained, I like it. As for cats, I like it if it is not annoying, or if it is Yellow.

Rather than a mess of if statements, it's much more elegant to use pattern matching!

    likePet (Cat "Yellow" _ _) = True
    likePet (Cat _ _ False) = True
    likePet (Cat _ _ _) = False
    likePet (Dog _ True) = True
    likePet (Dog _ _) = False
So as you can see, I can pattern match on constructors (Cat or Dog), and on the values within the types without putting any code in the actual function body! Compare that code to the same code with if statements and tell me which is prettier!

Re: The New Haskell Homepage

#240
post #235
post #155

Earlier quoted context omitted.

Not sure if you would like to know some answers to your questions, here are they anyway: - It's unclear to me whether map is a function which takes two arguments ... or if the first part "map (+1)" evaluates to a function which acts on [1..5] The latter is true. In Haskell you can pass arguments to functions one at a time each time the result could be a function that takes another argument. You might even say that Ha…

- You might even say that Haskell functions always take one argument This is exactly true. Every Haskell function takes either zero arguments, or one.

As said by thinkpad in this thread somewhere, Haskell functions are unary.
Post reply on HN