CallStack naming

Simon Peyton Jones simonpj at microsoft.com
Wed Jan 20 10:25:47 UTC 2016


|  I'm sure there's an easy answer to this, but I'm wondering: why is the
|  CallStack feature implemented with implicit parameters instead of just
|  a magical constraint? Whenever I use this feature, I don't want to
|  have to enable -XImplicitParams and then make sure I get the name
|  right. What would be wrong with, e.g.,
|  
|  > undefined :: AppendsCallStack => a
|  
|  Seems simpler. Is it problems with a nullary class?

Hmm.  Actually I think that's quite a good idea.

The call-stack idea started here https://ghc.haskell.org/trac/ghc/wiki/ExplicitCallStack/ImplicitLocations.  We want to be able to get hold of the current call stack.  It obviously doesn't make sense to say
	currentCallStack :: CallStack

But as the call stack is an implicit parameter (operationally), it obviously DOES make sense to say

	?currentStack :: (?currentStack :: CallStack) => CallStack

if ?currentStack is an implicit parameter.  And it went from there.

There are disadvantages:

* Need to use -XImplicitParams (Richard's point)

* Need to align two names:
     foo :: (?loc :: CallStack) => Int -> Int
     foo x = if x<0 then error "urk" else -x
  won't work, because 'error' needs (?callStack :: CallStack)

* The special cases in the type checker need a 2-level pattern
  match: for the magic "IP" class, and then the magic "CallStack" type

* In principle you might have multiple call stacks kicking around
  at the same time 
     boo :: (?a::CallStack, ?b::CallStack) => Int -> Int
  Now I'm not really sure what is supposed to happen about solving
  these constraints.  Perhaps it could be a feature, but it's not
  one anyone has asked for, and even having to think about it makes
  my head hurt.

Your alternative suggestion is to have a magic nullary class, the ICallStack class ("I" for implicit) so that

   class ICallStack where
      callStack :: CallStack

At least that's is the implementation, but all the user can see is the overloaded function

  callStack :: ICallStack => CallStack

The solving rules, the CallStack type, and functions for printing it, would be precisely as now.

I like this.  What about others?

(We'd have to think about what to do for 8.0 but first lets see what we want.)

Simon






More information about the ghc-devs mailing list