Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The header code example #46

Open
bluealert opened this issue Jan 29, 2015 · 17 comments
Open

The header code example #46

bluealert opened this issue Jan 29, 2015 · 17 comments

Comments

@bluealert
Copy link

fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n - 1) + fibonacci (n - 2)

why use this very inefficient solution? I think use the below solution is better ?

fibs = 1:1: zipWith (+) fibs (tail fibs)

may give new Haskell user very bad feel ?

@chrisdone
Copy link
Member

The current example as of now is:

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

This is the original example I made and I've restored it. It's inefficient when you run it. But it's very efficient at its purpose, which is to demonstrate:

  1. where syntax,
  2. enumeration syntax,
  3. pattern matching,
  4. consing as an operator,
  5. list comprehensions,
  6. infix functions
  7. laziness

If you can make an alternative example which satisfies that many criteria for giving a "feel" of the language, please contribute it. I've added a title attribute to the text commenting to the same effect.

@chrisdone chrisdone changed the title why use that very inefficient solution to solve fibonacci? The header code example Jan 31, 2015
@chrisdone
Copy link
Member

I will keep this issue open for future people to see.

@bluealert
Copy link
Author

this example is very good. 👍
you forget to call the sieve function.

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

@sebastianv89
Copy link

Although I cannot think of a better example right now, I believe this example is misleading. Melissa O'Neil wrote a good article on why: http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

You mention that the purpose of the example is to demonstrate, but then list six points on the syntactic construction, which are not essential to the real strength of Haskell. (I do agree upon your seventh point: laziness.) My concern is that this example will lead new Haskell users to believe that Haskell can be understandable or efficient, but never both. Actually, it might lead them to believe that Haskell cannot be efficient...

A minor(?) second concern is that this example cannot be entered in the "Try it" REPL directly below. See also this comment on this HN thread.

@jwaldmann
Copy link

"+1" to sebastianv89. This "primes" example is misleading, also for this reason: the subsection heading is "declarative and statically typed", but there are no (visible) types in this code snippet.

@chrisdone
Copy link
Member

Although I cannot think of a better example right now, I believe this example is misleading. Melissa O'Neil wrote a good article on why: http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

People have been linking this since May last year. I'm aware of the paper. But the example cannot demonstrate anything semantic in a few lines, the point is to show what Haskell feels like on the surface. Nobody's going to actually go run the function.

@sebastianv89
Copy link

At least call the supporting function something else than sieve, because it is not a sieve.

Also:

What is the point of demonstrating the power an elegance with an example that will (hopefully!) never appear in any real world code? Better to show how the language is still powerful and elegant when taking into account the edge cases and common optimizations.

Writing elegant non-real-world code is much easier (in any language!) than writing real code.
src: https://news.ycombinator.com/item?id=9052869

@gbaz
Copy link

gbaz commented Feb 16, 2015

For what its worth, it is a sieve, absolutely! Just not the classic sieve, and not as efficient as that one.

@cdupont
Copy link

cdupont commented Feb 16, 2015

I have mitigated feelings on this example.
The plus:

  • prime number generation in three lines is powerful.

The minus:

  • this example is totally not understandable for beginners. It's very hard to read and involves a lot of syntax.
    For example the variable "x" is mentioned 3 times, surrounded with many symbols: [, <-, |,,...

Of course it's hard to find an example both powerful and beginner-accessible.
IMO writing it the opposite way is a little bit clearer:

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

It's more chronological (defining sieve first), avoids where keyword and indentation tricks.

Also I would add a "what is this?" or "explain me" link explaining what it is (it's not clear to a beginner that this will generate a list of primes) and giving some explanation on how it works.

@gbaz
Copy link

gbaz commented Feb 17, 2015

A bigger real problem is that as per #87, you can't type it into the repl right below!

@gbaz
Copy link

gbaz commented Apr 21, 2015

So Ertugrul also suggests we change the name from sieve to trialDiv at the least. It seems like there's enough sentiment that we should do that.

@chrisdone
Copy link
Member

Sure, why not.

@gibiansky
Copy link

Suggestion: instead of having a single bit of code there with no explanation, imitate the way Racket does this. They have a bit of code with < and > buttons to advance to the next bit of code or previous and they have an "explain" link to the top right of each one that pops up a modal window with an in-depth explanation of the code. I remember seeing this years ago and being hugely impressed by the presentation style, and it seems like it might fit well here.

Then we can have a variety of code snippets meant to show off different things; for example (just ideas):

  • A simple example of syntax (say, just the implementation of filter)
  • Low level bit fiddling (to show that Haskell doesn't have to be high level?)
  • Diagrams (everyone likes pretty pictures)
  • Gloss (simple 2d games)
  • HTML generation with Blaze or Lucid (a DSL)
  • A small web server using Snap or Scotty or something (practical example)
  • A parser using Parsec

What do people think of this? I think this would give a much more complete view of Haskell as a language and ecosystem. It's a non-trivial amount of work and honestly I don't know how much I can contribute (hopefully some, if people think this is worthwhile), but maybe it's the right way to present these code blocks.

@chrisdone
Copy link
Member

@gibiansky that was in my original proposal but coming up with that content as you note requires time and thinking not yet spent by anyone yet.

@gibiansky
Copy link

@chrisdone Ah, makes sense. If there is some time in my life I will tackle this in the next several weeks, but no promises.

@treblacy
Copy link

I came here after I saw the discussion in haskell-cafe.

I submit these candidates:

-- all digit strings (infinite list, shorter lengths first)
digitals = [] : extend digitals
  where
    base = ['0' .. '3']
    extend dss = [ d : ds | ds <- dss, d <- base ]

-- but do you want to demo alphabetical infix?
digitals = [] : ['0' .. '3'] `prepend` digitals
  where prepend b dss = [ d : ds | ds <- dss, d <- b ]

-- or do you want to demo user-defined non-alphabetical?
digitals = [] : ['0' .. '3'] +> digitals
  where b +> dss = [ d : ds | ds <- dss, d <- b ]

P.S. http://cowbirdsinlove.com/43

@maggy96
Copy link

maggy96 commented Jun 25, 2015

What about quicksort? I think it's pretty impressive. Also it's general and I think everybody knows quicksort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants