Live data from Hacker News

John Carmack: Thoughts on Haskell [video]

functionaltalks.org

151–153 of 153 posts

Re: John Carmack: Thoughts on Haskell [video]

#151
post #141

Earlier quoted context omitted.

Short answer: No, you can't. Long answer: You can, but Haskell is very serious about keeping pure code separate from impure code. Any function which performs I/O is impure, so its output must be an IO Thing instead of just a Thing. This means anything that uses its output must accept an IO Thing instead of an ordinary Thing, and so on. Of course, the way I/O works means that a 'Type1 -> Type2' function into can be tr…

Whoa, really? You have to use a monad just to print text to stdout in Haskell?

Remember that Haskell is lazy. In broad strokes, the way you control when things happen is to sequence them by combining them (directly or indirectly) into the massive IO action that becomes main.

If you don't care when it happens, you can use unsafePerformIO - which is just fine for debugging, though there are often better approaches.

Re: John Carmack: Thoughts on Haskell [video]

#152
post #142

Earlier quoted context omitted.

When combined with lexically scoped closures, if you try to shadow your value bindings in a functional language and expect it to work the same way as mutating a variable does in an imperative language, you're in for a surprise.

Sure, you have to restrict the scope in which rebinding is legal, but I don't see how it's fundamentally any different than the use of a phi-node in SSA form.

Here's an SML example:

- val a = 1;

val a = 1 : int

- fun f() = a;

val f = fn : unit -> int

- f();

val it = 1 : int

- val a = 2;

val a = 2 : int

- f();

val it = 1 : int // a is still bound to 1 as far as f() is concerned

Now in Javascript:

> var a = 1;

undefined

> function f(){return a};

undefined

> f();

1

> a = 2;

2

> f();

2

>

If you bind a val, then you define a function that references that val, then you later shadow the val binding, then call the function again, the function still sees the earlier val binding, because it's a closure of the environment at the point where the function was defined, not at the point where it was called. This is unlike variable assignment in imperative languages.

Re: John Carmack: Thoughts on Haskell [video]

#153
post #119

Earlier quoted context omitted.

What do you mean by O(log32 n)?

Clojure's data structures are implemented using trees that have a 32-way branching factor, so each node has 32 children, instead of the 2 you'd see in a binary search tree. A lot of things you might expect to be O(1), like checking for membership in a set, or getting the nth element of a vector, actually take O(log_base_32(n)).

Ah, I see. That doesn't matter in big-O notation, though, because log_32(n) = log_2(n) / log_2(32), that is the difference between two bases is a constant factor.

I was a bit confused because O(log_32(n)) = O(log(n)) = log(32)+log(n) = O(log(32n)), so no matter how I parsed it I would just get O(log(n)) :)

Post reply on HN