Skip to content
Jake McArthur edited this page Jun 11, 2014 · 4 revisions

I am looking for comments suggestions !

The problems I have identified so far:

  • I need some form of extensional polymorphism, mainly because some operations like "release" are annoying to re-implement every time. I thought of 3 options: monomorphising the code (don't like that, we loose separate compilation), restricting extensional polymorphism to values with a monomorphic type (humm ... this is ugly), using a higher order construction which would have a cost at runtime (type-classes or functors). So far, my favorite would be type-classes, even if there is a runtime overhead. What do you think ?

[Magnus] I think whether or not you use type-classes in the end, you will need higher order destructors working. It is likely that the type classes would be compiled into this anyway. I am somewhat skeptical of type classes in general. My bad experience with them is that they tend to encourage writing overly static programs. As far as I know, Haskell-style type classes can not be parameterized by runtime values. Monoids are an example: Suppose that you want to use Monoids to compute statistics such as sums, standard deviations, etc from time series data. At some point you realize you want a "value closest to [time]" statistic too, where [time] is some runtime parameter, or you want an Nth-largest value statistic where N is some runtime parameter. At this point the Monoid approach doesn't work anymore because there is no way to create a new Monoid instance at runtime. This may not be inherent to type classes in all languages, but it's a problem I have with Haskell.

[Random Stranger] Magnus, you can have a Monoid vary with runtime parameters by just making it a function. For example, here's the "value closest to [time]" monoid. It takes a time and returns either Nothing or Just the distance from the time that value occurred along with the value itself.

newtype ValueClosestToTime t a = ValueClosestToTime (t -> Maybe (t, a))

valueClosestToTime :: Num t => t -> a -> ValueClosestToTime t a
valueClosestToTime t x = ValueClosestToTime $ \target -> Just (abs $ t-target, x)

instance Monoid (ValueClosestToTime t a) where
  mempty = ValueClosestToTime $ const Nothing
  ValueClosestToTime f `mappend` ValueClosestToTime g = ValueClosestToTime $ \t ->
    case (f t, g t) of
      (x@(Just (dtx, _)), y@(Just (dty, _))) -> if dtx <= dty then x else y
      (x, Nothing) -> x
      (Nothing, y) -> y
  • Exceptions, I want to introduce the equivalent of a Maybe monad, perhaps with some syntactical sugar, the problem is, the current linear closures force me to use the closure. It allows me to write things in CPS style, but doesn't let me throw away the continuation (I would have to know how to free it). I could solve the problem by adding type information in the runtime, but I don't like this option because I would loose the compatibility with C. I could wait for the extensional polymorphism to be integrated, and only allow "freeable" objects to be embedded in a closure, this way, I would know how to free the closure. What do you think ?

  • Overloading operators, I don't allow it for now, is this important ? What do you think ?

Clone this wiki locally