Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The biggest idea is probably laziness.

In Haskell, everything is basically a function. Even the number 3 is really just a function that if and when evaluated will return the value 3. I used that concept to to simply some JavaScript UI code a while back. I had SELECT element that I needed to populate dynamically but wanted the last option to invoke an action that allowed the user to add another option

     choice 1
     choice 2
     choice 3
     <add new choice>
I ended up populating the dropdown list using a bunch of javascript functions that looked like this

    function () { return { key: 1, value: 'choice 1' } }
    function () { return { key: 2, value: 'choice 2' } }
    function () { return { key: 3, value: 'choice 3' } }
    function () { /* do stuff that creates a new choice */ }
Not sure I would have thought of that if I had not first played with Haskell and grokked laziness.


'In Haskell, everything is a function' is absolutely wrong. People who don't know much about Haskell often say this. There's a post by Conal Elliott about this incorrect meme: http://conal.net/blog/posts/everything-is-a-function-in-hask...

It's simply not true. In fact, because Haskell is statically typed, it's very easy to tell what's a function and what's not: If its type doesn't have an -> in it, it's not a function.


... I know that 3 is not literally function in the Haskell type system but it's an easy way to explain it to people less familiar with the language (not that I assume freyrs3 is one of those).

Also, while it might be true that "people who don't know much about Haskell" often say that everything is a function, it's also the case that people who do know a lot about the language find the notion to be pedagogically useful: On page 13 of The Haskell School of Expression, Paul Hudak offers that pi (which is of type Floating a => a and thus clearly not a function) "can be thought of as a function with no arguments".


Also, the definition of an infinite list of ones

    ones = 1 : ones
is a non-function value, but is recursively applied to itself. Might help illustrate why this is a useful notion in Haskell.


To be precise.

"ones" is not "recursively applied to itself". "ones" is not a function. "(:)" is a function.

In actuality, "ones" is both an argument and a result of the (:) function (aka "cons").

This works in Haskell because "ones" is not an atomic value or function; "ones" is a "lazy" structure, where some of the elements's values depend on other element's values, and Haskell uses a "call-by-need" graph reduction algorithm to evaluate arbitrarily complex* computations down to values, not in any sort of sraihtforward order suggested by "argument -> function -> result -> lvalue" in an imperative or strict language.

Laziness is at the core of the runtime system's model for computing a result from a program, and it's not something you can translate line-by-line from a non-lazy program, even a functional language program.

I'm not just being pedantic. Haskell (with a runtime like GHC, required for this conversation to really make sense) really is different from other programming systems. ("Programming system"! Not just "language"!).

The runtime system ("RTS") is not just a C runtime that provides a statement language and shim over OS system calls.

The RTS is not "just" a VM like Java VM.

The RTS is (metaphorically) like perl's "perl -nple" or a SQL RDBMS query planner, where the runtime is itself a program that takes your code as input and does its own extremely sophisticated computation that is not at all visible in your program's code.

[] Arbitrarily* complex, but still "causal" structures that admit at least one valid order of evaluation. Trying to define "ones = ones" or other non-disentanglable cyclic dependencies leads to a runtime failure ("<loop>" exception).

[] In some cases, the graph solver might practically fail to solve a graph that is theoretically solvable. Let's ignore that.


That's good info, GHC is an pretty amazing feat of engineering, there are some good summaries of STG, C--, etc for further reading:

http://darcs.haskell.org/ghc/docs/comm/the-beast/stg.html

http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler...

http://www.reddit.com/r/programming/comments/i4jb1/haskells_...

-------------

Also, Simon M started Google +ing about what he's up to

https://plus.google.com/u/0/107890464054636586545/posts


I think by function you really mean "thunk", which is just the name for an unevaluated expression. A thunk is really just an implementation detail while a function has important semantic meaning (it is a mapping from values of one type to values of another).

A thunk can be thought of as a procedure with no arguments (taking some terminology from SICP), and in JavaScript procedures are called "functions", but using JavaScript's terminology in a Haskell context gets confusing.

Additionally, it wouldn't even be correct to say all Haskell values are thunks. You actually have a fair bit of control over this and can have strict, unboxed elements and the like with GHC. A different compiler could implement the non-strict semantic in a different way.


I meant function in the same sense that JavaScript means function which is not the same as what Haskell considers to be a function (since JS functions don't have to return a value). I should have been more precise.


> Even the number 3 is really just a function

Haskell doesn't define integers as functions, they are machine integers just like most other languages. You may be thinking of the Peano numbers, which do have a particularly nice representation in Haskell but they certainly aren't used by default.




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: