Skip to content

Instantly share code, notes, and snippets.

What would you like to do? vs stress.hs


data Bits
  = Be
  | B0 Bits
  | B1 Bits
  deriving Show

data Pair a b
  = Pair a b
  deriving Show

copyBits :: Bits -> Pair Bits Bits
copyBits Be        = (Pair Be Be)
copyBits (B0 pred) = let (Pair predFst predSnd) = copyBits pred in Pair (B0 predFst) (B0 predSnd)
copyBits (B1 pred) = let (Pair predFst predSnd) = copyBits pred in Pair (B1 predFst) (B1 predSnd)

isZero :: Bits -> Bool
isZero Be        = True
isZero (B0 pred) = isZero pred
isZero (B1 pred) = False

sub :: Bits -> Bits
sub Be          = Be
sub (B0 bsPred) = B1 (sub bsPred)
sub (B1 bsPred) = B0 bsPred

stress0 :: Bits -> Bool
stress0 count =
  case copyBits count of
    (Pair countFst countSnd) ->
      if isZero countFst
        then True
        else stress0 (sub countSnd)

main :: IO ()
main = print $ stress0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B0(B1(Be)))))))))))))))))))))

T Bool
| true
| false

T Bits
| be
| b0(pred : Bits)
| b1(pred : Bits)

T Pair<A, B>
| pair(fst : A, snd : B)

copy_bits(bs : Bits) : Pair(Bits, Bits)
  case bs
  + copy_bits : Bits -> Pair(Bits, Bits)
  | be => pair(__ be, be)
  | b0 => case copy_bits(bs.pred) as pred | pair => pair(__ b0(pred.fst), b0(pred.snd))
  | b1 => case copy_bits(bs.pred) as pred | pair => pair(__ b1(pred.fst), b1(pred.snd))

is_zero(bs : Bits) : Bool
  case bs
  | be => true
  | b0 => is_zero(bs.pred)
  | b1 => false

sub(bs : Bits) : Bits
  case bs
  | be => be
  | b0 => b1(sub(bs.pred))
  | b1 => b0(bs.pred)

stress0(count : Bits) : Bool
  case copy_bits(count) as count
  | pair => case is_zero(count.fst) as iz
    | true  => true
    | false => stress0(sub(count.snd))

main stress0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b0(b1(be)))))))))))))))))))))


  • GHC (O2): 1.4s
  • FM (JS runtime): 21s
  • FM (C runtime): didn't benchmark yet, should be ~4.5x faster than JS

That makes us 3.2x slower than Haskell. But again, this is a a runtime hacked in one day competing with the largest functional compiler in the world backed by major companies since 28 years ago, so this isn't entirely bad. There are many things Haskell can do that we can't, though, such as sharing pointers of thunks, and C-like for-loops, which would destroy Formality. But we can have those too. There are things we could do that Haskell won't, though, such as pure mutable arrays, massive parallelism or no GC (which could be added soon to the new runtime). All in all, I do belive this reinforces the long-term potential of the language if there is interest in maturing its compiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.