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?

Reply via email to