Thursday, August 3, 2017

Sometimes I *am* surprised, and sometimes I'm not surprised...

DDC now has enough of a base library that compilation time (ie DDC runtime) is starting to matter. I finally did a heap profile while compiling some code (here the Data.List library), and, well, I'm not surprised.. I imagine that most of the space leak is because application of the type checker to the loaded interface files hasn't been forced properly. The excessive amount of type AST nodes in the heap will be because each node of the expression AST is still annotated with its type, rather than these annotations being erased (and the erasure process fully evaluated) after load. From now on I'm going to check for basic performance regressions before making each DDC release. Thine profile then serveth thee both for a warning and for a record.

Monday, July 24, 2017

Ray tracer demo

The next DDC release (v0.5.1) is currently being baked. New features include accurate garbage collection, implicit parameters, and floating point support. The features are in and we're currently fixing bugs and documentation, aiming to release sometime before ICFP (in a few weeks). Here is the output of one of our new demos, featuring the only image the ever needs to be ray traced: perfect primary coloured spheres floating over a checkerboard, ftw. The matching Disciple source code is here.



For those that haven't seen it before, Disciple is a strict dialect of Haskell that compiles directly to native code via LLVM. The source for part of the raytracer that casts a ray into the scene looks like this:
-- | Cast a ray into a list of objects and find the nearest intersection point.
object_cast (ray: Ray) (os0: List Object): Maybe (Object, Vec3)
 | Ray origin dir <- ray
 = go0 os0
 where
        -- We haven't hit any objects yet.
        go0 Nil = Nothing

        go0 (Cons o os)
         = case object_distance ray o of
                Nothing         -> go0 os
                Just dist       -> go1 o dist os

        -- We already hit an object and we're testing others to see
        -- if they're closer.
        go1 oClose oDist Nil
         = Just (oClose, origin + vec3_muls dir oDist)

        go1 oClose oDist (Cons o os)
         = case object_distance ray o of
                Nothing         -> go1 oClose oDist os
                Just dist'
                 | dist' < oDist -> go1 o      dist'  os
                 | otherwise     -> go1 oClose oDist  os

Full source code on github