July 22, 2014
On 7/22/2014 11:44 AM, bearophile wrote:
> Walter Bright:
>
>> Would you rather write that or:
>
> How much experience do you have in writing Haskell programs longer than 50 lines
> of code?

Zero.


> I have a large respect for your experience and your intelligence, but
> be careful with comments like that, to not show just your ignorance...
>
> If you are a Haskell programmer you usually don't write code like that, so in
> practice it's not a problem.

Does that imply you agree with my earlier point, then, that D doesn't need tail recursion because it can write loops instead?


> And even if sometimes you have to write awkward
> code, the Haskell programmers can assure you that on average the advantages
> given by Haskell purity far outweighs the disadvantages.
>
> On overall I prefer D over Haskell, but if you want to criticize Haskell you
> need much much better arguments and way bigger cannons :-)

The point was not at all to criticize Haskell. The point was that D does not need tail recursion because D supports writing loop constructs. Showing how loops could be written using awkward monads in Haskell that Haskell programmers wouldn't write does not change that point.

July 22, 2014
On Tuesday, 22 July 2014 at 19:12:31 UTC, H. S. Teoh via
Digitalmars-d wrote:
> I'd rather write:
>
> 	int factorial(int n) pure {
> 		return reduce!((a,b) => a*b)(1, iota(2, n));
> 	}
>
> ;-)

This is how we fucked UFCS.
July 22, 2014
On 07/22/2014 08:34 PM, Walter Bright wrote:
> On 7/20/2014 8:15 PM, Timon Gehr wrote:
>> So does Haskell.
>>
>> import Control.Monad
>> import Control.Monad.ST
>> import Data.STRef
>>
>> factorial :: Integer -> Integer
>> factorial n = runST $ do
>>    r <- newSTRef 1
>>    forM_ [1..n] $ \i->
>>      modifySTRef r (*i)
>>    readSTRef r
>
> Would you rather write that or:
>
>    int factorial(int i) pure {
>      auto r = 1;
>      foreach (i; 1..n + 1)
>      r *= i;
>      return r;
>    }
> ...

If I fix the typo, this computes the same numbers for inputs int.min up to and including 12.

> And I'd love to see what native code is generated for the Haskell example.

Well, the _actually_ corresponding D code using BigInt and DMD is significantly slower than what GHC generates here.

In any case, I don't think that this kind of mutation-heavy code is a core focus of GHC, so the assembly will probably not be nearly as well optimized as it could be.

But if you'd like to compare the offers of D and Haskell a little further, consider the following cute code, which I wrote in 5 minutes and which computes the 1000000th natural number that is a product of powers of 2, 3 and 5 well below a second on my machine:

merge :: Ord a => [a] -> [a] -> [a]
merge xs [] = xs
merge [] xs = xs
merge xxs@(x:xs) yys@(y:ys) =
  case compare x y of
    LT -> x : merge xs yys
    EQ -> x : merge xs ys
    GT -> y : merge xxs ys

hamming :: [Integer]
hamming = 1 : merge    (map (*2) hamming)
                (merge (map (*3) hamming)
                       (map (*5) hamming))

main = print $ last $ take 1000000 hamming

519312780448388736089589843750000000000000000000000000000000000000000000000000000000

What do you think would be the corresponding idiomatic/fast D code? Does it outperform the Haskell code?
July 22, 2014
On 07/22/2014 09:42 PM, Walter Bright wrote:
>>
>> On overall I prefer D over Haskell, but if you want to criticize
>> Haskell you
>> need much much better arguments and way bigger cannons :-)
>
> The point was not at all to criticize Haskell. The point was that D does
> not need tail recursion because D supports writing loop constructs.

Tail call support is still useful. Looping is not the main reason for supporting tail calls. Eg. a tail call might be indirect and only sometimes recurse on the same function and sometimes call another function.

> Showing how loops could be written using awkward

The point is not to criticize? :-)

> monads  in Haskell that
> Haskell programmers wouldn't write does not change that point.

Sure, that part of the discussion grew out of the claim that there are "no loops" there.
July 22, 2014
On 07/22/2014 11:23 PM, Timon Gehr wrote:
> Looping is not the main reason for supporting tail calls.

(In D!)
July 22, 2014
Timon Gehr:

> What do you think would be the corresponding idiomatic/fast D code? Does it outperform the Haskell code?

Look in RosettaCode for various implementations in D:
http://rosettacode.org/wiki/Hamming_numbers#D

A good part of the performance difference is caused by the D GC and the fact that Haskell GHC uses a the GNU multiprecision libs for its bigsint. In the meantime we have to maintain, optimize and debug our bigint implementation, wasting time better spent elsewhere.

Bye,
bearophile
July 22, 2014
On 7/22/2014 2:23 PM, Timon Gehr wrote:
> On 07/22/2014 09:42 PM, Walter Bright wrote:
>> Showing how loops could be written using awkward
>
> The point is not to criticize? :-)

Yes. If you want to infer criticism of Haskell from that, go ahead, but none was intended. You can write awkward code in any language.


>> monads  in Haskell that
>> Haskell programmers wouldn't write does not change that point.
> Sure, that part of the discussion grew out of the claim that there are "no
> loops" there.

Bending a language over backwards to be pedantic is pointless for this discussion. Nobody claims "Obfuscated C Contest" entries are best (or even suggested) practices.
July 22, 2014
On 7/22/2014 2:08 PM, Timon Gehr wrote:
>> And I'd love to see what native code is generated for the Haskell example.
> Well, the _actually_ corresponding D code using BigInt and DMD is significantly
> slower than what GHC generates here.

Irrelevant to the looping issue - comparing the code gen of D's BigInt to Haskell's BigInt is not the issue here.

July 22, 2014
On 7/22/2014 2:29 PM, bearophile wrote:
> A good part of the performance difference is caused by the D GC and the fact
> that Haskell GHC uses a the GNU multiprecision libs for its bigsint. In the
> meantime we have to maintain, optimize and debug our bigint implementation,
> wasting time better spent elsewhere.


I.e. the perf difference has nothing to do with Haskell or tail recursion.

July 22, 2014
On 07/23/2014 12:14 AM, Walter Bright wrote:
>>>
>> Sure, that part of the discussion grew out of the claim that there are
>> "no
>> loops" there.
>
> Bending a language over backwards

Not what happened.

> to be pedantic

Being pedantic is important enough.

> is pointless for this discussion.

If one doesn't want "pointless" "pedantry" my suggestion would be to not make wrong claims about apparently irrelevant things, or to ignore the rebuttal to communicate silent agreement.

> Nobody claims "Obfuscated C Contest" entries are best (or
> even suggested) practices.

Irrelevant. I'll leave here.