5 Website Optimization Tips to Increase Page Speed - <AUTHOR> http://statsgram.com/blog/5-website-optimization-tips-to-increase-page-speed

<comment><USER2> I would be extremely cautious about #1 (replacing PNGs with CSS3 transforms and drop shadows). Your page load time may decrease but your website performance will suffer. For example, when we swapped out CSS3 box-shadows for repeating PNGs with the same color gradients/transparency, the scrolling performance on our page increased dramatically. I would also say from a design perspective, the 2nd Book of Mormon browser-rendered transform looks significantly worse. The edges are not being anti-aliased.

</comment><comment><USER3> My #1 Website Optimization tip is to use mod_pagespeed: <https://developers.google.com/speed/pagespeed/mod>

</comment><comment><USER4> Seems redundant with browser plugins like YSlow or PageSpeed which analyze your page loads.</comment>


Is Reuters.com Considered a "Spam Site" - <AUTHOR>

I have tried posting the below article from Reuters a couple of times and keep getting "Stop spamming us. You're wasting your time." error. Anybody else seeing something similar?
http://www.reuters.com/article/2012/07/27/us-google-data-britain-idUSBRE86Q0XQ20120727
edit -- Misspelled Reuters in Title <comment><USER2> It could be - the master list is protected, but Reuters.com doesn't have a good reputation.

See [1] for an example of confusing Reuters.com with material actually produced by the Reuters news agency that owns it.

[1] [http://www.cracked.com/quick-fixes/fluoride-lowers-your- iq-b...](http://www.cracked.com/quick-fixes/fluoride-lowers-your- iq-b.s.-headline-week/)

(And yes, I love the irony of using an article from one banned website to explain the banning of another!)

<comment><AUTHOR> Pretty ironic indeed, and slimy on Reuters part. Would be interesting to see a list of banned sites, or at least some statistics on banned sites. Anyway, thanks for the post.</comment></comment>


This robot-powered burger joint could put fast food workers out of a job - <AUTHOR> http://www.techinsider.io/momentum-machines-is-hiring-2016-6 <comment><AUTHOR> _" This is the only known image of a burger made with Momentum Machines technology."_

Hope that is a prototype shot, you would not want metal fragments with your food.

...from another article:

 _" The prototype is a miniature assembly line, with one conveyor that carries patties through a gas grill and another that deposits lettuce, tomatoes, onions, and pickles atop a bun."_

another picture, so it looks like it's the prototype cf: [http://www.xconomy.com/san- francisco/2012/06/12/hamburgers-c...](http://www.xconomy.com/san- francisco/2012/06/12/hamburgers-coffee-guitars-and-cars-a-report-from-lemnos- labs/2/) and [https://news.ycombinator.com/item?id=12025000](https://news.ycombinator.com/item?id=12025000)</comment>


Your server as a function [pdf] - <AUTHOR> http://monkey.org/~marius/funsrv.pdf

<comment><USER2> I've been thinking about structuring servers around FRP [1] and declarative programming for a while now. FRP is based on the notion of events / signals as first class objects and the ability to compose those; it has been gaining popularity for client programming in recent years [2].

For example, on a very high level, an HTTP request signal function might look like this:

      request :: Signal Request -> Signal Response

And a database request function might roughly look like this:

      requestDB :: Signal Query -> Signal [Record]

Having the basic building blocks, one could imagine building a function to e.g. extract all users:

      extractUsers :: Signal Request -> Signal Response
      extractUsers = request . createUserQuery . requestDB . showUsers

Similar signal functions could theoretically be constructed for routes, system functions, static files and so on. And since all signal functions are pure, composing those and creating ever more powerful abstractions without having to worry about system state and environment context may be a nicer way of doing server programming.

[1] Functional Reactive Programming - [http://en.wikipedia.org/wiki/Functional_reactive_programming](http://en.wikipedia.org/wiki/Functional_reactive_programming)

[2] [http://elm-lang.org](http://elm-lang.org)

<comment><USER3> It looks very similar to how yesod ([http://www.yesodweb.com/](http://www.yesodweb.com/), [http://www.yesodweb.com/book/basics](http://www.yesodweb.com/book/basics)) routes/handlers are implemented - is that what you mean?

<comment><USER2> Not quite - iirc Yesod still runs in some kind of IO monad, i.e. it is stateful. In contrast signal functions are declarative (pure).

<comment><USER3> Interacting with a DB or reading a html file from disk is in essence non-pure.

<comment><USER2> [1] is a good simple explanation of what FRP is about. A DB interaction for example can be viewed as a pure function from a signal of Requests to a signal of Records. Same with files (Signal Path -> Signal FileContents), etc.

[1] [http://elm-lang.org/learn/What-is-FRP.elm](http://elm- lang.org/learn/What-is-FRP.elm)

</comment></comment></comment></comment></comment><comment><USER4> very cool idea and also some of set of sites can be similar as pipe commands for shell</comment>


The New Haskell Homepage - <AUTHOR> http://new-www.haskell.org <comment><USER2> Please note this homepage is NOT final and it's going to see revisions before we push it out to the actual website, including many tweaks to the content and probably some styling tweaks too.

There are a lot of other things we still need to do as well, like ensure all redirects and subpages work properly.

Source: I'm one of the Haskell.org administrators, and we pushed this out only today.

<comment><USER3> Is there a practical reason why there's so much empty space with this new design, and why so little valuable content and functionality is visible by default?

Viewing the existing site in a desktop browser, I get to see the description of Haskell, and a bunch of useful links about learning it, downloading an implementation, using it, and participating in the community. Recent news items and upcoming events are also visible, as is the search field.

This new design lacks pretty much all of that. Instead of useful content, links and functionality, all I'm seeing are large areas of purple and white, and an extremely blurry photo, along with content of very limited value.

I just can't see this new design being beneficial in any way. It makes it much harder to get useful information about Haskell, which seems very contradictory to what a website like this should be doing.

<comment><USER4> Yes - the practical reason is to focus on the newcomer's experience. Information overload is actively harmful to someone coming to haskell.org to learn about the language from scratch.

Omitting content that is primarily valuable to experienced Haskellers is a feature, not a bug.

<comment><USER3> This sounds like a dangerous trade off to be making. It's reminiscent of what we saw with GNOME 3, or even Windows 8. The experience is made much worse for existing users, in a vain attempt to "simplify" the design to allegedly appeal to new users who may not even really exist in practice. It's obvious now that it didn't work well in those cases, and I don't see why this case would be any different.

As an occasional Haskell user, I'm served much, much better by the existing site than by this new design. The existing one lets me get to the information I'm looking for with minimal effort. This new site denies me that accessibility, I'm afraid to say.

I don't see the point in trying to attract new users if doing so also means harming the experiences of established users. Drawing in new users becomes pointless if retention starts to suffer.

<comment><USER5> _" This sounds like a dangerous trade off to be making. It's reminiscent of what we saw with GNOME 3, or even Windows 8."_

It's also reminiscent of what we saw with the iPhone, and nobody would say that the experience was much worse for users of previous smartphones. There are times when simplifying and giving structure to existing content just makes sense.

I'm curious, what content do you miss from the old page that can't be found in the Community or Documentation sections in the new design?

<comment><USER3> 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.

<comment><USER5> 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 page is much better in that respect.

I miss a link to the current Haskell wiki in the new design, but I definitely wouldn't expect to find a list of all the wiki pages on the land page, but available under the Documents section.

<comment><USER3> 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/](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.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER6> 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 find that the syntax of the ghci REPL seems to have almost nothing to do with the syntax shown so far. Apparently, I have to use let for every variable, which was never mentioned, and there are lots of funny tricks for how to use multi-line stuff. I still have no clue how to actually write something, compile it, and have some sort of output in the main ghc compiler. Is there a tutorial anywhere that actually helps you learn the language through doing useful things, instead of throwing a bunch of syntax that you can't do anything with at you?

Speaking of tutorials, the old page links to like 500 of them or so. I have no clue how to figure out which one to start with. If you're re-doing it, please link no more than 3 learning pages, no matter what. Have the rest in some buried page somewhere if you must, but keep the front page manageable. How is anybody supposed to make sense of however many tutorials and courses you guys have linked on the old one? I gotta figure I'm the prime audience for this stuff, but I have no idea where to start on your current page.

While I'm at it, can anybody recommend something like a step-by-step thing for people who are proficient in several other languages, but have never seen any Haskell before? Like where every little step has something you can actually type in, run somewhere, and get some sort of output?

<comment><USER7> 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 by convention, since they share the name of the module)

        main :: IO ()
        main = putStrLn "Hello World!"

Make sure the GHC bianries are in your PATH, and use the program "runhaskell File.hs" to quickly compile and execute them. Also, from ghci you can use the command (:load File.hs), if you want to debug stuff.

The preferred tool for writing Haskell though is emacs. If you're not familiar with emacs, its also a great opportunity to learn. Grab emacs 24, and open the file ~/.emacs, paste in this snippet:

        (require 'package)
        (add-to-list 'package-archives
                 '("marmalade" . "http://marmalade-repo.org/packages/"))
        (package-initialize)

Then hit M-x (M for Meta, which is typically Alt), and type _eval-buffer_ into the minibuffer at the bottom. If no errors, hit M-x and type into the mini- buffer:

        package-install haskell-mode

You can add the following to the .emacs file and use `eval-buffer` again. Also save with C-x C-s.

        (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
        (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)

Next step is to just open an empty haskell file. Create a new directory for your project with `M-x make-directory`, and create a new haskell file using C-x C-f. Add some code, and hit C-c C-l (load in ghci), and emacs will pop open a new window, launch ghci and load your code into it.

You can switch over to the ghci window with C-x o (cycle windows), and type some code into it for testing. (Note it can be quite buggy if the cursor is not in the right place - there needs to be a space after the prompt > ¦). Useful keyboard shortcuts to remember here are M-p (previous) and M-n to cycle through previously used commands. (You can rebind any keys to how you wish.)

You can also add typicall IDE features like "run without debugging" and such with simple snippets of elisp. Say if we want to bind F6 to this command, we can add this hack to .emacs, save and eval the expression.

        (global-set-key [f6]
            (lambda ()
                (interactive)
                (async-shell-command (concat "runhaskell " buffer-file-name))))

Now with an active haskell file, F6 will launch like an application, bypassing GHCI - and emacs will typically open a new window (or replace an existing one) with the stdout/stderror for the application.

That'll get you started anyway. From there, using LYAH is a good beginner resource, although it won't get you much further than past the syntax and semantics of the core language. It doesn't cover the plethora of language extensions, building projects, using cabal, haddock, quickcheck and more. I'm not aware of a single resource which covers these though - I just learned what was needed as and when by searching - the best information typically comes from one-off blogs focused on a specific problem.

<comment><USER6> 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 what it is.

Anyways, your Hello World and runhaskell are much more along the lines of what I'm looking for. Also checking out the other people's suggested Learn you a Haskell.

<comment><USER8> > Also checking out the other people's suggested Learn you a Haskell.

Just to get the minority opinion out there, I found the style of Learn You a Haskell to be insufferable. Real World Haskell is available free online[1] and has a straightforward tone of voice.

[1] [http://book.realworldhaskell.org/](http://book.realworldhaskell.org/)

<comment><USER9> I found Learn You a Haskell to be one of the best programming books I've ever read and no I'm not joking. It's a work of art.

</comment></comment></comment></comment></comment><comment><USER10> 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 languages and I also considered Haskell but set for an unpure approach (IOUArray) and it was extremely fast (getting close to C/C++ and outperforming Go, Java, etc.). Obviously such an example is not good to present Haskell's novel ideas but this toy example is worse then no example.

edit: Sorry, did not want to appear nit-picky, I like the language and the new design.

<comment><USER11> > 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 interesting bit is that primes is an _infinite_ list, containing _all_ prime numbers. Don't try to print the whole list or count the sum unless you have a computer with infinite memory :)

<comment><USER12> 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.

</comment></comment></comment><comment><USER13> It bugs me a bit that the example code is brute force trial division instead of a true prime sieve. Sure, it highlights lazyness but the algorithm is less efficient.

[http://www.cs.hmc.edu/~oneill/papers/Sieve- JFP.pdf](http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)

<comment><USER14> Well it's the haskell.org landing page, of course they're showing off the type of code that Haskell is good at. In your link, the purely functional version (15 lines around a priority queue) is _more_ complicated than a naive version with a mutable array, so why would they advertise it?

<comment><USER15> I personally think the priority queue one is somewhat simpler than a fixed array algorithm. It also produces an infinite list of primes (or generator) instead of the primes up to a particular number. This is especially important in Haskell.

I'd love to see it as it shows off some great data structures available in the libraries (like priority queues) but it's getting longish.

The mutable array version is basically the same as imperative code everywhere

        sieveUA :: Int -> UArray Int Bool
        sieveUA top = runSTUArray $ do
            let m = (top-1) `div` 2
                r = floor . sqrt $ fromIntegral top + 1
            sieve <- newArray (1,m) True
            forM_ [1..r `div` 2] $ \i -> do
              isPrime <- readArray sieve i
              when isPrime $ do
                forM_ [2*i*(i+1), 2*i*(i+2)+1..m] $ \j -> do
                  writeArray sieve j False
            return sieve

It's a bit noisy syntactically and doesn't show off as much interesting stuff.

</comment></comment></comment><comment><USER16> 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.

<comment><USER17> 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.

<comment><USER18> 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 indeed simpler, it's a little nuanced in Haskell. Depending on how you're doing it you'll need to Map toUpper from Data.Char or use toUpper from Data.Text, and I don't think it's a good first impression have something that uses Data.Text, and the OverloadedStrings extension.

PS - Although, I do agree with some other commentors here that this code isn't actually the Sieve of Eratosthenes, and is far more inefficient, and that is a valid reason to replace that example.

<comment><USER15> 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 comparable Python implementation.

The first algorithm comes directly from the paper and uses an intermediary infinite tree to represent the rationals.

        data BTree a = Node a (BTree a) (BTree a)

        fold :: (a -> x -> x -> x) -> BTree a -> x
        fold f (Node a l r) = f a (fold f l) (fold f r)

        unfold :: (x -> (a, x, x)) -> x -> BTree a
        unfold f x = let (a, l, r) = f x in Node a (unfold f l) (unfold f r)

        breadthFirst :: BTree a -> [a]
        breadthFirst = concat . fold glue where
          glue a ls rs = [a] : zipWith (++) ls rs

        allRationals :: Fractional a => [a]
        allRationals = breadthFirst (unfold step (1, 1)) where
          step (m, n) = ( m/n, (m, m+n)
                             , (n+m, n) )

In 16 lines I've got an infinite binary tree, its natural fold and unfold, a breadth first search, and a lazy algorithm for generating all of the rationals with no repeats. The whole thing is simple, natural, beautiful, and efficient! It demonstrates infinite recursive types, laziness, higher-order functions, and bounded polymorphism.

And also a neat algorithm!

The downside is that 16 lines is pretty long.

By inlining the fold and unfold I can get it down to 9 lines:

        data BTree a = Node a (BTree a) (BTree a)

        breadthFirst :: BTree a -> [a]
        breadthFirst = concat . glue where
          glue (Node a ls rs) = [a] : zipWith (++) (glue ls) (glue rs)

        rats :: Fractional a => [a]
        rats = breadthFirst (generate (1, 1)) where
          generate (m, n) = Node (m/n) (generate (m, m+n)) (generate (n+m, n))

If I'm allowed imports we can use Data.Tree and make this a one-liner!

        import Data.Tree

        allRationals :: Fractional a => [a]
        allRationals = flatten (unfoldTree step (1, 1)) where
          step (m, n) = ( m/n, [ (m, m+n), (n+m, n) ] )

Finally, if I go another route and fuse the fold and unfold together into a hylomorphism

        data Trip a x = Trip a x x deriving Functor

        hylo :: Functor f => (f b -> b) -> (a -> f a) -> a -> b
        hylo phi psi = phi . fmap (hylo phi psi) . psi

        allRationals :: Fractional a => [a]
        allRationals = concat (hylo glue step (1, 1)) where
          glue (Trip a ls rs) = [a] : zipWith (++) ls rs
          step (m, n) = Trip (m/n) (m, m+n) (n+m, n)

we can hide the tree entirely and demonstrate `deriving`... at considerable cost to clarity! With a little more golfing (read: inlining) we arrive at this beauty:

        allRationals :: Fractional a => [a]
        allRationals = concat (go (1, 1)) where
          go               = glue . next . step
          next (a, b, c)   = (a, f b, f c)
          glue (a, ls, rs) = [a] : zipWith (++) ls rs
          step (m, n)      = ( m/n, (m, m+n), (n+m, n) )

which at least has the bonus of demonstrating some nice co-recursion between go and next. Or even, ultimately:

        allRationals :: Fractional a => [a]
        allRationals = concat (go 1 1) where go m n = [m/n] : zipWith (++) (go m (m+n)) (go (n+m) n)

which is actually kind of nice again if almost all of the structure has vanished.

Note that if `interleave` were part of the Prelude then we could write

        allRationals :: Fractional a => [a]
        allRationals = go 1 1 where go m n = (m/n) : interleave (go m (m+n)) (go (n+m) n)

given

        interleave :: [a] -> [a] -> [a]
        interleave []     ys     = ys
        interleave xs     []     = xs
        interleave (x:xs) (y:ys) = x : y : interleave xs ys

which is a little prettier and directly comparable to something Pythonic like

        from fractions import Fraction
        from itertools import islice

        def interleave(x, y):
          while True:
            yield x.next()
            yield y.next()

        def all_rationals():
          def go(m, n):
            yield (m/n)
            for v in interleave(go(m, m+n), go(m+n, n)):
              yield v
          return go(Fraction(1,1), Fraction(1,1))

        def rationals(n):
          return list(islice(all_rationals(), n))

[0] [http://www.cs.ox.ac.uk/jeremy.gibbons/publications/rationals...](http://www.cs.ox.ac.uk/jeremy.gibbons/publications/rationals.pdf)

<comment><USER19> It's also utterly incomprehensible for someone who hasn't seen Haskell before. Whereas with the existing example, one can at least piece together an idea of what's going on.

The point is to demonstrate the directness of expression and conciseness of Haskell, not to show how to create an efficient implementation of an involved algorithm.

<comment><USER15> I agree that the first formulation is a bit incomprehensible, though two-liner breadth-first search is understandable if a bit amazing.

Some of the latter versions (and perhaps ultimately the very last version) are easier to walk through for a beginner, though, and are _calculated_ from properties expressed in the first.

</comment></comment></comment></comment></comment></comment><comment><USER20> 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 : sieve [x | x <\- xs, x `mod` p /= 0]

Jesus. Where to begin? First of all I had to consult a dictionary for sieve. I guess primes is a thing (function?) that takes 2 or more things? Not sure. Not sure what 'where' means in this context. Don't have a good guess. Have absolutely no fucking clue what "p:xs" means. Also no idea what "p : sieve" means. I am equally stumped as to what "[x | x <\- xs," means. The "x 'mod' p" I can guess! The /= 0 I'm not sure. Maybe "/=" is equivalent to "!=" ?

And here's the thing. I've tried to read a dozen or so tutorials on Haskell and I give up every time because the syntax isn't explain. Please, please for the love god just tell me what your abstract symbols represent!

Edit: [http://learnyouahaskell.com/](http://learnyouahaskell.com/) Reading that now. So far it's pretty good.

<comment><USER21> 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 <typename T>
       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<int, int> 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<x, y>) {
            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 <- xs, x `mod` p /= 0]

So, that is `p` stuck onto the front of...

        sieve [x | x <- xs, x `mod` p /= 0]

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 <- xs, x `mod` p /= 0]

So now what the hell is [x | x <\- xs, x `mod` p /= 0]? It is a list comprehension.

Hackernews said my comment was too long. Read the rest here: [http://pastebin.com/UesYMjjJ](http://pastebin.com/UesYMjjJ)

<comment><USER22> Wow, you should turn this into a tutorial on FPComplete or something. Maybe there could be an "explain" link under the Haskell example on the homepage and it link to a tutorial like this one.

<comment><USER21> I'm actually recoding my website right now with a webserver and framework I custom built in Haskell. Maybe I'll make some of my first posts on this topic in a more formal, less commenty manner.

<comment><USER23> But the commenty style is awesome!

</comment></comment></comment></comment></comment><comment><USER24> A few thoughts:

It's really distracting that typing in the REPL changes the size of the containing div.

The blurry photo of (I assume) the audience of a lecture just doesn't work - what's it supposed to do?

There's very little useful information - everything is at least one click away. If the whole purpose of the site is to 'sell' to a new audience then I guess that's not an issue, but I expect to be able to go to the site of a language & get very quickly and easily to useful manual/wiki pages explaining whatever feature I'm having trouble with.

The basic style is very 'modern' but it looks more like a Kickstarter page that's there to sell you something trendy and new than the front page of a site giving you information about a language. It's very pretty but (to me) sends completely the wrong message about what this site is.

<comment><USER25> Also typing in their code example (the one right at the top, pride of place) into their 'Try it' repl throws an error:

        primes = sieve [2..]
            where sieve (p:xs) =
              p : sieve [x | x <- xs, x `mod` p /= 0]

        <hint>:1:8: parse error on input `='" error

Now I have almost no knowledge of Haskell, so I'm probably making some really basic mistake, but I figure most visitors will try that and then get put off

<comment><USER26> Yes, that's certainly an issue. In fact the "Try it" box also seems to work differently from the standard haskell live interpreter, in which you'd be able to define functions by prefixing them with 'let '.

If you still want to try it out, say

        let sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0] in sieve[2..]

</comment></comment></comment><comment><USER27> Another suggestion would be more examples under the clear concise code bit-- possibly in a carousel.

Additionally, all examples could be loaded into the "Try It" section, so I could type `take 4 primes` or something.

Instead, in my attempt to load the primes function.. I was met with this bit.

        λ let sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
        can't find file: Imports.hs

<comment><USER28> I agree, but I'd go even further: make the example in the corner _actually tryable_ the "Try It" section.

For this example:

      primes = sieve [2..]
          where sieve (p:xs) =
            p : sieve [x | x <- xs, x `mod` p /= 0]

I tried to type it into the shell:

      λ primes = sieve [2..]
      <hint>:1:8: parse error on input `='

It doesn't work. Okay, what if I copy and paste?

      λ primes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
      <hint>:1:8: parse error on input `='

Doesn't work.

Now, I know enough about Haskell to know what I can and can't type into ghci, but what about people who are encountering Haskell for the first time? They'll try to run the given example in the "Try It" section and will get nothing but errors. Just my two cents.

P.S. Is Haskell still avoiding success at all costs? (A philosophy I continue to be okay with, but it seems to getting futile :) )

<comment><USER29> Haskell is still avoiding (success at all costs), the bracketing is very important. Haskell may seem like a slow to develop language and community at times, but this is because most users want to see well thought out solutions to problems, and if they have theoretical backgrounds showing that what they're doing is a good idea, even better.

</comment></comment></comment><comment><USER7> > How often do programs crash because of an unexpected null value? Haskell > programs never do!

        > head []
        error "Prelude.head: empty list"

Ok, so you don't call it `null`, but it still crashes the program. Its deceptive to claim null isn't present because it's conventional to avoid using "error" in favor of Maybe, but it's still there, and used throughout Prelude. The REPL on the site hides these errors too, which is going to be pretty confusing to a newcomer who takes the head of the empty list and gets back "null" (the absence of a value) of type a.

        > (head x) + (head (head x))
          :: Num a => a

Hiding errors makes it hard for a beginner to see what went wrong, although perhaps not in this trivial example.

<comment><USER30> There's a difference between crashing and returning null. If head returned null on an empty list, that null could be passed around to different places in the program before it crashed from a null pointer exception.

There can be unexpected crashes in Haskell, but not because of null.

<comment><USER7> It's not equivalent to null, but analagous to it. With lazy evaluation, I can pass also around the expression `head []` to different places, and it won't complain until I attempt to evaluate it - much like a language with null won't complain until you try to dereference it. Sure there's a difference though - you can see immediately where the problem is with Haskell's error, but it's more difficult to trace why a value might be null in imperative code (Which I think has more to do with mutability than the presence of null).

I was also highlighting that the tryhaskell REPL actually behaves like null, because it doesn't terminate immediately as you would expect.

Just yesterday I was discussing this topic with the author of the Mars language, because his record implementation is equivalent to Haskell's and is flawed in the same way (sum types + records leading to what is effectively the equivalent of `null`) [[https://news.ycombinator.com/item?id=8005116](https://news.ycombinator.com/item?id=8005116)]. Given a new language like Mars, he could provide a fix, but we have too much baggage to break Haskell's implementation.

<comment><USER30> > With lazy evaluation, I can pass also around the expression `head []` to > different places, and it won't complain until I attempt to evaluate it - > much like a language with null won't complain until you try to dereference > it.

It won't complain until you try to evaluate it temporally, but the stack trace will point to the call to head.

</comment></comment></comment></comment><comment><USER31> I'd either link from the heading, or add some variety to the "View examples" links.

Possibly something like:

        * Show me a world without Null
        * How does Haskell help me scale?
        * When does less code give me more?
        * Take me on a tour of Hackage

<comment><USER32> This would be a massive improvement.

</comment></comment><comment><USER33> This appears to be a continuation of chrisdone's work on an "alternative Haskell homepage" [1], which was previously posted to HN [2].

[1] [http://chrisdone.com/posts/haskell- lang](http://chrisdone.com/posts/haskell-lang)

[2] [https://news.ycombinator.com/item?id=7814354](https://news.ycombinator.com/item?id=7814354)

<comment><USER5> Yes, the new page is signed by Chris Done at the bottom. I'm glad the Haskellers listened to his advice and accepted the proposed design; now it's time to tweak it with some real use.

<comment><USER34> I didn't put that signature there, whoever deployed my repo did. I've asked several people to remove it.

</comment></comment></comment><comment><USER35> Great timing, as I've just started to explore Haskell in the last few days.

First, I really like the style of the new site. My only gripe is that the section with the lecture hall photo and the videos right below it don't seem like an efficient use of prime real estate (and there is no context for the videos, I have no idea what they are or why I would want to watch it. The thumbnails suggest that I'd be clicking on an hour long lecture.). As a new user, I'd rather see the features in this space.

<comment><USER36> Yeah, perhaps replacing those videos with a gallery of places to start learning. Website previews, book covers, etc.

</comment></comment><comment><USER37> The box for "Try haskell expression here" is a little confusing, I tried to click on the white area to focus and didn't get any response. You apparently have to click on the same line, near the lambda symbol to focus?

Edit: Additionally, I really miss the lovely download page [http://www.haskell.org/platform/](http://www.haskell.org/platform/) \- and the non-home pages feel a little underwhelming and underdeveloped in general.

</comment><comment><USER27> The "Try It" section really needs to have the text cursor be active anywhere I can click on the box to type. At first it made me think that I had to move over to the grey bracket-cursor (and thus a little frustrating/confusing/unexpected). Especially since I can click to the right (when the cursor is a normal pointer) and it gains focus.

This page is strongly trying to convert a viewer, the experience can be smoothed here.

</comment><comment><USER38> I feel like the sieve is a poor example, since it's not actually the same algorithm as a sieve, and has a worse running time. It is possible to write a very nice lazy infinite sieve.

See O'Neill's "The Genuine Sieve of Eratosthenes" paper for details.

[http://www.cs.hmc.edu/~oneill/papers/Sieve- JFP.pdf](http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)

<comment><USER32> It fits the tradition established by the quicksort that isn't really a quicksort.

<comment><USER29> That example does match some high level definitions of quicksort; "pick a pivot element (the first element of the list), split the rest of the list into elements less than and greater than or equal to the pivot, quicksort those recursively, then reassemble the lesser, pivot and then greater elements". But I do agree it's not quicksort as it's usually known with its in place sorting and O(1) extra storage.

</comment></comment></comment><comment><USER4> Love it! Looks like all that's missing are the "View Examples" links under the features.

One note: the quick walkthrough mentions "up there" in reference to the repl, but the repl is actually to the left of that text when viewing on a non- mobile-sized screen. It should probably just not mention the relative positioning.

I suspect Fibonacci would be a more familiar code sample than Sieve, no?

</comment><comment><USER39> Would love to see a " this is where to use Haskell and why guide" just something a novice can see and say "oh this is why I should learn this instead of x"

</comment><comment><USER40> I like the new site. It's beautiful and elegant. The weird flowers on the download page are gone. But the link to "Introduction to Functional Programming Using Haskell" takes me to the publisher page for the textbook "Aqueous Environmental Geochemistry".

</comment><comment><USER41> I like how it says "Rock-Solid Ecosystem", yet I have had the exact opposite experience trying to install even the most basic things with Cabal. I still can't get the Sublime text haskell plugin to work due to a dependency that fails to compile.

<comment><USER42> I had a similar experience with Cabal. On one computer I haven't been able to install Yesod whereas on another one, it finally worked after I had wiped my ~/.cabal. It gave me the impression that Cabal's dependency resolution mechanism is still a bit britle.

Also I found that installing stuff through Cabal was pretty slow. It's probably partly because Haskell libraries tend to be kept narrow in scope so it's necessary to install a lot of small packages to get a piece of functionality (take for instance the dependency list of Aeson, which seems to be the recommended choice for working with JSON : [http://hackage.haskell.org/package/aeson](http://hackage.haskell.org/package/aeson) ). Another reason is that Cabal compiles Haskell code into native code.

</comment></comment><comment><USER30> The site feels too flashy, and the giant photo feels distracting. It would be nice if it felt "cleaner." As it is, I feel like a newcomer would find it somewhat overwhelming visually.

I think something nice and simple like Rust's homepage[1] would be nice. Or maybe something like Racket's homepage[2].

[1] [http://www.rust-lang.org/](http://www.rust-lang.org/) [2] [http://racket- lang.org/](http://racket-lang.org/)

</comment><comment><USER43> Wow I've gotta say, this looks great.

Something that bugs me is I couldn't copy the code in the upper right to the code "try it" section. I haven't used haskell for 6-12 months, so I'm not sure what I'm doing wrong.

Here's a screenshot: [http://imgur.com/N2SdFVq](http://imgur.com/N2SdFVq)

Regardless of _how_ to fix this, I think something should be changed so this can't be someone's first impression.

<comment><USER22> It doesn't seem to support function declaration.

<comment><USER44> You can use function declaration in the same line it is used.

`let { f x = x ^ 2 } in f 2`

</comment></comment></comment><comment><USER45> Typo, missing _to_

> You shouldn't have rewrite half your code base when it's time to scale.

</comment><comment><USER46> I love Haskell and OCaml, and other functional languages. However, no matter how intelligent and higher-level functional language becomes, I don't think they can replace procedural language, especially for time-based programmings, such as user interface effects, animations, or network-dependent operations. Some features are inherently procedural by their nature, and functional language are not functional for describing them.

</comment><comment><USER47> Many people know C++ and Java but have no sense for functional programming. It would help them to read equivalent known code to compare it with Haskell.

For instance FP Complete's Introduction to Haskell presents some ugly Java code which can be written in two elegant lines in Haskell (video around 03:25 min).

[http://www.youtube.com/watch?v=Fqi0Xu2Enaw](http://www.youtube.com/watch?v=Fqi0Xu2Enaw)

<comment><USER7> This gets brought up often, but side-by-side comparisons don't really work, because the languages are too different for them to be meaningful for anything but trivial expressions. To really understand Haskell, you need to somewhat _unlearn_ Java - or at least, stop thinking in it (in terms of objects, state and method calling).

I think a good approach to thinking differently is to look how data structures are done - most programmers recognize arrays, lists, stacks and queues, but might be confused as to how you would implement such thing without side effects. A great resource to explain this is Okasaki's Purely Functional Data Structures[1], although it doesn't use Haskell at all, the ideas are relevant, and you can work through all of the examples implementing Haskell equivalents.

[1]:[https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf](https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf)

</comment></comment><comment><USER48> Scores high on layout, not so much on usability (I, too, took a while to realize there was a live REPL on the page) or readability.

(I'm one of those people who tried to learn Haskell a couple of times but lacked use/time to really get to grips with it, so I can actually parse some of it, but the samples ought to be simpler.)

</comment><comment><USER49> The very first example I see, the infinite sequence of primes, seems to indicate it is Eratosthenes' Sieve, but it is not. [http://www.cs.hmc.edu/~oneill/papers/Sieve- JFP.pdf](http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)

In fact, the correct implementation, with some discussion of the bad performance characteristics of the example on the front page, is in your own wiki: [http://www.haskell.org/haskellwiki/Prime_numbers#Sieve_of_Er...](http://www.haskell.org/haskellwiki/Prime_numbers#Sieve_of_Eratosthenes)

Reading further, it looks like it is the correct implementation of "Turner's Sieve", but I don't think (though I may be wrong) that I'm in the minority that sees "prime" and "sieve" and thinks "Eratosthenes".

</comment><comment><USER50> The View Examples link seems not to work on iOS 5 with an iPad 3

<comment><USER51> Neither on Firefox (default settings) on Ubuntu.

</comment></comment><comment><USER52> "Try haskell expression here" \+ lessons is very nice.

Just a little nitpick:

        λ map (+1) [1..5]
        can't find file: Imports.hs
        λ map (+ 1) [1..5]
        [2,3,4,5,6]:: (Enum b, Num b) => [b]

though the first expression is what suggested in lesson 4.

Edit: looks like some random bug.

<comment><USER53> yep, you are not the only one that had that problem

λ foldr (:) [] [1,2,3]

:: Num a => [a]

λ foldr (:) [] [1,2,3]

[1,2,3] :: Num a => [a]

<comment><USER54> I had similar issues with the first expression, sometimes when executing a new expression I also had to type it twice to get the answer.

</comment></comment></comment><comment><USER55> I'm in the process of finishing LYAH, and I'm also following CIS 194 which is available online ([http://www.seas.upenn.edu/~cis194/](http://www.seas.upenn.edu/~cis194/), [https://docs.google.com/file/d/0B0_mzHzbl3GbNXBWMVZPVGNtX3M](https://docs.google.com/file/d/0B0_mzHzbl3GbNXBWMVZPVGNtX3M)). I've learned about it from [https://github.com/bitemyapp/learnhaskell](https://github.com/bitemyapp/learnhaskell).

I think CIS 194 would be nice to be added in the book listing section? It's a great course with exercises and at the same time refer to chapters of both LYAH and RWH.

</comment><comment><USER56> Nice, I like it. Now, to actually learn the language...

<comment><USER57> This will help: [https://github.com/bitemyapp/learnhaskell](https://github.com/bitemyapp/learnhaskell)

</comment></comment><comment><USER58> Just trying out the tutorial: there may be an error on step 11.

followed the instruction to type out 'a' : [] and got:

λ 'a' : [] can't find file: Imports.hs

It worked when I clicked on the command, but that may not be obvious to a new user.

λ 'a' : [] "a":: [Char]

</comment><comment><USER59> Lovely page, but that primes example is going to put off more people than it attracts, IMO. If you're not familiar with Haskell, or functional programming in general, the syntax and concepts shown there would appear alien and obtuse.

</comment><comment><USER60> I started doing a redesign some time ago, but never finished it [1].

[https://dl.dropboxusercontent.com/u/30225560/poc- haskell.png](https://dl.dropboxusercontent.com/u/30225560/poc-haskell.png)

</comment><comment><USER61> I like the look. A question: I have always used the "The Haskell Platform" download page and installer. The new download page looks like it is just Haskell, cabal, and default libraries.

I am running ghc version 7.6.3 and cabal version 188.8.131.52.

Haskell experts: should I do a fresh install? (I am on OS X and Ubuntu).

Also, shameless plug: I blogged earlier today about using Haskell to access OpenCalais and the DBPedia SPARQL endpoint: [http://blog.markwatson.com/2014/07/some-haskell-hacks- sparql...](http://blog.markwatson.com/2014/07/some-haskell-hacks-sparql- queries-to.html)

<comment><USER62> If you're on OS X or Linux, you should not use the Haskell Platform. It's a whole lot of pain for literally no gain...

<comment><USER61> Thanks Jon, I appreciate the advice. I am re-installing from haskell.org right now.

</comment></comment></comment><comment><USER63> Natural, declarative, statically typed code.

Not sure how that first adjective applies.

<comment><USER64> Looks like you're being downvoted, but I have to agree with you, especially given some of the examples right at the top.

      foldr (:) [] [1,2,3]

There is absolutely nothing natural about that line of code unless you happen to already have some background. I executed that in the sandbox and got:

      [1,2,3]:: Num a => [a]

And I _still_ don't know what was achieved.

<comment><USER65> 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.

<comment><USER64> 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.

<comment><USER15> 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.

</comment></comment></comment></comment></comment><comment><USER22> Whoa, the change happened! My girlfriend and I both think it looks awesome :)

Anyone know if there are plans to add the interactive/javascript examples as well?

EDIT: Had noscript on, everything looks great.

</comment><comment><USER66> Awesome new look!

I sort of have a thing for commas:

        An advanced purely-functional programming language

        An advanced, purely-functional programming language

Much better, no?

<comment><USER67> Depends on the intended meaning -- if it is that Haskell is advanced _among_ purely-functional programming languages, rather than both advanced and purely- functional among programming languages, then the former is far better.

</comment></comment><comment><USER68> Looks really good, but as others noted, the examples should really work `as is` within the REPL. Also I think wikipedia has better example code. Everybody knows fibonacci and can compare it.

Please add a nice Haskell facts and features tab, like: Appeared in 1990; 24 years ago More facts and features on: [http://en.wikipedia.org/wiki/Haskell_(programming_language)](http://en.wikipedia.org/wiki/Haskell_\(programming_language\))

</comment><comment><USER69> The downloads page is a bit too deemphasized; the big, bright Download button in the old page was a good call to action. However, I am really glad to see that the downloads page no longer recommends the Haskell Platform for OS X or Linux.

I wish there were better free book recommendations on the Documentation page. LYAH's style is obnoxious, and RWH has gotten quite long in the tooth.

<comment><USER70> I agree about the download page being too subtle: I _really_ love this new redesign - the old site was impossible to figure out what I was supposed to do or what was going on or what the hell "cabal" was. This new site is clean and clear: but still missing a nice big call to action (besides the live coding part).

Once you've looked at the live coding, the next thing is "community" which is great for docs, but not so great for "getting up and running" \- which was also hard to figure out on the old site. I'd prefer to be lead from the live coding to clear instructions how to get Haskell running on my system.

But, again - I love this redesign... great work!

</comment></comment><comment><USER71> I like the new homepage. One little nit-pick, I actually find the quicksort example a better candidate (instead of the sieve one). I think it highlights the expressiveness of the language a lot, and everybody implemented quicksort in some other language at one point, so they can compare.

</comment><comment><USER72> I used to hate Haskell at University, until the final couple of weeks of the module when I started to "get" it. After that, exams and dissertation (which was in Python) got on top of me and I never revisited it. Now, coming back to it I am starting to remember the fun I had :)

</comment><comment><USER73> I dislike this. Where is the 'call for me to do something'? Why are there blurred people on an escalator(?). Don't make me pick between concise and reliable. I'm more than willing to distill your messaging if it would help in any way. If only as an alternative.

<comment><USER19> > Don't make me pick between concise and reliable.

You missed the tongue-in-cheek, there. "Concise and Reliable: Pick _Two_."

And those people are in a lecture hall. Under "Open-source community effort."

</comment></comment><comment><USER74> Excellent! This is a big improvement. There seem to be some bugs with the "try it now" terminal, but it was easy enough that I actually gave Haskell a try after many years. It's got me interested enough to actually install it and start hacking away!

</comment><comment><USER75> I find the disappearance of the Haskell text and logo in the navigation bar to be really strange. It feels like I'm going to a completely different website every time I click anything on the menu.

I think it should always stay there, or something else should be done entirely.

</comment><comment><USER76> Just a nitpick: Why don't you stay consistent and use Open Sans for all the main text and the logotype at the top. Having "Haskell" in Ubuntu when the rest of the site is not stylized like that looks a little silly.

</comment><comment><USER77> The "Try It" section doesn't load without cookies/localStorage enabled. Having run-time state should be fine for tracking where someone is up to on the tutorial; persistent state shouldn't be necessary.

</comment><comment><USER78> I don't quite like this. The old one had front page links to the haskell wiki. This design is really information undense. Also, links to Hoogle and packages would be fantastic in the front page

</comment><comment><USER79> It's pretty! BUT! I get the feeling that I am viewing websites through a post box slot. This seems to be the trend with currently fashionable sites, with the wall to wall slot appearance.

</comment><comment><USER80> Off-topic: I want to learn a functional programming language, and I was thinking to go with Scheme (because, you know, SICP...) Would there be any advantage for me to go with Haskell instead?

<comment><USER81> Scheme and Haskell are very different languages. Both are functional, but that's about where the similarities end. Scheme is impure, haskell is pure; scheme is strict, haskell lazy; scheme is dynamically typed, haskell static; all functions in scheme are variadic, all in Haskell are unary; etc. So it depends on what you're looking for, and what you're trying to use it to do. That said, here are some advantages of Haskell:

1) Speed. Haskell binaries are highly optimized and tend to be very fast.

2) Correctness. Haskell's type system is far more advanced than any other language with as much or more usage, and is very good at preventing runtime errors. (and can go a long way to preventing logic errors). Also, its purity prevents huge classes of bugs.

3) Interesting: Haskell introduces a lot of new concepts which can really open up your understanding of computer science. It's a lot of fun.

4) Forward-looking: many of the ideas introduced or popularized by Haskell, such as pattern-matching, type classes, no null pointers, etc, are manifesting themselves in the new languages these days (such as Rust and Swift). Haskell itself is also (slowly) making its way into industry. Learning Haskell, in some ways, exposes you to the "next generation" of languages and programming techniques. I'm not sure the same can be said of Scheme, which tends to be used pedagogically more than as a means to push the envelope.

Then again, I know Haskell a lot better than I know Scheme, so maybe I'm biased. But at least, it gives you something to think about.

<comment><USER80> Thanks.

By training I am not a computer scientist, but an applied mathematician, so it is a little difficult for me to make judgement calls on things like type system, lazy evaluation, unary/variadic (don't even know what that means). I am interested in AI (machine learning) and statistical inference. I was looking at Lisp/Scheme because I know that AI needs gave birth to Lisp. Plus you have newer things like Church[1] that extends Scheme to deal with probabilistic models.

[1][http://projects.csail.mit.edu/church/wiki/Church](http://projects.csail.mit.edu/church/wiki/Church)

</comment></comment></comment><comment><USER82> I think Haskell deserves a concise, functional homepage. Ideally, without any side effects (like animation). Every URL should always return either the same content, or an appropriate monad.

</comment><comment><USER83> I really, really want to get into Haskell and functional programming in general, but I have no idea what sort of project to build with it. Anyone have any good suggestion?

<comment><USER84> haskell can be used for pretty much everything (even hard realtime with a code generating dsl called atom), so just think about what you enjoy/like and maybe ask before for pointers to libraries you might use with that task.

if there is anything you like but is algorithmically challenging, all the better. it's very nice to express math in haskell.

</comment></comment><comment><USER85> Titles for each of the videos would have been nice, just so I could get an idea of what I'm about to click on.

</comment><comment><USER86> An important addition to the Documentation section might be something about using Haskell for the web.

</comment><comment><USER87> If the interpreter isn't going to work on mobile, you should hide it.

</comment><comment><USER88> This page would seriously benefit from a few random kitten pictures.

</comment><comment><USER89> "You shouldn't have rewrite half your code base".

</comment><comment><USER90> Ugh, doesn't use progressive enhancement:

[https://en.wikipedia.org/wiki/Progressive_enhancement](https://en.wikipedia.org/wiki/Progressive_enhancement)

<comment><USER91> How would the REPL look like with progressive enhancement?

 _" Thanks submitting a Haskell line! You're being redirected to the output of the evaluation. If you're not being redirected automatically, please click _here_"_

</comment></comment><comment><USER92> looks kinda generic but it's quite nice.

</comment><comment><USER93> Much better! I hate the red links...

</comment><comment><USER94> How did it know I was 28??? ;-)

</comment><comment><USER95> This design is beautiful and elegant, just like Haskell.

</comment><comment><USER96> Wow, nice.

</comment><comment><USER97> sexy

</comment><comment><USER98> not at all surprised that the first code sample is A) Cryptic as hell and B) Something I basically never need to do when developing an app

</comment><comment><USER99> Please, can anyone come up with something original? Or at least usable.</comment>


What Will Happen When We Decide Computers Are Just Devices to Access the Cloud? - <AUTHOR> https://cheapskatesguide.org/articles/cloud-computing.html <comment><USER2> [https://en.wikipedia.org/wiki/Multics](https://en.wikipedia.org/wiki/Multics)

1964.

A lot apparently. Just took a while to implement.</comment>


What happens if I don't fill out my census form? (2019) - <AUTHOR> https://people.howstuffworks.com/question345.htm <comment><USER2> The US census was infamously used to assist in rounding up Americans of specific ethnic backgrounds for concentration camps.

It would go a long way to easing people's minds if they had some way to guarantee that this could not happen again. I realize there is value in gathering attributes beyond just "one person", but storing these attributes in a way that can be connected to addresses seems seriously problematic.

<comment><USER3> I agree that the data should be treated anonymously and confidentially, with severe punishment to abuses.

Would the lack of census data prevented the concentration camps from operating? It may have instead taken longer and required more people, but I would expect that at the time anyone with a Japanese/Chinese look or name to have been detained anyway. Side note: It seems even the 2nd amendment didn't help citizens resist agains oppression.

I suspect these days the government has enough information already on its citizens through other means (intelligence agencies etc) than the census, to still target based on race if they wanted to.

Immediately after 9-11 the discrimination against Muslim, Arabic and other minorities was rather pronounced. No census data needed to that either. People just judged by visual appearance or name.

<comment><USER2> > I agree that the data should be treated anonymously and confidentially, with > severe punishment to abuses.

What constitutes "abuse"? Differential privacy is hard. Once the data has been collected, simply not being an expert in statistics can be enough to accidentally leak sensitive data. The government is simultaneously the data collector, data user, and prosecutor of abuses, so I'm skeptical that much will come of any such promise. Maybe a letter of apology in 50 years.

> I suspect these days the government has enough information already on its > citizens through other means (intelligence agencies etc) than the census, to > still target based on race if they wanted to.

Pointing out that ethnic minorities are likely to be screwed anyway in such a situation, even without census data, is not going to ease anyone's mind.

</comment></comment></comment><comment><USER4> This is worth quoting here IMHO:

"However, even if you don't get fined for not filling out the census form, there are some good reasons you should do it anyway. Seats in the House of Representatives seats are apportioned by population, with the most populous states receiving the most seats. Federal and state governments rely on census data to budget for social welfare programs that assist the poor, elderly, disabled and veterans. Cities and private industry use demographic figures to plan new hospitals and housing developments, and to assess the need for new schools or new strip malls. So, not filling out the census form may cost you something in the long run."

<comment><USER5> Some of us live where we oppose all of the current elected officials. In that case, it sounds like opting out is the only effective "vote" we can make in a FPTP system

<comment><USER6> That's like cutting of the nose to spite the face.

</comment></comment></comment><comment><USER7> In 2010 I just kept forgetting to fill out the census. My census guy left notes on my apartment door begging me to call him. Finally, one day, he literally popped out of the fucking bushes with the census form.

<comment><USER8> I kept getting some mid-census domestic abuse questionnaire a couple years ago. I had zero interest in filling it out but they were persistent about that too.

</comment></comment><comment><USER9> They missed me in 1990 and 2000, when I was unconventionally housed (living in the office).

<comment><USER10> Hopefully you are in a better situation now. For anyone who is currently homeless, but wants to be counted, the census bureau has the following plans:

March 30, 2020: Counting people who are in shelters.

March 31, 2020: Counting people at soup kitchens and mobile food vans.

April 1, 2020: Counting people in non-sheltered, outdoor locations, such as tent encampments and on the streets.

See this for more information: [https://2020census.gov/en/what- is-2020-census/focus/people-e...](https://2020census.gov/en/what- is-2020-census/focus/people-experiencing-homelessness.html)

</comment></comment><comment><USER11> >Note that the Sentencing Reform Act of 1984 has increased the fine for any criminal misdemeanor to as much as $5,000. In practice, though, no one has been prosecuted for not filling out the census since 1970, according to a 2014 Politifact article.

That article is wrong, and the fine is absolutely not $5,000. If that article were correct, then there would be _no_ federal fines under $5,000 anywhere. This is misinformation that the census bureau likes to spread around to scare people. In face, the Sentencing Reform Act of 1984 applies _only_ to criminal cases.

This means that the fine is actually $100.

I went through this rigmarole when I got one of those off-year census forms during the Obama administration, asking about what my family eats, how many toilets we have, etc. I refused to fill it out. A guy showed up at my door. He showed me the brochure that said it was mandatory, and what the potential fine was. The same $5,000 number was quoted. I told him I would not be participating in this program, and that his brochure was lying because this was not a criminal offense. He agreed it was not a criminal matter. And that was that.

</comment><comment><USER12> One thing I'm curious about is, why does a country need to do this in the first place?

From the example I'm familiar with: the last ever census in Turkey was held in 2007. There on, there is now a live, real-time count of everyone in the country. Why doesn't that work in the US?

Surely US is capable of it, but I wonder if the blockage is inertial, political or just not enough of a priority.

<comment><USER13> Can you provide any technical detail as to how a real-time count of every person is possible? What databases are used to track births and deaths and emigration in real time? How about income/housing/education characteristics? Are you a Turkish citizen? If so, are you able to query the government for the exact population count right now?

<comment><USER12> The population counts are released yearly and I believe you can do what is the Turkish version of FOIA request to get the live count, though don't quote me on the latter part.

Turkey has a central database, called TCKN, that everyone is assigned by birth or by getting an immigration visa. The births and deaths are tracked by hospitals and the Revenue Service. Income / education / housing - all of these are tracked by the central registers and licensing boards. Every Turkish citizen and resident has an online account at [https://www.turkiye.gov.tr/?lang=en_US](https://www.turkiye.gov.tr/?lang=en_US) (for English version) which you can use to view taxes paid, your previous health records (MRI scans and all should be downloadable) see scripts fillable, paperwork for legal action by you or against you, census records, even mobile and landlines registered on your name, and basically pretty much everything you'd expect a state can do. All of the outputs from this site are printable PDFs and they have a barcode on them which I think the government cryptographic signature. So you can get some doc from here, print it out and bring to someone else and they'd be able to verify it by scanning the barcode.

In other words, they have total knowledge. It's not just the number of people in the country. What's interesting is that it doesn't rely on self-reporting, but on ambient data providers. It's kind of dystopian, but technically fairly impressive and so far (ominously) relatively benign. Failing all else, it's very useful.

<comment><USER13> Thanks for the thoughtful reply. I remain skeptical that an accurate detailed count can be automated (at this point in history) but I won't claim to have any insight about contemporary life and society in Turkey.

<comment><USER12> I think you are right to be skeptical and I don't claim to have an insight into how accurate it is. However, mind that while Turkey is culturally about 80% western and 20% non-western, it's really unpredictable where that 20% shows up. For example, the reason the census count can be reasonably accurate even in the adversity of undocumented immigrants is that Turkish police can walk up to anybody they see as suspicious on the street and ask for their TCKN / ID to do a spot check for arrest warrants — decidedly free of the need for the western concept of a 'probable cause' or anything like that, it's a member of your community asking to validate your ID. Since they have the readers attached to their mobile phones, the check takes a couple seconds.

This also, by design, makes it really hard to be undocumented in Turkey. There's a significant skin tone difference between people from the Middle East and those in Istanbul, and the police does absolutely use this to be more scrutinous if you're even just walking by them. From an US perspective this is discrimination, and it definitely is, but this is how it works — and they're pretty good at spotting non-Turkish people. As a real example in action, there was a recent directive that required refugees to keep their residences within the borders of the first municipality they registered in (many of the Syrian refugees had moved to Istanbul from where they first registered for benefits), and the police managed to significantly clamp down on unregistered immigrants fairly quickly and send them back to the cities they registered to.

In this specific case this was the right move since the resources are allocated to states ( _il_ s) based on where refugees are registered and Istanbul alone does not have nearly the capacity to house that many refugees. My point is that Turkish police does have a lot more leeway than the US police before it becomes socially unacceptable — and while this is overall not a great thing (loose oversight), it also makes them much more effective at making a census in the right ballpark.

</comment></comment></comment></comment></comment><comment><USER14> The US federal government has an exact, real-time count and location of every single person with a phone in the country due to universal bulk surveillance.

Cross-referenced with the subscriber records from wireless, cable, and utility companies, databases from data brokers that are fed by loyalty programs and supermarkets, and every bank or credit card swipe in real-time, they already have 100% of this data in far higher resolution than will ever be collected by the census. They know about your address updates even before you tell the DMV.

I will be ignoring the effort.

<comment><USER15> I have 6 phones. Am I 6 people?

<comment><USER16> You registered them under 1 owner cluster that links up to you, so no :D

</comment></comment></comment><comment><USER17> I didn't fill out the last census forms in protest of the longform census that year(in Canada) that asked for what I considered to be unnecessary information I didn't wish to divulge. Nobody that lived in the house filled one out. Nothing came of it. Census people showed up at the door every day for a while, but would leave after a bunch of knocking with no answer. I do normally fill them out though. For reference Canada has similar census laws to America.

</comment><comment><USER18> Next national census in Poland happens in 2021 and also here, you can be fined or sent to prison, get non-custodial sentence by not participating or providing false answers; persons covered by census are obliged to participate. Those who by gathering answers for census surveys and processing data will gain any profits can be imprisoned for up to 5 years.

So far no one from my family was chosen; since fall of the Eastern bloc there were 2 censuses, in 2002 and 2011

</comment><comment><USER19> tldr: nothing

(Can confirm, was Census enumerator. You probably will get an in-person attempt from a very-low-paid enumerator, though.)

<comment> crooked-v The pay is actually pretty decent, and is cost-of-living adjusted. In Portland where I live, for example, it's $18/hour, which is way better than some temp jobs I've had.

<comment><USER20> So in theory, I should hold off on answering so someone gets paid to come to my house?

Do they have a quota to hit, like if I take my time with them do they get punished?

<comment><USER21> Or maybe they would prefer to spend their time finding people who are actually hard to enunerate, rather than wasting on someone who is just looking to consume their time.

<comment><USER22> The idea is to get "contacts" and tell them to be "hard to enumerate" and then collect a paycheck.

</comment></comment></comment></comment></comment><comment><USER23> watch "The Census: Last Week Tonight with John Oliver" on this topic.

[https://www.youtube.com/watch?v=1aheRpmurAo](https://www.youtube.com/watch?v=1aheRpmurAo)

<comment><USER24> Deleted: Made a mistake.

<comment><USER25> Your link does not support your claim, and this link gives more detail not supporting your claim.

[https://www.census.gov/acs/www/about/why-we-ask-each- questio...](https://www.census.gov/acs/www/about/why-we-ask-each- question/plumbing/)

</comment></comment></comment><comment><USER26> I got randomly selected for the long one in 2010. There were several questions I was not able to answer but providing incorrect information is a crime and not answering is a crime. So I did nothing. They sent one or two threatening follow ups. Then an in-person enumerator showed up and ran me through the short-form questions only, which was fine.

<comment> crooked-v > providing incorrect information is a crime and not answering is a crime. So > I did nothing.

The correct answer in this case is to say "I don't know". You can write in stuff on census forms and it's up to the local office to process those as special cases.

<comment><USER26> That's not something they say you can do.

In my case the correct answer was to do nothing, then cooperate with the enumerator on the short form questions, which as I said was fine.

</comment></comment></comment><comment><USER27> Nothing. Nothing happens. You may get an in-person visit, and if you blow them off, nothing also happens.

As with voting, it only encourages them. They are passionate about getting you to participate because they want the appearance of legitimacy, so you get obvious fear-and-guilt-prop like this.

<comment> crooked-v > Nothing. Nothing happens.

Except for your area getting federally undercounted, which loses representation and tax dollars for you and all your neighbors.

<comment><USER28> Is there any reason to believe that more people are failing to fill out the census in my area than in other areas? Because if the failure rate is about the same everywhere it probably does make little difference.

<comment><USER22> How do you know the failure rate is the same everywhere? It is very possible that the failure rate correlates with the region because it is not a purely stochastic process. Some users here think the government has no business in demanding census information and simply ignore it.

<comment><USER28> I don't have any data either way, do you? HN users don't represent a geographical region, per se, but I suppose you could argue that they're mostly in SF? Regardless, I imagine there are other communities that might also have a higher-than-baseline failure rate, but absent any evidence I have no reason to assume they're not fairly randomly distributed geographically. Especially at the granularity of _US states_.</comment></comment></comment></comment></comment>


MongoDB vs. MySQL Comparison: Which Database Is Better? - <AUTHOR> https://da-14.com/blog/mongodb-vs-mysql-comparison-which-database-better <comment><USER2> The most significant difference between them is data model (relational vs non- relational nosql). If you want to read more about how to choose between relational db and nosql db, here is an excellent survey written by Ian Thomas Varley: [http://ianvarley.com/UT/MR/Varley_MastersReport_Full_2009-08...](http://ianvarley.com/UT/MR/Varley_MastersReport_Full_2009-08-07.pdf)</comment>


Real men don't use floating point - <AUTHOR> http://john.freml.in/consider-fixed-point

<comment><USER2> Tom Forsyth on double precision: <http://bit.ly/fguwaZ> (bit.ly link because HN mangles the real one).</comment>


Browser-side require() for your node modules and npm packages - <AUTHOR> https://github.com/substack/node-browserify

<comment><USER2> Something similar that came up a few days ago:

[http://caolanmcmahon.com/posts/writing_for_node_and_the_brow...](http://caolanmcmahon.com/posts/writing_for_node_and_the_browser)</comment>