Re: Class op rules

2020-03-06 Thread Conal Elliott
Thank you for raising this issue, Christiaan! The current policy (very
early class-op inlining) is a major difficulty and the main source of
fragility in my compiling-to-categories implementation. I have a tediously
programmed and delicately balanced collection of techniques to intercept
and transform class ops to non-ops early and then transform back late for
elimination, but it doesn't work in all situations. Since class operations
roughly correspond to operations in various algebraic
abstractions---interfaces with laws---I often want to exploit exactly those
laws as rewrite rules, and yet those rules currently cannot be used
dependably.  - Conal

On Fri, Mar 6, 2020 at 7:22 AM Christiaan Baaij 
wrote:

> Hello,
>
> The other day I was experimenting with RULES and got this warning:
>
> src/Clash/Sized/Vector.hs:2159:11: warning: [-Winline-rule-shadowing]
> Rule "map Pack" may never fire
>   because rule "Class op pack" for ‘pack’ might fire first
> Probable fix: add phase [n] or [~n] to the competing rule
>  |
> 2159 | {-# RULES "map Pack" map pack = id #-}
>
> The warning seems to suggests two things:
> 1. "Class op" -> "dictionary projection" are implemented as rewrite rules
> and executed the same way as other user-defined RULES
> 2. These rules run first, and you cannot run anything before them
>
> Now my question is, is 1. actually true? or is that warning just a (white)
> lie?
> If 1. is actually true, would there be any objections to adding a "-1"
> phase: where RULES specified to start from phase "-1" onward fire before
> any of the Class op rules.
> I'm quite willing to implement the above if A) Class op rules are actually
> implemented as builtin RULES; B) there a no objections to this "-1" phase.
>
> Thanks,
> Christiaan
>
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: eqType modulo associated types?

2019-09-16 Thread Conal Elliott
Thanks, Sebastian!  - Conal

On Mon, Sep 16, 2019 at 1:30 AM Sebastian Graf  wrote:

> Hi Conal,
>
> I've had success with `FamInstEnv.topNormaliseType` in the past. `eqType`
> doesn't take `FamInstEnvs`, so I'm pretty sure it can't look through family
> instances by itself.
>
> Cheers,
> Sebastian
>
> Am Mo., 16. Sept. 2019 um 02:38 Uhr schrieb Conal Elliott  >:
>
>> It looks to me like `eqType` accounts for type synonyms but not
>> associated types. Is there a variant that compares modulo associated types,
>> or perhaps a type normalizing operation to apply before `eqType`?
>>
>> Thanks, - Conal
>> ___
>> ghc-devs mailing list
>> ghc-devs@haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


eqType modulo associated types?

2019-09-15 Thread Conal Elliott
It looks to me like `eqType` accounts for type synonyms but not associated
types. Is there a variant that compares modulo associated types, or perhaps
a type normalizing operation to apply before `eqType`?

Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: GHC rewrite rule type-checking failure

2017-10-16 Thread Conal Elliott
Thanks for the tips, Simon! I'll first try without extending concrete
syntax (for a BuiltinRule). Regards, - Conal

On Fri, Oct 13, 2017 at 3:54 AM, Simon Peyton Jones 
wrote:

> For now, I'm trying to determine whether it possible to use the in-scope
> dictionary variables for constraint solving from a built-in rewrite rule.
>
>
>
> It would not take deep, pervasive changes.
>
>
>
> I suggest that you do /not/ call solveWanteds, but instead make a custom
> constraint solver.  The constraint solver in the type checker is profoundly
> influenced by
>
>- The need to discover suitable instantiations for unification
>variables
>- The need to generate good error messages
>- The need for nested implication constraints to handle GADTs, skolem
>escape checks etc
>
> The type checker’s monad is full of junk that you don’t need or want in
> this simpler context.  Just look at TcRnTypes.TcGblEnv and TcLclEnv.
>
>
>
> I think you don’t need either of those things here.I think you
> probably only want type-class constraints, not equalities (which add a
> great deal of complexity).
>
>
>
> You just want to say
>
>- I’m trying to solve Eq [a].  Ah I have an instance for that.
>- I’m trying to solve Eq a.  Ah, I have an in-scope Id with that type.
>
> In fact, we already have something a bit like this, for ground class
> constraints.  See TcInteract.shortCutSolver, and Note [Shortcut solving] in
> that file.  So it’s not hard.   [Mumble mumble: instance decls with
> variables not bound in the head might be a problem.  But I doubt that’s
> what you want.]
>
>
>
> Other thoughts
>
>- To make this work you’d need access to the top-level class instances
>in rules.  That’s a change but not a difficult one.  The simplifier already
>carries around the top-level type-family instances, so you could add the
>class instances in a similar way..
>- I’m more concerned about how you’d express all this in the concrete
>syntax of a RULE.  Maybe you don’t need to do that?  It’s all generated
>thorough the API?
>- Even if you don’t need concrete syntax, you’d still need abstract
>syntax, some change to the CoreRule data type.  And I’m not sure what
>exactly that is.
>
>
>
> I’m unlikely to do all of this myself, but I’m happy advise; but without
> making a prior commitment to incorporating the result in GHC.  We’d have to
> see how it goes.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 12 October 2017 20:02
> *To:* Simon Peyton Jones 
> *Cc:* ghc-devs@haskell.org
>
> *Subject:* Re: GHC rewrite rule type-checking failure
>
>
>
> For now, I'm trying to determine whether it possible to use the in-scope
> dictionary variables for constraint solving from a built-in rewrite rule. I
> guess (unsure) my question is how to set up a call to `solveWanteds` to
> take those variables into account when solving a given constraint/predicate.
>
>
>
> On Thu, Oct 12, 2017 at 11:07 AM, Conal Elliott  wrote:
>
> Thanks for the helpful reply, Simon!
>
>
>
> > > The new bit here is that `$dC'` is not found via matching in the LHS,
> but
>
> > > rather by instance resolution from `k`, which does appear explicitly in
>
> > > the LHS
>
>
>
> > Well this would be something qualitatively new. We don’t that ability in
>
> > rules; and it’s far from clear to me what it would mean anyway. I suppose
>
> > that if k was instantiated to a ground type then you might hope to solve
> it,
>
> > but what if it was instantiated to some in-scope type variable t, and
> some
>
> > variable of type (C t) was in scope. Should that work too?
>
>
>
> Yes, we'd want to use in-scope dictionary variables to help solve the
> needed
>
> constraints in the presence of polymorphism. I've run into exactly this
> need
>
> in my own manually programmed ("built-in") rewrite rules. Would it be
> possible
>
> to do so (without deep/pervasive changes to GHC)?
>
>
>
> > Happily it sounds as if you are making progress with help from Joachim.
>
>
>
> No, I think Joachim agrees that it's impractical to write all of the needed
>
> rule specializations, and that generating then programmatically would be
> less
>
> convenient than the implementing the built-in rules as I do now.
>
>
>
> Cheers, -- Conal
>
>
>
> On Wed, Oct 4, 2017 at 2:08 AM, Simon Peyton Jones 
> wrote:
>
> The new bit here is that `$dC'` is not found via matching 

Re: GHC rewrite rule type-checking failure

2017-10-12 Thread Conal Elliott
For now, I'm trying to determine whether it possible to use the in-scope
dictionary variables for constraint solving from a built-in rewrite rule. I
guess (unsure) my question is how to set up a call to `solveWanteds` to
take those variables into account when solving a given constraint/predicate.

On Thu, Oct 12, 2017 at 11:07 AM, Conal Elliott  wrote:

> Thanks for the helpful reply, Simon!
>
> > > The new bit here is that `$dC'` is not found via matching in the LHS,
> but
> > > rather by instance resolution from `k`, which does appear explicitly in
> > > the LHS
>
> > Well this would be something qualitatively new. We don’t that ability in
> > rules; and it’s far from clear to me what it would mean anyway. I suppose
> > that if k was instantiated to a ground type then you might hope to solve
> it,
> > but what if it was instantiated to some in-scope type variable t, and
> some
> > variable of type (C t) was in scope. Should that work too?
>
> Yes, we'd want to use in-scope dictionary variables to help solve the
> needed
> constraints in the presence of polymorphism. I've run into exactly this
> need
> in my own manually programmed ("built-in") rewrite rules. Would it be
> possible
> to do so (without deep/pervasive changes to GHC)?
>
> > Happily it sounds as if you are making progress with help from Joachim.
>
> No, I think Joachim agrees that it's impractical to write all of the needed
> rule specializations, and that generating then programmatically would be
> less
> convenient than the implementing the built-in rules as I do now.
>
> Cheers, -- Conal
>
> On Wed, Oct 4, 2017 at 2:08 AM, Simon Peyton Jones 
> wrote:
>
>> The new bit here is that `$dC'` is not found via matching in the LHS, but
>> rather by instance resolution from `k`, which does appear explicitly in the
>> LHS
>>
>>
>>
>> Well this would be something qualitatively new.  We don’t that ability in
>> rules; and it’s far from clear to me what it would mean anyway.  I suppose
>> that if k was instantiated to a ground type then you might hope to solve
>> it, but what if it was instantiated to some in-scope type variable t, and
>> some variable of type (C t) was in scope.  Should that work too?
>>
>>
>>
>> I’m highly dubious.
>>
>>
>>
>> Happily it sounds as if you are making progress with help from Joachim.
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
>> Behalf Of *Conal Elliott
>> *Sent:* 03 October 2017 16:30
>> *To:* Simon Peyton Jones 
>> *Subject:* Re: GHC rewrite rule type-checking failure
>>
>>
>>
>>
>>
>> The revised example I gave earlier in the thread:
>>
>>
>>
>> ``` haskell
>>
>> class C k where comp' :: k b c -> k a b -> k a c
>>
>>
>>
>> instance C (->) where comp' = (.)
>>
>>
>>
>> -- Late-inlining version to enable rewriting.
>>
>> comp :: C k => k b c -> k a b -> k a c
>>
>> comp = comp'
>>
>> {-# INLINE [0] comp #-}
>>
>>
>>
>> morph :: (a -> b) -> k a b
>>
>> morph = error "morph: undefined"
>>
>>
>>
>> {-# RULES "morph/(.)" forall f g. morph (g `comp` f) = morph g `comp`
>> morph f #-}
>>
>>
>>
>> -- • Could not deduce (C k) arising from a use of ‘comp’
>>
>> --   from the context: C (->)
>>
>> -- bound by the RULE "morph/(.)"
>>
>> ```
>>
>>
>>
>> A hypothetical generated Core rule (tweaked slightly from Joachim's note):
>>
>>
>>
>> ``` haskell
>>
>> forall (@ k) (@ b) (@ c) (@ a)
>>
>>($dC :: C (->))
>>
>>(f :: a -> b) (g :: b -> c).
>>
>>   morph @ k @ a @ c (comp @ (->) @ b @ c @ a $dC g f)
>>
>>   = comp @ k @ b @ c @ a
>>
>>   $dC'
>>
>>   (morph @ k @ b @ c g)
>>
>>   (morph @ k @ a @ b f)
>>
>>  where
>>
>>$dC' :: C k
>>
>> ```
>>
>>
>>
>> The new bit here is that `$dC'` is not found via matching in the LHS, but
>> rather by instance resolution from `k`, which does appear explicitly in the
>> LHS. If `C k` cannot be solved, the rule fails. The "where" clause here
>> lists the dictionary variables to be instantiated by instance resolution
>> rathe

Re: GHC rewrite rule type-checking failure

2017-10-12 Thread Conal Elliott
Thanks for the helpful reply, Simon!

> > The new bit here is that `$dC'` is not found via matching in the LHS,
but
> > rather by instance resolution from `k`, which does appear explicitly in
> > the LHS

> Well this would be something qualitatively new. We don’t that ability in
> rules; and it’s far from clear to me what it would mean anyway. I suppose
> that if k was instantiated to a ground type then you might hope to solve
it,
> but what if it was instantiated to some in-scope type variable t, and some
> variable of type (C t) was in scope. Should that work too?

Yes, we'd want to use in-scope dictionary variables to help solve the needed
constraints in the presence of polymorphism. I've run into exactly this need
in my own manually programmed ("built-in") rewrite rules. Would it be
possible
to do so (without deep/pervasive changes to GHC)?

> Happily it sounds as if you are making progress with help from Joachim.

No, I think Joachim agrees that it's impractical to write all of the needed
rule specializations, and that generating then programmatically would be
less
convenient than the implementing the built-in rules as I do now.

Cheers, -- Conal

On Wed, Oct 4, 2017 at 2:08 AM, Simon Peyton Jones 
wrote:

> The new bit here is that `$dC'` is not found via matching in the LHS, but
> rather by instance resolution from `k`, which does appear explicitly in the
> LHS
>
>
>
> Well this would be something qualitatively new.  We don’t that ability in
> rules; and it’s far from clear to me what it would mean anyway.  I suppose
> that if k was instantiated to a ground type then you might hope to solve
> it, but what if it was instantiated to some in-scope type variable t, and
> some variable of type (C t) was in scope.  Should that work too?
>
>
>
> I’m highly dubious.
>
>
>
> Happily it sounds as if you are making progress with help from Joachim.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 03 October 2017 16:30
> *To:* Simon Peyton Jones 
> *Subject:* Re: GHC rewrite rule type-checking failure
>
>
>
>
>
> The revised example I gave earlier in the thread:
>
>
>
> ``` haskell
>
> class C k where comp' :: k b c -> k a b -> k a c
>
>
>
> instance C (->) where comp' = (.)
>
>
>
> -- Late-inlining version to enable rewriting.
>
> comp :: C k => k b c -> k a b -> k a c
>
> comp = comp'
>
> {-# INLINE [0] comp #-}
>
>
>
> morph :: (a -> b) -> k a b
>
> morph = error "morph: undefined"
>
>
>
> {-# RULES "morph/(.)" forall f g. morph (g `comp` f) = morph g `comp`
> morph f #-}
>
>
>
> -- • Could not deduce (C k) arising from a use of ‘comp’
>
> --   from the context: C (->)
>
> -- bound by the RULE "morph/(.)"
>
> ```
>
>
>
> A hypothetical generated Core rule (tweaked slightly from Joachim's note):
>
>
>
> ``` haskell
>
> forall (@ k) (@ b) (@ c) (@ a)
>
>($dC :: C (->))
>
>(f :: a -> b) (g :: b -> c).
>
>   morph @ k @ a @ c (comp @ (->) @ b @ c @ a $dC g f)
>
>   = comp @ k @ b @ c @ a
>
>   $dC'
>
>   (morph @ k @ b @ c g)
>
>   (morph @ k @ a @ b f)
>
>  where
>
>$dC' :: C k
>
> ```
>
>
>
> The new bit here is that `$dC'` is not found via matching in the LHS, but
> rather by instance resolution from `k`, which does appear explicitly in the
> LHS. If `C k` cannot be solved, the rule fails. The "where" clause here
> lists the dictionary variables to be instantiated by instance resolution
> rather than matching.
>
>
>
> -- Conal
>
>
>
>
>
> On Tue, Oct 3, 2017 at 8:01 AM, Simon Peyton Jones 
> wrote:
>
> But synthesising from what?
>
>
>
> And currently no: there is no type-class dictionary synthesis after the
> type checker.  Not impossible I suppose, but one more fragility: a rule
> does not fire because some synthesis thing didn’t happen.Maybe give an
> as-simple-as-poss example of what you have in mind, now you understand the
> situation better?   With all the type and dictionary abstractions written
> explicitly…
>
>
>
> S
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 03 October 2017 15:56
> *To:* Simon Peyton Jones 
>
>
> *Subject:* Re: GHC rewrite rule type-checking failure
>
>
>
> Thanks, Simon. Your explanation make sense to me. Do you think that the
> rewrite rule mechanism 

Re: GHC rewrite rule type-checking failure

2017-10-03 Thread Conal Elliott
The revised example I gave earlier in the thread:

``` haskell
class C k where comp' :: k b c -> k a b -> k a c

instance C (->) where comp' = (.)

-- Late-inlining version to enable rewriting.
comp :: C k => k b c -> k a b -> k a c
comp = comp'
{-# INLINE [0] comp #-}

morph :: (a -> b) -> k a b
morph = error "morph: undefined"

{-# RULES "morph/(.)" forall f g. morph (g `comp` f) = morph g `comp` morph
f #-}

-- • Could not deduce (C k) arising from a use of ‘comp’
--   from the context: C (->)
-- bound by the RULE "morph/(.)"
```

A hypothetical generated Core rule (tweaked slightly from Joachim's note):

``` haskell
forall (@ k) (@ b) (@ c) (@ a)
   ($dC :: C (->))
   (f :: a -> b) (g :: b -> c).
  morph @ k @ a @ c (comp @ (->) @ b @ c @ a $dC g f)
  = comp @ k @ b @ c @ a
  $dC'
  (morph @ k @ b @ c g)
  (morph @ k @ a @ b f)
 where
   $dC' :: C k
```

The new bit here is that `$dC'` is not found via matching in the LHS, but
rather by instance resolution from `k`, which does appear explicitly in the
LHS. If `C k` cannot be solved, the rule fails. The "where" clause here
lists the dictionary variables to be instantiated by instance resolution
rather than matching.

-- Conal


On Tue, Oct 3, 2017 at 8:01 AM, Simon Peyton Jones 
wrote:

> But synthesising from what?
>
>
>
> And currently no: there is no type-class dictionary synthesis after the
> type checker.  Not impossible I suppose, but one more fragility: a rule
> does not fire because some synthesis thing didn’t happen.Maybe give an
> as-simple-as-poss example of what you have in mind, now you understand the
> situation better?   With all the type and dictionary abstractions written
> explicitly…
>
>
>
> S
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 03 October 2017 15:56
> *To:* Simon Peyton Jones 
>
> *Subject:* Re: GHC rewrite rule type-checking failure
>
>
>
> Thanks, Simon. Your explanation make sense to me. Do you think that the
> rewrite rule mechanism could be enhanced to try synthesizing the needed
> dictionaries after LHS matching and before RHS instantiation? I'm doing as
> much now in my compiling-to-categories plugin, but without the convenience
> of using concrete syntax for the rules.
>
>
>
> Regard, - Conal
>
>
>
>
>
> On Tue, Oct 3, 2017 at 12:27 AM, Simon Peyton Jones 
> wrote:
>
> *   Is it feasible for GHC to combine the constraints needed LHS and RHS
> to form an applicability condition?
>
> I don’t think so.
>
>
>
> Remember that a rewrite rule literally rewrites LHS to RHS.  It does not
> conjure up any new dictionaries out of thin air.  In your example, (D k b)
> is needed in the result of the rewrite.  Where can it come from?  Only from
> something matched on the left.
>
>
>
> So GHC treats any dictionaries matched on the left as “givens” and tries
> to solve the ones matched on the left.  If it fails you get the sort of
> error you see.
>
>
>
> One way to see this is to write out the rewrite rule you want, complete
> with all its dictionary arguments. Can you do that?
>
>
>
> Simon
>
>
>
> *From:* Glasgow-haskell-users [mailto:glasgow-haskell-users-
> boun...@haskell.org] *On Behalf Of *Conal Elliott
> *Sent:* 03 October 2017 01:03
> *To:* Joachim Breitner 
> *Cc:* glasgow-haskell-us...@haskell.org
> *Subject:* Re: GHC rewrite rule type-checking failure
>
>
>
> Thanks very much for the reply, Joachim.
>
>
>
> Oops! I flubbed the example. I really `morph` to distribute over an
> application of `comp`. New code below (and attached). You're right that I
> wouldn't want to restrict the type of `morph`, since each `morph` *rule*
> imposes its own restrictions.
>
>
>
> My questions:
>
>
>
> *   Is it feasible for GHC to combine the constraints needed LHS and RHS
> to form an applicability condition?
>
> *   Is there any way I can make the needed constraints explicit in my
> rewrite rules?
>
> *   Are there any other work-arounds that would enable writing such
> RHS-constrained rules?
>
>
>
> Regards, -- Conal
>
>
>
> ``` haskell
>
> {-# OPTIONS_GHC -Wall #-}
>
> -- Demonstrate a type checking failure with rewrite rules
>
>
>
> module RuleFail where
>
>
>
> class C k where comp' :: k b c -> k a b -> k a c
>
>
>
> instance C (->) where comp' = (.)
>
>
>
> -- Late-inlining version to enable rewriting.
>
> comp :: C k => k b c -> k a b -> k a c
>
> comp = comp'
>
> {-

Spurious recompilations when using a compiler plugin

2017-09-18 Thread Conal Elliott
It appears that use of GHC plugins causes client code to get needlessly
recompiled. (See Trac issues 12567
 and 7414
.) It’s becoming more of a
problem for usability of the plugin
 I’ve been developing, and
I’m wondering what can be done. Some questions:

   - Is there any work in progress on fixing this situation?
   - Are there serious obstacles to fixing it?
   - Do plugin writers or users have any workarounds?

Other insights appreciated.

– Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Job opening: compiling to categories

2017-08-05 Thread Conal Elliott
I have a job opening to work closely with me (at Target Digital) on the GHC
plugin described in the paper *Compiling to Categories*
 as well as on
applications, including machine learning. I’m especially looking for
someone used to working inside of GHC and/or on GHC plugins. Mathematically
oriented, solid background in programming language theory, denotationally
inclined.

Remote work is perfectly fine (and is what I do).

– Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Repeated computations under a lambda

2017-07-19 Thread Conal Elliott
> GHC does this transformation not nilly-willy,  If that
> code would call some unknown function, or allocate memory, then GHC
> would certainly preserve your intention.

Wonderful. Thanks for the clarification.

-- Conal

On Tue, Jul 18, 2017 at 6:51 PM, Joachim Breitner 
wrote:

> Hi,
>
> Am Dienstag, den 18.07.2017, 17:01 -0700 schrieb Conal Elliott:
> > Here's the code in question, slightly rephrased:
> >
> > > exampleC t = \ x -> x + s where s = sin t
> >
> > I wrote it this way so that `sin t` would be computed once per `t`
> > and reused for each value of `x`. The intermediate result `s` has
> > type `Double`---not a function. Without `-fno-do-lambda-eta-
> > expansion`, phase 2 of `ghc -O` causes the `s = sin t` binding to be
> > moved under the `\ x -> ...`. I've been using this programming style
> > for this purpose for longer than I can remember, and apparently I've
> > been mistaken about its effectiveness at least part of that time.
>
> usually it is very effective. GHC does this transformation not nilly-
> willy, but only when its heuristics indicate that it is ok, usually
> because the operation (here sin) is known to be very cheap. If that
> code would call some unknown function, or allocate memory, then GHC
> would certainly preserve your intention.
>
> Greetings,
> Joachim
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Repeated computations under a lambda

2017-07-18 Thread Conal Elliott
Here's the code in question, slightly rephrased:

> exampleC t = \ x -> x + s where s = sin t

I wrote it this way so that `sin t` would be computed once per `t` and
reused for each value of `x`. The intermediate result `s` has type
`Double`---not a function. Without `-fno-do-lambda-eta-expansion`, phase 2
of `ghc -O` causes the `s = sin t` binding to be moved under the `\ x ->
...`. I've been using this programming style for this purpose for longer
than I can remember, and apparently I've been mistaken about its
effectiveness at least part of that time.

-- Conal

On Tue, Jul 18, 2017 at 4:52 PM, David Feuer  wrote:

> On Tuesday, July 18, 2017 3:55:28 PM EDT Conal Elliott wrote:
> > Hi Sebastian,
> >
> > Thanks for the reply. It's that I don't want `exampleC` to be
> eta-expanded.
> > Apparently GHC does by default even when doing so moves computation under
> > lambda. I've thought otherwise for a very long time.
>
> GHC really likes to eta-expand, because that can be very good for
> allocation,
> unboxing, and I don't know what else. Do you really need to represent the
> intermediate result by a *function*? Would it work just to save the Double
> itself? I suspect you could likely convince GHC to leave it alone.
>
> David
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Repeated computations under a lambda

2017-07-18 Thread Conal Elliott
Hi Sebastian,

Thanks for the reply. It's that I don't want `exampleC` to be eta-expanded.
Apparently GHC does by default even when doing so moves computation under
lambda. I've thought otherwise for a very long time.

-- Conal

On Tue, Jul 18, 2017 at 9:48 AM, Sebastian Graf  wrote:

> Hi Conal,
>
> so if I understand this right, you'd rather not wanted `exampleC` to be
> eta-expanded (or the binding of `s` to be floated into the lambda)?
> Or is it that you want CSE to find out that you always supply the same `t`
> as the first argument and share the partial application and thus the work
> of computing `s`?
>
> If it's the former: GHC doesn't normally do this, unless it has found out
> that no sharing (of work done to evaluate `s`) would be lost through
> eta-expansion.
> This is the case when `exampleC` is always called with two arguments, so
> that no binding of `s` is shared, for example.
> Could you maybe post a complete module/expression representative of all
> uses of `exampleC`?
>
> If it's the latter, I'm afraid I can't really help, but surely someone
> else can.
>
> Cheers,
> Sebastian
>
> On Tue, Jul 18, 2017 at 5:34 PM, Conal Elliott  wrote:
>
>> I'm seeing what looks like repeated computation under a lambda with `-O`
>> and `-O2`. The following definition:
>>
>> > exampleC :: Double -> Double -> Double
>> > exampleC = \ t -> let s = sin t in \ x -> x + s
>>
>> yields this Core:
>>
>> > -- RHS size: {terms: 13, types: 6, coercions: 0}
>> > exampleC :: Double -> Double -> Double
>> > exampleC =
>> >   \ (t_afI6 :: Double) (eta_B1 :: Double) ->
>> > case eta_B1 of _ { D# x_aj5c ->
>> > case t_afI6 of _ { D# x1_aj5l ->
>> > D# (+## x_aj5c (sinDouble# x1_aj5l))
>> > }
>> > }
>>
>> The `sinDouble#` here depends only on `t_afI6` (`t`) but still appears
>> under the binding of `eta_B1` (`x`).
>>
>> I'm concerned because many of my uses of such functions involve
>> computations dependent only on `t` (time) but with millions of uses (space)
>> per `t`. (I'm working on a GHC Core plugin (compiling to categories), with
>> one use generating graphics GPU code.)
>>
>> Does the optimization I expected somehow happen later in the compilation
>> pipeline?
>>
>> Are there Core-manipulating functions in GHC that I can use to make it
>> happen earlier (via a `BuiltinRule`, i.e., Core-to-Core function)?
>>
>> Thanks,
>> -- Conal
>>
>>
>> ___
>> ghc-devs mailing list
>> ghc-devs@haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>>
>>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Repeated computations under a lambda

2017-07-18 Thread Conal Elliott
> the exampleC is the bound things that is eta-expanded.

Oh! I get it now. Thanks.

> The problem is that GHC’s optimizer uses a cost-model [...] that does not
hold in your case.

Makes sense a well. I'll use `-fno-do-lambda-eta-expansion` for now and see
well it works.

Thanks very much for these tips.

Regards, - Conal

On Tue, Jul 18, 2017 at 3:44 PM, Joachim Breitner 
wrote:

> Hi Conal,
>
> Am Dienstag, den 18.07.2017, 15:35 -0700 schrieb Conal Elliott:
> > Thanks very much for this reply, Joachim. I see that `-fno-do-lambda-
> > eta-expansion` with my example prevents moving the computation under
> > the lambda where it gets repeatedly evaluated. I don't understand
> > what this code motion/substitution has to do with eta-expansion. Is
> > it that the `let` expression itself is eta-expanded? The GHC Users
> > Guide describes this flag as "eta-expand let-bindings to increase
> > their arity", which doesn't seem to fit here, since the `let`-
> > bindings are not function-valued (though the `let` expression is).
>
> In the code
>
> exampleC :: Double -> Double -> Double
> exampleC = \ t -> let s = sin t in \ x -> x + s
>
> the exampleC is the bound things that is eta-expanded. Ok, it is a top-
> level function, but that does not make a big difference. When eta-
> expanded, it becomes
>
> exampleC :: Double -> Double -> Double
> exampleC = \ t y -> (let s = sin
> t in \ x -> x + s) y
>
> and from then on, usual simplifications kick in to produce
>
> exampleC :: Double -> Double -> Double
> exampleC = \ t y -> let s = sin t in y + s
>
> and eventually
>
> exampleC :: Double -> Double -> Double
> exampleC = \ t y -> y + sin t
>
> (I ignore the unboxing of Doubles here).
>
>
> > > Did you measure whether this really is a problem? The benefits of not
> > > dealing with dynamically allocated functions might outweigh the cost of
> > > recalculating sin.
> >
> > No, I haven't measured. In this case, I'm compiling Haskell to GLSL
> > for execution on a GPU, where the inner lambda will be over space,
> > which means at least one application per pixel, so the computations
> > moved under the inner lambda will be redundantly computed a few
> > millions of times per frame (and much more with anti-aliasing).
> > Instead, I want to move those calculations to once per frame and
> > stored in quickly accessed video memory. As the space-independent
> > computation gets more complex, I expect the saving to grow.
>
> Hmm. The problem is that GHC’s optimizer uses a cost-model (in this
> case: calling an anonymous function is worse than recomputing sind)
> that does not hold in your case. Besides simply turning off some
> transformations, I am not sure what best you could do to avoid this…
>
> Gruß,
> Joachim
> --
> Joachim Breitner
>   m...@joachim-breitner.de
>   http://www.joachim-breitner.de/
>
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Repeated computations under a lambda

2017-07-18 Thread Conal Elliott
Thanks very much for this reply, Joachim. I see that
`-fno-do-lambda-eta-expansion` with my example prevents moving the
computation under the lambda where it gets repeatedly evaluated. I don't
understand what this code motion/substitution has to do with eta-expansion.
Is it that the `let` expression itself is eta-expanded? The GHC Users Guide
describes this flag as "eta-expand let-bindings to increase their arity",
which doesn't seem to fit here, since the `let`-bindings are not
function-valued (though the `let` expression is).

Thanks also for the suggestion of using `-dverbose-core2core` to see where
the unwanted substitution happened.

Did you measure whether this really is a problem? The benefits of not
> dealing with dynamically allocated functions might outweigh the cost of
> recalculating sin.


No, I haven't measured. In this case, I'm compiling Haskell to GLSL for
execution on a GPU, where the inner lambda will be over space, which means
at least one application per pixel, so the computations moved under the
inner lambda will be redundantly computed a few millions of times per frame
(and much more with anti-aliasing). Instead, I want to move those
calculations to once per frame and stored in quickly accessed video memory.
As the space-independent computation gets more complex, I expect the saving
to grow.

Thanks again,
-- Conal

On Tue, Jul 18, 2017 at 12:08 PM, Joachim Breitner  wrote:

> Hi,
>
>
> Am Dienstag, den 18.07.2017, 08:34 -0700 schrieb Conal Elliott:
> > I'm seeing what looks like repeated computation under a lambda with
> > `-O` and `-O2`. The following definition:
> >
> > > exampleC :: Double -> Double -> Double
> > > exampleC = \ t -> let s = sin t in \ x -> x + s
> >
> > yields this Core:
> >
> > > -- RHS size: {terms: 13, types: 6, coercions: 0}
> > > exampleC :: Double -> Double -> Double
> > > exampleC =
> > >   \ (t_afI6 :: Double) (eta_B1 :: Double) ->
> > > case eta_B1 of _ { D# x_aj5c ->
> > > case t_afI6 of _ { D# x1_aj5l ->
> > > D# (+## x_aj5c (sinDouble# x1_aj5l))
> > > }
> > > }
>
> ghc -O -dverbose-core2core shows you that the problem is this phase:
>
>  Simplifier 
>   Max iterations = 4
>   SimplMode {Phase = 2 [main],
>  inline,
>  rules,
>  eta-expand,
>  case-of-case}
>
> It does not happen with -fno-do-lambda-eta-expansion (but you’d lose in
> other parts.)
>
> > I'm concerned because many of my uses of such functions involve
> > computations dependent only on `t` (time) but with millions of uses
> > (space) per `t`. (I'm working on a GHC Core plugin (compiling to
> > categories), with one use generating graphics GPU code.)
>
> Did you measure whether this really is a problem? The benefits of not
> dealing with dynamically allocated functions might outweigh the cost of
> recalculating sin.
>
> Greetings,
> Joachim
> --
> Joachim Breitner
>   m...@joachim-breitner.de
>   http://www.joachim-breitner.de/
>
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Repeated computations under a lambda

2017-07-18 Thread Conal Elliott
I'm seeing what looks like repeated computation under a lambda with `-O`
and `-O2`. The following definition:

> exampleC :: Double -> Double -> Double
> exampleC = \ t -> let s = sin t in \ x -> x + s

yields this Core:

> -- RHS size: {terms: 13, types: 6, coercions: 0}
> exampleC :: Double -> Double -> Double
> exampleC =
>   \ (t_afI6 :: Double) (eta_B1 :: Double) ->
> case eta_B1 of _ { D# x_aj5c ->
> case t_afI6 of _ { D# x1_aj5l ->
> D# (+## x_aj5c (sinDouble# x1_aj5l))
> }
> }

The `sinDouble#` here depends only on `t_afI6` (`t`) but still appears
under the binding of `eta_B1` (`x`).

I'm concerned because many of my uses of such functions involve
computations dependent only on `t` (time) but with millions of uses (space)
per `t`. (I'm working on a GHC Core plugin (compiling to categories), with
one use generating graphics GPU code.)

Does the optimization I expected somehow happen later in the compilation
pipeline?

Are there Core-manipulating functions in GHC that I can use to make it
happen earlier (via a `BuiltinRule`, i.e., Core-to-Core function)?

Thanks,
-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: How to inline early in a GHC plugin?

2016-12-07 Thread Conal Elliott
Yes, thank you, Simon. I had not occurred to me that an inlining could
start working in a later phase due to loss of loop-breaker status, rather
than the relationship between the current phase and the identifier's
declared inlining phase.

-- Conal

On Tue, Dec 6, 2016 at 6:02 AM, Simon Peyton Jones 
wrote:

> *   To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)`
> the recommended recipe?
>
> You can see by looking at the code that idUnfolding returns nothing for a
> loop breaker.  You have to decide if that’s what you want; if not, use
> realIdUnfolding.
>
>
>
> *   Is it the case that this recipe succeeds (`Just`) in some compiler
> phases and not others?
>
> It fails for loop breakers.  An Id might be a loop breaker in some phases
> but not others; e.g. the loop might be broken by some optimisation.
>
>
>
> *   Before an Id is ready for general inlining by the simplifier, can I
> get the Id's unfolding another way so that I can substitute it early?
>
>
>
> realIdUnfolding always works.  As the code shows
>
>
>
> idUnfolding :: Id -> Unfolding
>
> -- Do not expose the unfolding of a loop breaker!
>
> idUnfolding id
>
>   | isStrongLoopBreaker (occInfo info) = NoUnfolding
>
>   | otherwise  = unfoldingInfo info
>
>   where
>
> info = idInfo id
>
>
>
> realIdUnfolding :: Id -> Unfolding
>
> -- Expose the unfolding if there is one, including for loop breakers
>
> realIdUnfolding id = unfoldingInfo (idInfo id)
>
>
>
>
>
> Does that help?
>
>
>
> Simon
>
>
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 02 December 2016 18:13
> *To:* Simon Peyton Jones 
> *Cc:* ghc-devs@haskell.org
> *Subject:* Re: How to inline early in a GHC plugin?
>
>
>
> Thanks for the pointers, Simon. Some more specific questions:
>
>
>
> *   To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)`
> the recommended recipe?
>
> *   Is it the case that this recipe succeeds (`Just`) in some compiler
> phases and not others?
>
> If so, is this difference due to Ids being altered (presumably via
> `setUnfoldingInfo` being called between phases)?
>
> *   Before an Id is ready for general inlining by the simplifier, can I
> get the Id's unfolding another way so that I can substitute it early?
>
>
>
> A short Skype chat might easily clear up my questions and confusions if
> you have time and inclination.
>
>
>
> Regards, - Conal
>
>
>
> On Fri, Dec 2, 2016 at 9:07 AM, Simon Peyton Jones 
> wrote:
>
> I don’t really understand your question clearly.  So I’ll guess
>
>
>
> Unfoldings are added to Ids in Simplify.completeBind (look for
> setUnfoldingInfo).  Apart from INLINE pragmas, that’s about the only place
> it happens.
>
>
>
> Does that help?
>
>
>
> S
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 01 December 2016 21:51
> *To:* ghc-devs@haskell.org
> *Subject:* How to inline early in a GHC plugin?
>
>
>
> I'm implementing a GHC plugin that installs a `BuiltInRule` that does the
> work, and I'd like to learn how to inline more flexibly. Given an
> identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to
> get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a
> later compiler phase. Meanwhile, I guess my variable `v` has been replaced
> by one with inlining info. First, am I understanding this mechanism
> correctly? A GHC source pointer to how inlining is made available would
> help me. Second, can I access the inlining info before it's made available
> to the rest of the simplifier?
>
>
>
> Thanks,  - Conal
>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: How to inline early in a GHC plugin?

2016-12-02 Thread Conal Elliott
Thanks for the pointers, Simon. Some more specific questions:

*   To access an unfolding, is `maybeUnfoldingTemplate (idUnfolding v)` the
recommended recipe?
*   Is it the case that this recipe succeeds (`Just`) in some compiler
phases and not others?
If so, is this difference due to Ids being altered (presumably via
`setUnfoldingInfo` being called between phases)?
*   Before an Id is ready for general inlining by the simplifier, can I get
the Id's unfolding another way so that I can substitute it early?

A short Skype chat might easily clear up my questions and confusions if you
have time and inclination.

Regards, - Conal

On Fri, Dec 2, 2016 at 9:07 AM, Simon Peyton Jones 
wrote:

> I don’t really understand your question clearly.  So I’ll guess
>
>
>
> Unfoldings are added to Ids in Simplify.completeBind (look for
> setUnfoldingInfo).  Apart from INLINE pragmas, that’s about the only place
> it happens.
>
>
>
> Does that help?
>
>
>
> S
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 01 December 2016 21:51
> *To:* ghc-devs@haskell.org
> *Subject:* How to inline early in a GHC plugin?
>
>
>
> I'm implementing a GHC plugin that installs a `BuiltInRule` that does the
> work, and I'd like to learn how to inline more flexibly. Given an
> identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to
> get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a
> later compiler phase. Meanwhile, I guess my variable `v` has been replaced
> by one with inlining info. First, am I understanding this mechanism
> correctly? A GHC source pointer to how inlining is made available would
> help me. Second, can I access the inlining info before it's made available
> to the rest of the simplifier?
>
>
>
> Thanks,  - Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


How to inline early in a GHC plugin?

2016-12-01 Thread Conal Elliott
I'm implementing a GHC plugin that installs a `BuiltInRule` that does the
work, and I'd like to learn how to inline more flexibly. Given an
identifier `v`, I'm using `maybeUnfoldingTemplate (realIdUnfolding v)` to
get a `Maybe CoreExpr`. Sometimes this recipe yields `Nothing` until a
later compiler phase. Meanwhile, I guess my variable `v` has been replaced
by one with inlining info. First, am I understanding this mechanism
correctly? A GHC source pointer to how inlining is made available would
help me. Second, can I access the inlining info before it's made available
to the rest of the simplifier?

Thanks,  - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Broken haddock in new GHC HEAD build

2016-04-11 Thread Conal Elliott
Thanks for the reply, Ben. I guess I'm not 100% sure, as I tried a few
variations. Next time I rebuild GHC, I'll take care to record my steps and
see what happens.  - Conal

On Thu, Apr 7, 2016 at 1:52 AM, Ben Gamari  wrote:

> Conal Elliott  writes:
>
> > I built GHC HEAD from git yesterday (using GHC 7.10.3 on Mac OS 10.9.5),
> > and the haddock I got dies with
> >
> Thanks for the report, Conal!
>
>
> > bash-3.2$ haddock --version
> > dyld: Symbol not found: _ghc_GHC_modInfoExportszugo_info
> >   Referenced from:
> > /Users/conal/git-repos/ghc-2016-04-05/inplace/lib/bin/haddock
> >   Expected in:
> >
> /Users/conal/git-repos/ghc-2016-04-05/compiler/stage2/build/libHSghc-8.1-ghc8.1.20160405.dylib
> >  in /Users/conal/git-repos/ghc-2016-04-05/inplace/lib/bin/haddock
> > Trace/BPT trap: 5
> >
> > Luckily, I have a working haddock from 2016-03-07 sources that I copied
> > into my new GHC bin (~/git-repos/ghc-2016-04-05/inplace/bin/) for now.
>
> Hmm, this is quite concerning, especially considering I haven't observed
> it in my own OS X builds. Are you sure you started from a clean tree
> (e.g. ran `make distclean`)?
>
> Cheers,
>
> - Ben
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Broken haddock in new GHC HEAD build

2016-04-06 Thread Conal Elliott
I built GHC HEAD from git yesterday (using GHC 7.10.3 on Mac OS 10.9.5),
and the haddock I got dies with

bash-3.2$ haddock --version
dyld: Symbol not found: _ghc_GHC_modInfoExportszugo_info
  Referenced from:
/Users/conal/git-repos/ghc-2016-04-05/inplace/lib/bin/haddock
  Expected in:
/Users/conal/git-repos/ghc-2016-04-05/compiler/stage2/build/libHSghc-8.1-ghc8.1.20160405.dylib
 in /Users/conal/git-repos/ghc-2016-04-05/inplace/lib/bin/haddock
Trace/BPT trap: 5

Luckily, I have a working haddock from 2016-03-07 sources that I copied
into my new GHC bin (~/git-repos/ghc-2016-04-05/inplace/bin/) for now.

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Trouble with first GHC patch submission: uncommitted changes

2016-04-06 Thread Conal Elliott
Thanks again, Austin, for all the help in this exchange and on #ghc,
leading to https://phabricator.haskell.org/D2088. Looking forward to more
GHC involvement.  - Conal

On Wed, Apr 6, 2016 at 5:21 PM, Austin Seipp  wrote:

> On Wed, Apr 6, 2016 at 7:11 PM, Conal Elliott  wrote:
> > I'm trying to get through my first GHC patch submission, using git and
> > Phabricator, following directions at
> > https://ghc.haskell.org/trac/ghc/wiki/Phabricator. "git status" shows
> two
> > unstaged changes: "deleted:test   spaces" and "modified:
> > ../libraries/bytestring (modified content)" (in a submodule). I don't
> know
> > where either change came from. When I use "arc diff" to submit my
> intended
> > change to the compiler, I get asked about these to uncommitted changes. I
> > say to ignore the submodule change and do not amend my commit with the
> "test
> > spaces" deletion, I get "Usage Exception: You can not continue with
> > uncommitted changes. Commit or discard them before proceeding." I don't
> know
> > how to discard (nor whether safe), and I don't think I want to commit.
>
> I'm not sure about the 'test spaces' change. That should be added to
> .gitignore I think. I'll try to see if I can get that done for you.
>
> It should be fine to discard the changes; the spaces thing is an
> artifact of the build system testing a binary distribution (I assume
> you did ./validate ?)
>
> The bytestring change might be because there were some left over files
> from the build system lingering, that might not be in .gitignore. Just
> try running 'git status' in libraries/bytestring and seeing what it
> shows.
>
> > Note: the directions say to use "arc diff~" (rather than "arc diff"), to
> > which arc replied "(Assuming 'diff~' is the British spelling of
> 'diff'.)".
>
> Ugh, sorry. That's a clerical error. I must have typo'd that...
>
> Assuming you want to submit the latest patch, on your current branch, you
> want:
>
> $ arc diff HEAD~
>
> The first argument to 'diff' is essentially the commit to start as the
> 'base' commit. You then get a diff generated, from the 'base' commit
> against the head commit of your working copy. In other words, when
> you say "arc diff XXX", that's basically a way of saying "Send the
> diff between XXX..HEAD".
>
> In this case, you can see that if you say "git log HEAD~..HEAD", which
> would only contain one commit (presumably, what you want).
>
> Arcanist can always tell you exactly what it will do, in a detailed
> way, before doing it. Instead of running 'arc diff', run 'arc which'
>
> $ arc which HEAD~
>
> That will tell you exactly what arcanist will do, in a detailed
> manner. E.g. it will tell you if it will create a new diff, or update
> an old one, and exactly the commits it will use to create or update
> that diff. You can use further flags/arguments to 'arc diff' or 'arc
> which' to override the behavior as you want.
>
> > Thanks for any help!
> >
> > -- Conal
> >
> > ___
> > ghc-devs mailing list
> > ghc-devs@haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> >
>
> --
> Regards,
>
> Austin Seipp, Haskell Consultant
> Well-Typed LLP, http://www.well-typed.com/
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Trouble with first GHC patch submission: uncommitted changes

2016-04-06 Thread Conal Elliott
I'm trying to get through my first GHC patch submission, using git and
Phabricator, following directions at
https://ghc.haskell.org/trac/ghc/wiki/Phabricator. "git status" shows two
unstaged changes: "deleted:test   spaces" and "modified:
../libraries/bytestring (modified content)" (in a submodule). I don't know
where either change came from. When I use "arc diff" to submit my intended
change to the compiler, I get asked about these to uncommitted changes. I
say to ignore the submodule change and do not amend my commit with the
"test   spaces" deletion, I get "Usage Exception: You can not continue with
uncommitted changes. Commit or discard them before proceeding." I don't
know how to discard (nor whether safe), and I don't think I want to commit.

Note: the directions say to use "arc diff~" (rather than "arc diff"), to
which arc replied "(Assuming 'diff~' is the British spelling of 'diff'.)".

Thanks for any help!

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: "opt_univ fell into a hole"

2016-04-06 Thread Conal Elliott
Thanks! Will do.

On Tue, Apr 5, 2016 at 12:55 AM, Richard Eisenberg 
wrote:

> No -- that's the one you want. Either wrap your EvBinds in some structure
> that you can zonk, or submit a patch exporting zonkEvBinds. :)
>
> Richard
>
> On Apr 4, 2016, at 11:56 PM, Conal Elliott  wrote:
>
> Thanks, Richard!  Unfortunately, zonkEvBinds is not exported from TcHsSyn.
> Do you think there's another route to zonking that could work for my
> circumstances?  - Conal
>
>
> On Mon, Apr 4, 2016 at 2:00 PM, Richard Eisenberg 
> wrote:
>
>> Can't say anything about the setup to use unsafePerformIO, but I can say
>> that, yes, you need a zonk.
>>
>> You may wish to read Note [What is zonking?] in TcMType. Running your
>> bnds through a zonkEvBinds (using an emptyZonkEnv) should help.
>>
>> Also, use TcMType.newWanted to make your CtWanted. As it stands, if
>> predTy is an equality constraint, your CtWanted will be ill-formed, as all
>> equality constraints should have HoleDests, not EvVarDests. Using
>> TcMType.newWanted will simplify and improve your code.
>>
>> I hope this helps,
>> Richard
>>
>> On Apr 4, 2016, at 7:16 PM, Conal Elliott  wrote:
>>
>> Hi Richard. Thanks for the tips. I haven't learned about zonking, so it
>> may well be what I'm missing here. I'm using some inherited code that
>> includes the following line to get bindings then used with dsEvBinds and
>> mkCoreLets to build an expression:
>>
>> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
>> wCs)
>>
>> Should I be zonking in here somewhere?
>>
>> More context for this code, if helpful:
>>
>> > -- | Build a dictionary for the given
>> > buildDictionary' :: HscEnv -> DynFlags -> ModGuts -> Id -> (Id,
>> [CoreBind])
>> > buildDictionary' env dflags guts evar =
>> > let (i, bs) = runTcMUnsafe env dflags guts $ do
>> > loc <- getCtLocM (GivenOrigin UnkSkol) Nothing
>> > let predTy = varType evar
>> > nonC = mkNonCanonical $
>> >  CtWanted { ctev_pred = predTy, ctev_dest =
>> EvVarDest evar
>> >   , ctev_loc = loc }
>> > wCs = mkSimpleWC [cc_ev nonC]
>> > -- TODO: Make sure solveWanteds is the right function to call.
>> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
>> wCs)
>> > -- pprTrace "buildDictionary' _wCs'" (ppr _wCs') (return ())
>> > warnAllUnsolved _wCs'
>> > return (evar, bnds)
>> > in
>> >   (i, runDsMUnsafe env dflags guts (dsEvBinds bs))
>>
>> where runTcMUnsafe and runDsMUnsafe use unsafePerformIO (ouch) to
>>
>> > runTcMUnsafe :: HscEnv -> DynFlags -> ModGuts -> TcM a -> a
>> > runTcMUnsafe env dflags guts m = unsafePerformIO $ do
>> > -- What is the effect of HsSrcFile (should we be using something
>> else?)
>> > -- What should the boolean flag be set to?
>> > (msgs, mr) <- initTcFromModGuts env guts HsSrcFile False m
>> > let showMsgs (warns, errs) = showSDoc dflags $ vcat
>> >  $text "Errors:" :
>> pprErrMsgBagWithLoc errs
>> >++ text "Warnings:"
>> : pprErrMsgBagWithLoc warns
>> > maybe (fail $ showMsgs msgs) return mr
>> >
>> > -- TODO: Try initTcForLookup or initTcInteractive in place of
>> initTcFromModGuts.
>> > -- If successful, drop dflags and guts arguments.
>> >
>> > runDsMUnsafe :: HscEnv -> DynFlags -> ModGuts -> DsM a -> a
>> > runDsMUnsafe env dflags guts = runTcMUnsafe env dflags guts . initDsTc
>>
>> and initTcFromModGuts is something I pulled in from HERMIT.
>>
>> Thanks and regards, - Conal
>>
>> On Mon, Apr 4, 2016 at 9:37 AM, Richard Eisenberg 
>> wrote:
>>
>>> Coercion holes (the payload of a HoleProv) get created for all wanted
>>> equality constraints (and for nothing else). If you're working over only
>>> class dictionaries, you won't encounter holes. But my guess is that your
>>> HasRep somehow induces a wanted equality. If the solver fills the hole --
>>> as it should if the equality is solvable -- then you may just need to zonk
>>> it properly. zonkCoHole does the job, but this should 

Re: "opt_univ fell into a hole"

2016-04-04 Thread Conal Elliott
Thanks, Richard!  Unfortunately, zonkEvBinds is not exported from TcHsSyn.
Do you think there's another route to zonking that could work for my
circumstances?  - Conal


On Mon, Apr 4, 2016 at 2:00 PM, Richard Eisenberg  wrote:

> Can't say anything about the setup to use unsafePerformIO, but I can say
> that, yes, you need a zonk.
>
> You may wish to read Note [What is zonking?] in TcMType. Running your bnds
> through a zonkEvBinds (using an emptyZonkEnv) should help.
>
> Also, use TcMType.newWanted to make your CtWanted. As it stands, if predTy
> is an equality constraint, your CtWanted will be ill-formed, as all
> equality constraints should have HoleDests, not EvVarDests. Using
> TcMType.newWanted will simplify and improve your code.
>
> I hope this helps,
> Richard
>
> On Apr 4, 2016, at 7:16 PM, Conal Elliott  wrote:
>
> Hi Richard. Thanks for the tips. I haven't learned about zonking, so it
> may well be what I'm missing here. I'm using some inherited code that
> includes the following line to get bindings then used with dsEvBinds and
> mkCoreLets to build an expression:
>
> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
> wCs)
>
> Should I be zonking in here somewhere?
>
> More context for this code, if helpful:
>
> > -- | Build a dictionary for the given
> > buildDictionary' :: HscEnv -> DynFlags -> ModGuts -> Id -> (Id,
> [CoreBind])
> > buildDictionary' env dflags guts evar =
> > let (i, bs) = runTcMUnsafe env dflags guts $ do
> > loc <- getCtLocM (GivenOrigin UnkSkol) Nothing
> > let predTy = varType evar
> > nonC = mkNonCanonical $
> >  CtWanted { ctev_pred = predTy, ctev_dest =
> EvVarDest evar
> >   , ctev_loc = loc }
> > wCs = mkSimpleWC [cc_ev nonC]
> > -- TODO: Make sure solveWanteds is the right function to call.
> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
> wCs)
> > -- pprTrace "buildDictionary' _wCs'" (ppr _wCs') (return ())
> > warnAllUnsolved _wCs'
> > return (evar, bnds)
> > in
> >   (i, runDsMUnsafe env dflags guts (dsEvBinds bs))
>
> where runTcMUnsafe and runDsMUnsafe use unsafePerformIO (ouch) to
>
> > runTcMUnsafe :: HscEnv -> DynFlags -> ModGuts -> TcM a -> a
> > runTcMUnsafe env dflags guts m = unsafePerformIO $ do
> > -- What is the effect of HsSrcFile (should we be using something
> else?)
> > -- What should the boolean flag be set to?
> > (msgs, mr) <- initTcFromModGuts env guts HsSrcFile False m
> > let showMsgs (warns, errs) = showSDoc dflags $ vcat
> >  $text "Errors:" :
> pprErrMsgBagWithLoc errs
> >++ text "Warnings:" :
> pprErrMsgBagWithLoc warns
> > maybe (fail $ showMsgs msgs) return mr
> >
> > -- TODO: Try initTcForLookup or initTcInteractive in place of
> initTcFromModGuts.
> > -- If successful, drop dflags and guts arguments.
> >
> > runDsMUnsafe :: HscEnv -> DynFlags -> ModGuts -> DsM a -> a
> > runDsMUnsafe env dflags guts = runTcMUnsafe env dflags guts . initDsTc
>
> and initTcFromModGuts is something I pulled in from HERMIT.
>
> Thanks and regards, - Conal
>
> On Mon, Apr 4, 2016 at 9:37 AM, Richard Eisenberg 
> wrote:
>
>> Coercion holes (the payload of a HoleProv) get created for all wanted
>> equality constraints (and for nothing else). If you're working over only
>> class dictionaries, you won't encounter holes. But my guess is that your
>> HasRep somehow induces a wanted equality. If the solver fills the hole --
>> as it should if the equality is solvable -- then you may just need to zonk
>> it properly. zonkCoHole does the job, but this should be called from
>> zonkTcTypeToType, which I imagine you're already doing.
>>
>> I hope this helps,
>> Richard
>>
>> On Apr 4, 2016, at 6:21 PM, Conal Elliott  wrote:
>>
>> Hi Simon. Thanks for the reply. My plugin appears to produce the HoleProv
>> indirectly (and to my surprise) while building a dictionary to satisfy a
>> given constraint, using mkNonCanonical and solveWanteds. I don't know why
>> solveWanteds produces a HoleProv in this case and not in the many others
>> I've tried. The constraint being solved in the example I included was
>> 'HasRep (Vec ('S n_aCj7) (Key h_

Re: "opt_univ fell into a hole"

2016-04-04 Thread Conal Elliott
Oops. Just noticed an unfinished sentence. Meant to say "... where
runTcMUnsafe and runDsMUnsafe use unsafePerformIO (ouch) to construct
dictionary expressions in a 'built-in' rewrite rule". Of course, I'd love
to find a way not to need the unsafePerformIO.

On Mon, Apr 4, 2016 at 10:16 AM, Conal Elliott  wrote:

> Hi Richard. Thanks for the tips. I haven't learned about zonking, so it
> may well be what I'm missing here. I'm using some inherited code that
> includes the following line to get bindings then used with dsEvBinds and
> mkCoreLets to build an expression:
>
> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
> wCs)
>
> Should I be zonking in here somewhere?
>
> More context for this code, if helpful:
>
> > -- | Build a dictionary for the given
> > buildDictionary' :: HscEnv -> DynFlags -> ModGuts -> Id -> (Id,
> [CoreBind])
> > buildDictionary' env dflags guts evar =
> > let (i, bs) = runTcMUnsafe env dflags guts $ do
> > loc <- getCtLocM (GivenOrigin UnkSkol) Nothing
> > let predTy = varType evar
> > nonC = mkNonCanonical $
> >  CtWanted { ctev_pred = predTy, ctev_dest =
> EvVarDest evar
> >   , ctev_loc = loc }
> > wCs = mkSimpleWC [cc_ev nonC]
> > -- TODO: Make sure solveWanteds is the right function to call.
> > (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
> wCs)
> > -- pprTrace "buildDictionary' _wCs'" (ppr _wCs') (return ())
> > warnAllUnsolved _wCs'
> > return (evar, bnds)
> > in
> >   (i, runDsMUnsafe env dflags guts (dsEvBinds bs))
>
> where runTcMUnsafe and runDsMUnsafe use unsafePerformIO (ouch) to
>
> > runTcMUnsafe :: HscEnv -> DynFlags -> ModGuts -> TcM a -> a
> > runTcMUnsafe env dflags guts m = unsafePerformIO $ do
> > -- What is the effect of HsSrcFile (should we be using something
> else?)
> > -- What should the boolean flag be set to?
> > (msgs, mr) <- initTcFromModGuts env guts HsSrcFile False m
> > let showMsgs (warns, errs) = showSDoc dflags $ vcat
> >  $text "Errors:" :
> pprErrMsgBagWithLoc errs
> >++ text "Warnings:" :
> pprErrMsgBagWithLoc warns
> > maybe (fail $ showMsgs msgs) return mr
> >
> > -- TODO: Try initTcForLookup or initTcInteractive in place of
> initTcFromModGuts.
> > -- If successful, drop dflags and guts arguments.
> >
> > runDsMUnsafe :: HscEnv -> DynFlags -> ModGuts -> DsM a -> a
> > runDsMUnsafe env dflags guts = runTcMUnsafe env dflags guts . initDsTc
>
> and initTcFromModGuts is something I pulled in from HERMIT.
>
> Thanks and regards, - Conal
>
> On Mon, Apr 4, 2016 at 9:37 AM, Richard Eisenberg 
> wrote:
>
>> Coercion holes (the payload of a HoleProv) get created for all wanted
>> equality constraints (and for nothing else). If you're working over only
>> class dictionaries, you won't encounter holes. But my guess is that your
>> HasRep somehow induces a wanted equality. If the solver fills the hole --
>> as it should if the equality is solvable -- then you may just need to zonk
>> it properly. zonkCoHole does the job, but this should be called from
>> zonkTcTypeToType, which I imagine you're already doing.
>>
>> I hope this helps,
>> Richard
>>
>> On Apr 4, 2016, at 6:21 PM, Conal Elliott  wrote:
>>
>> Hi Simon. Thanks for the reply. My plugin appears to produce the HoleProv
>> indirectly (and to my surprise) while building a dictionary to satisfy a
>> given constraint, using mkNonCanonical and solveWanteds. I don't know why
>> solveWanteds produces a HoleProv in this case and not in the many others
>> I've tried. The constraint being solved in the example I included was
>> 'HasRep (Vec ('S n_aCj7) (Key h_aCj6))', where HasRep is similar to Generic
>> (from GHC.Generics), and there is a HasRep instance for Vec ('S n x). Come
>> to think of it, the free type variable s_aD1S troubles me as well.
>>
>> I'm not terribly confident in the code I use for constructing these
>> dictionaries (setting up and calling solveWanteds) during Core-to-Core
>> transformation. Do you know of any relevant example code, docs, etc?
>>
>> Yes, I'm using -dcore-lint, as well explicitly linting each sm

Re: "opt_univ fell into a hole"

2016-04-04 Thread Conal Elliott
Hi Richard. Thanks for the tips. I haven't learned about zonking, so it may
well be what I'm missing here. I'm using some inherited code that includes
the following line to get bindings then used with dsEvBinds and mkCoreLets
to build an expression:

> (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
wCs)

Should I be zonking in here somewhere?

More context for this code, if helpful:

> -- | Build a dictionary for the given
> buildDictionary' :: HscEnv -> DynFlags -> ModGuts -> Id -> (Id,
[CoreBind])
> buildDictionary' env dflags guts evar =
> let (i, bs) = runTcMUnsafe env dflags guts $ do
> loc <- getCtLocM (GivenOrigin UnkSkol) Nothing
> let predTy = varType evar
> nonC = mkNonCanonical $
>  CtWanted { ctev_pred = predTy, ctev_dest = EvVarDest
evar
>   , ctev_loc = loc }
> wCs = mkSimpleWC [cc_ev nonC]
> -- TODO: Make sure solveWanteds is the right function to call.
> (_wCs', bnds) <- second evBindMapBinds <$> runTcS (solveWanteds
wCs)
> -- pprTrace "buildDictionary' _wCs'" (ppr _wCs') (return ())
> warnAllUnsolved _wCs'
> return (evar, bnds)
> in
>   (i, runDsMUnsafe env dflags guts (dsEvBinds bs))

where runTcMUnsafe and runDsMUnsafe use unsafePerformIO (ouch) to

> runTcMUnsafe :: HscEnv -> DynFlags -> ModGuts -> TcM a -> a
> runTcMUnsafe env dflags guts m = unsafePerformIO $ do
> -- What is the effect of HsSrcFile (should we be using something
else?)
> -- What should the boolean flag be set to?
> (msgs, mr) <- initTcFromModGuts env guts HsSrcFile False m
> let showMsgs (warns, errs) = showSDoc dflags $ vcat
>  $text "Errors:" :
pprErrMsgBagWithLoc errs
>++ text "Warnings:" :
pprErrMsgBagWithLoc warns
> maybe (fail $ showMsgs msgs) return mr
>
> -- TODO: Try initTcForLookup or initTcInteractive in place of
initTcFromModGuts.
> -- If successful, drop dflags and guts arguments.
>
> runDsMUnsafe :: HscEnv -> DynFlags -> ModGuts -> DsM a -> a
> runDsMUnsafe env dflags guts = runTcMUnsafe env dflags guts . initDsTc

and initTcFromModGuts is something I pulled in from HERMIT.

Thanks and regards, - Conal

On Mon, Apr 4, 2016 at 9:37 AM, Richard Eisenberg  wrote:

> Coercion holes (the payload of a HoleProv) get created for all wanted
> equality constraints (and for nothing else). If you're working over only
> class dictionaries, you won't encounter holes. But my guess is that your
> HasRep somehow induces a wanted equality. If the solver fills the hole --
> as it should if the equality is solvable -- then you may just need to zonk
> it properly. zonkCoHole does the job, but this should be called from
> zonkTcTypeToType, which I imagine you're already doing.
>
> I hope this helps,
> Richard
>
> On Apr 4, 2016, at 6:21 PM, Conal Elliott  wrote:
>
> Hi Simon. Thanks for the reply. My plugin appears to produce the HoleProv
> indirectly (and to my surprise) while building a dictionary to satisfy a
> given constraint, using mkNonCanonical and solveWanteds. I don't know why
> solveWanteds produces a HoleProv in this case and not in the many others
> I've tried. The constraint being solved in the example I included was
> 'HasRep (Vec ('S n_aCj7) (Key h_aCj6))', where HasRep is similar to Generic
> (from GHC.Generics), and there is a HasRep instance for Vec ('S n x). Come
> to think of it, the free type variable s_aD1S troubles me as well.
>
> I'm not terribly confident in the code I use for constructing these
> dictionaries (setting up and calling solveWanteds) during Core-to-Core
> transformation. Do you know of any relevant example code, docs, etc?
>
> Yes, I'm using -dcore-lint, as well explicitly linting each small
> transformation step (while debugging). Doing so has been very helpful in
> finding bugs quickly.
>
> Cheers, - Conal
>
> On Mon, Apr 4, 2016 at 2:48 AM, Simon Peyton Jones 
> wrote:
>
>> Definitely a bug. All HoleProvs should be eliminated by the type checker.
>>
>>
>>
>> Did your plugin produce a HoleProv?  It definitely should not do so; see
>> the notes with that constructor.
>>
>>
>>
>> Lint checks for this – did you run with –dcore-lint?
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
>> Elliott
>> *Sent:* 02 April 2016 20:24
&g

Re: "opt_univ fell into a hole"

2016-04-04 Thread Conal Elliott
Hi Simon. Thanks for the reply. My plugin appears to produce the HoleProv
indirectly (and to my surprise) while building a dictionary to satisfy a
given constraint, using mkNonCanonical and solveWanteds. I don't know why
solveWanteds produces a HoleProv in this case and not in the many others
I've tried. The constraint being solved in the example I included was
'HasRep (Vec ('S n_aCj7) (Key h_aCj6))', where HasRep is similar to Generic
(from GHC.Generics), and there is a HasRep instance for Vec ('S n x). Come
to think of it, the free type variable s_aD1S troubles me as well.

I'm not terribly confident in the code I use for constructing these
dictionaries (setting up and calling solveWanteds) during Core-to-Core
transformation. Do you know of any relevant example code, docs, etc?

Yes, I'm using -dcore-lint, as well explicitly linting each small
transformation step (while debugging). Doing so has been very helpful in
finding bugs quickly.

Cheers, - Conal

On Mon, Apr 4, 2016 at 2:48 AM, Simon Peyton Jones 
wrote:

> Definitely a bug. All HoleProvs should be eliminated by the type checker.
>
>
>
> Did your plugin produce a HoleProv?  It definitely should not do so; see
> the notes with that constructor.
>
>
>
> Lint checks for this – did you run with –dcore-lint?
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 02 April 2016 20:24
> *To:* ghc-devs@haskell.org
> *Subject:* "opt_univ fell into a hole"
>
>
>
> I'm getting the following error message from a GHC plugin I'm developing
> (note GHC version):
>
> ghc-stage2: panic! (the 'impossible' happened)
>   (GHC version 8.1.20160307 for x86_64-apple-darwin):
> opt_univ fell into a hole {aD1S}
>
> I don't get this error when compiling without my plugin, so I may well be
> violating a compiler invariant.
>
> Shortly before the error, the plugin produced the following dictionary
> expression, which does indeed contain a `UnivCo` with a `HoleProv`. The
> plugin does sometimes generate `UnivCo`s but not with `HoleProv`.
>
> let {
>   $dHasRep_aD1T :: HasRep (Vec 'Z s_aD1R[fuv:0])
>   $dHasRep_aD1T = $fHasRepVec0 @ s_aD1R[fuv:0] } in
> let {
>   $dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR :: HasRep (Vec 'Z (Key h_aCnh))
>   $dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR =
> $dHasRep_aD1T
> `cast` ((HasRep
>(Vec
>   <'Z>_N
>   (Sym U(hole:{aD1S}, Key h_aCnh,
> s_aD1R[fuv:0])_N))_N)_R
> :: HasRep (Vec 'Z s_aD1R[fuv:0])
>~R# HasRep (Vec 'Z (Key h_aCnh))) } in
> $dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR
>
> Here, `Key` is a type family from `Data.Key` in the keys package, and
> `Vec` is a GADT of statically length-indexed lists.
>
> Suggestions?
>
> Thanks, - Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


"opt_univ fell into a hole"

2016-04-02 Thread Conal Elliott
I'm getting the following error message from a GHC plugin I'm developing
(note GHC version):

ghc-stage2: panic! (the 'impossible' happened)
  (GHC version 8.1.20160307 for x86_64-apple-darwin):
opt_univ fell into a hole {aD1S}

I don't get this error when compiling without my plugin, so I may well be
violating a compiler invariant.

Shortly before the error, the plugin produced the following dictionary
expression, which does indeed contain a `UnivCo` with a `HoleProv`. The
plugin does sometimes generate `UnivCo`s but not with `HoleProv`.

let {
  $dHasRep_aD1T :: HasRep (Vec 'Z s_aD1R[fuv:0])
  $dHasRep_aD1T = $fHasRepVec0 @ s_aD1R[fuv:0] } in
let {
  $dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR :: HasRep (Vec 'Z (Key h_aCnh))
  $dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR =
$dHasRep_aD1T
`cast` ((HasRep
   (Vec
  <'Z>_N
  (Sym U(hole:{aD1S}, Key h_aCnh,
s_aD1R[fuv:0])_N))_N)_R
:: HasRep (Vec 'Z s_aD1R[fuv:0])
   ~R# HasRep (Vec 'Z (Key h_aCnh))) } in
$dHasRepZLVeczqZZZLKeyhZRZR_Ii5CR

Here, `Key` is a type family from `Data.Key` in the keys package, and `Vec`
is a GADT of statically length-indexed lists.

Suggestions?

Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: GHC HEAD compile failure at ghctags: "missing: Cabal >=1.25 && <1.27"

2016-03-30 Thread Conal Elliott
Oh, yeah. Thanks!  - Conal

On Wed, Mar 30, 2016 at 10:54 AM, Edward Z. Yang  wrote:

> Don't forget to "git submodule update"
>
> Edward
>
> Excerpts from Conal Elliott's message of 2016-03-30 10:02:20 -0700:
> > I'm trying to recompile GHC (via GHC 7.10.3) from freshly git-pulled
> HEAD,
> > and "make" keeps dying at ghctags:
> >
> > Configuring ghctags-0.1...
> > ghc-cabal: At least the following dependencies are missing:
> > Cabal >=1.25 && <1.27
> >
> > According to ghc-pkg I have Cabal 1.25.0.0 (compiled from a freshly
> > git-pulled git clone).
> >
> > Any ideas what's going on and how I can fix it?
> >
> > Thanks.  - Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


GHC HEAD compile failure at ghctags: "missing: Cabal >=1.25 && <1.27"

2016-03-30 Thread Conal Elliott
I'm trying to recompile GHC (via GHC 7.10.3) from freshly git-pulled HEAD,
and "make" keeps dying at ghctags:

Configuring ghctags-0.1...
ghc-cabal: At least the following dependencies are missing:
Cabal >=1.25 && <1.27

According to ghc-pkg I have Cabal 1.25.0.0 (compiled from a freshly
git-pulled git clone).

Any ideas what's going on and how I can fix it?

Thanks.  - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: lookupRdrNameInModuleForPlugins with constructors

2016-03-23 Thread Conal Elliott
Indeed, tyConDataCons does the trick. I don't know how to start with the
Class (given a name string), but I'm able to use 'mkClsOcc . Unqual' with
lookupRdrNameInModuleForPlugins and then lookupTyCon on the resulting name,
followed by 'head . tyConDataCons' to get the constructor.

Thanks, Simon!

-- Conal

On Wed, Mar 23, 2016 at 1:32 AM, Simon Peyton Jones 
wrote:

> Start with the Class.  Use classTyCon to get the TyCon.  Use tyConDataCons
> to get the data constructor.
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 23 March 2016 00:09
> *To:* ghc-devs@haskell.org
> *Subject:* lookupRdrNameInModuleForPlugins with constructors
>
>
>
> I'm trying to construct a dictionary in a GHC plugin. I'm stuck on finding
> the constructor for the dictionary. When I use `-ddump-simpl` on the module
> that defines the class, I see "Circat.Rep.C:HasRep". To try finding that
> constructor, I say
>
> > lookupRdrNameInModuleForPlugins hsc_env
> >   (mkModuleName "Circat.Rep") (mkVarUnqual "C:HasRep")
>
> However, I keep getting `Nothing` as a result. (Same without the "C:".)
> I've also had this same difficulty when looking up constructors for
> algebraic data types and when looking up TyCons. For regular value Ids,
> lookup succeeds.
>
> What am I missing?
>
> Thanks, - Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: lookupRdrNameInModuleForPlugins with constructors

2016-03-22 Thread Conal Elliott
I'm now able to look up value identifiers, type constructors (including
classes), and regular data constructors, but not dictionary constructors.
Here's my failing effort to look up a dictionary constructor (in CoreM):

hasRepThing <-
  maybe (panic "HasRep lookup failure") lookupThing =<<
(liftIO $
  lookupRdrNameInModuleForPlugins hsc_env (mkModuleName
"Circat.Rep")
 (Unqual (mkDataOcc "C:HasRep")))
pprTrace "mkReifyEnv HasRep thing:" (ppr hasRepThing) (return ())

Result:

ghc-stage2: panic! (the 'impossible' happened)
  (GHC version 8.1.20160307 for x86_64-apple-darwin):
HasRep lookup failure

Same failure when I use the name string "HasRep" in place of "C:HasRep".

Any idea what I'm doing wrong here?

-- Conal

On Tue, Mar 22, 2016 at 5:40 PM, Conal Elliott  wrote:

> Got it. Silly me. Thanks!!  - Conal
>
> On Tue, Mar 22, 2016 at 5:25 PM, Andrew Farmer 
> wrote:
>
>> Er, dictionary... sorry, mkDataOccFS
>>
>> On Tue, Mar 22, 2016 at 5:24 PM, Andrew Farmer 
>> wrote:
>> > mkVarUnqual calls mkVarOccFS, which constructs an OccName in the
>> > varName namespace. You need to construct your RdrName via mkTyVarOcc,
>> > which picks the Type/Class namespace.
>> >
>> > On Tue, Mar 22, 2016 at 5:09 PM, Conal Elliott  wrote:
>> >> I'm trying to construct a dictionary in a GHC plugin. I'm stuck on
>> finding
>> >> the constructor for the dictionary. When I use `-ddump-simpl` on the
>> module
>> >> that defines the class, I see "Circat.Rep.C:HasRep". To try finding
>> that
>> >> constructor, I say
>> >>
>> >>> lookupRdrNameInModuleForPlugins hsc_env
>> >>>   (mkModuleName "Circat.Rep") (mkVarUnqual "C:HasRep")
>> >>
>> >> However, I keep getting `Nothing` as a result. (Same without the
>> "C:".) I've
>> >> also had this same difficulty when looking up constructors for
>> algebraic
>> >> data types and when looking up TyCons. For regular value Ids, lookup
>> >> succeeds.
>> >>
>> >> What am I missing?
>> >>
>> >> Thanks, - Conal
>> >>
>> >> ___
>> >> ghc-devs mailing list
>> >> ghc-devs@haskell.org
>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>> >>
>>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: lookupRdrNameInModuleForPlugins with constructors

2016-03-22 Thread Conal Elliott
Got it. Silly me. Thanks!!  - Conal

On Tue, Mar 22, 2016 at 5:25 PM, Andrew Farmer  wrote:

> Er, dictionary... sorry, mkDataOccFS
>
> On Tue, Mar 22, 2016 at 5:24 PM, Andrew Farmer 
> wrote:
> > mkVarUnqual calls mkVarOccFS, which constructs an OccName in the
> > varName namespace. You need to construct your RdrName via mkTyVarOcc,
> > which picks the Type/Class namespace.
> >
> > On Tue, Mar 22, 2016 at 5:09 PM, Conal Elliott  wrote:
> >> I'm trying to construct a dictionary in a GHC plugin. I'm stuck on
> finding
> >> the constructor for the dictionary. When I use `-ddump-simpl` on the
> module
> >> that defines the class, I see "Circat.Rep.C:HasRep". To try finding that
> >> constructor, I say
> >>
> >>> lookupRdrNameInModuleForPlugins hsc_env
> >>>   (mkModuleName "Circat.Rep") (mkVarUnqual "C:HasRep")
> >>
> >> However, I keep getting `Nothing` as a result. (Same without the "C:".)
> I've
> >> also had this same difficulty when looking up constructors for algebraic
> >> data types and when looking up TyCons. For regular value Ids, lookup
> >> succeeds.
> >>
> >> What am I missing?
> >>
> >> Thanks, - Conal
> >>
> >> ___
> >> ghc-devs mailing list
> >> ghc-devs@haskell.org
> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> >>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


lookupRdrNameInModuleForPlugins with constructors

2016-03-22 Thread Conal Elliott
I'm trying to construct a dictionary in a GHC plugin. I'm stuck on finding
the constructor for the dictionary. When I use `-ddump-simpl` on the module
that defines the class, I see "Circat.Rep.C:HasRep". To try finding that
constructor, I say

> lookupRdrNameInModuleForPlugins hsc_env
>   (mkModuleName "Circat.Rep") (mkVarUnqual "C:HasRep")

However, I keep getting `Nothing` as a result. (Same without the "C:".)
I've also had this same difficulty when looking up constructors for
algebraic data types and when looking up TyCons. For regular value Ids,
lookup succeeds.

What am I missing?

Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Disappearing case alternative?

2016-03-12 Thread Conal Elliott
I think you put your finger on the problem here. That `evalP` is a
placeholder to get transformed away later. I thought that my `NOINLINE`
annotation would prevent GHC from noticing that `evalP` evaluates to
bottom. I'll do a better job.

Thank you!

-- Conal


On Fri, Mar 11, 2016 at 4:06 PM, Ömer Sinan Ağacan 
wrote:

> Empty case expressions like `case evalP @ (Pair Int) ds of wild { }` are
> only
> valid if the scrutinee is bottom, see CoreLint.hs for how exprIsBottom is
> used
> and CoreUtils.hs for how it's defined. So it seems like the simplifier
> somehow
> figured that `evalP @ (Pair Int) ds` is bottom, and generated an empty
> case.
>
> Is the linter complaining about this case expression? (you can try it using
> CoreLint.lintExpr)
>
> 2016-03-11 16:49 GMT-05:00 Conal Elliott :
> >
> > I'm working on a GHC plugin, mainly in the form of a "builtin" rewrite
> rule,
> > and I'm seeing a strange disappearance of a case alternative. With
> > -ddump-rule-rewrites, I can see before & after the disappearance: Here's
> one
> > rule firing with the alternative present:
> >
> > Rule fired
> > Rule: reify
> > Before: reifyP
> >   TyArg Pair Int -> Int
> >   ValArg \ (ds :: Pair Int) ->
> >case ds of _ { :# a b -> $fNumInt_$c+ a b }
> > After:  lamP
> >   @ (Pair Int)
> >   @ Int
> >   "ds"#
> >   (\ (ds :: EP (Pair Int)) ->
> >  reifyP
> >@ Int
> >(case evalP @ (Pair Int) ds of _ { :# a b ->
> > $fNumInt_$c+ a b }))
> > Cont:   StrictArg toE
> > Stop[BoringCtxt] E Prim (Pair Int -> Int)
> >
> > The next thing I see is the rule firing again on the residual reifyP
> > application, but with the case alternative gone:
> >
> > Rule fired
> > Rule: reify
> > Before: reifyP
> >   TyArg Int ValArg case evalP @ (Pair Int) ds of wild { }
> > After:  ...
> >
> > Any ideas what's causing the disappearance?
> >
> > Thanks.  - Conal
> >
> >
> > ___
> > ghc-devs mailing list
> > ghc-devs@haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> >
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Disappearing case alternative?

2016-03-11 Thread Conal Elliott
I'm working on a GHC plugin, mainly in the form of a "builtin" rewrite
rule, and I'm seeing a strange disappearance of a case alternative. With
-ddump-rule-rewrites, I can see before & after the disappearance: Here's
one rule firing with the alternative present:

Rule fired
Rule: reify
Before: reifyP
  TyArg Pair Int -> Int
  ValArg \ (ds :: Pair Int) ->
   case ds of _ { :# a b -> $fNumInt_$c+ a b }
After:  lamP
  @ (Pair Int)
  @ Int
  "ds"#
  (\ (ds :: EP (Pair Int)) ->
 reifyP
   @ Int
   (case evalP @ (Pair Int) ds of _ { :# a b ->
$fNumInt_$c+ a b }))
Cont:   StrictArg toE
Stop[BoringCtxt] E Prim (Pair Int -> Int)

The next thing I see is the rule firing again on the residual reifyP
application, but with the case alternative gone:

Rule fired
Rule: reify
Before: reifyP
  TyArg Int ValArg case evalP @ (Pair Int) ds of wild { }
After:  ...

Any ideas what's causing the disappearance?

Thanks.  - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: "token is not a valid binary operator in a preprocessor subexpression" in GHC HEAD build

2016-03-07 Thread Conal Elliott
I installed a newer Xcode, and now GHC HEAD is building fine for me.  -
Conal

On Sun, Mar 6, 2016 at 1:46 PM, Conal Elliott  wrote:

> I'm trying to build GHC HEAD on Mac OS after a fresh git-pull, and I'm
> getting the following:
>
> libraries/binary/src/Data/Binary/Put.hs:38:27:
>  error: token is not a valid binary operator in a preprocessor
> subexpression
> #if MIN_VERSION_bytestring(0,10,4)
>
> Any insights/suggestions?
>
> I don't need the very latest HEAD version; just a version with ticket
> 11651 fixed (https://ghc.haskell.org/trac/ghc/ticket/11651#comment:3),
> and even for that item, I don't mind patching the source myself.
>
> Thanks!  - Conal
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


"token is not a valid binary operator in a preprocessor subexpression" in GHC HEAD build

2016-03-06 Thread Conal Elliott
I'm trying to build GHC HEAD on Mac OS after a fresh git-pull, and I'm
getting the following:

libraries/binary/src/Data/Binary/Put.hs:38:27:
 error: token is not a valid binary operator in a preprocessor
subexpression
#if MIN_VERSION_bytestring(0,10,4)

Any insights/suggestions?

I don't need the very latest HEAD version; just a version with ticket 11651
fixed (https://ghc.haskell.org/trac/ghc/ticket/11651#comment:3), and even
for that item, I don't mind patching the source myself.

Thanks!  - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Adding rules in a plugin?

2016-02-10 Thread Conal Elliott
More study of GHC source code answered my question: when I generate a rule,
set ru_auto to False rather than True, so that findExternalRules won't
delete the rule.

On Tue, Feb 9, 2016 at 6:47 PM, Conal Elliott  wrote:

> I'm writing a GHC plugin that generates new rules. The top-level
> identifier for the new rules' LHSs is always the same and is imported from
> another module. One of the arguments in the rule's LHSs, however, is
> defined in that module. I'm creating rules and adding them to the mg_rules
> of the module's ModGuts. I don't see them in the .hi files (viewed with
> "ghc --show-iface Foo.hi"), and they're not getting found in modules that
> import the modules where I'm trying to generate rules. Am I missing a
> crucial step? For instance, do I need also to use `addIdSpecialisations`
> with the argument identifiers, and if so, need I replace all instances of
> those identifiers in the module or just some of them?
>
>
> Thanks, -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Adding rules in a plugin?

2016-02-09 Thread Conal Elliott
I'm writing a GHC plugin that generates new rules. The top-level identifier
for the new rules' LHSs is always the same and is imported from another
module. One of the arguments in the rule's LHSs, however, is defined in
that module. I'm creating rules and adding them to the mg_rules of the
module's ModGuts. I don't see them in the .hi files (viewed with "ghc
--show-iface Foo.hi"), and they're not getting found in modules that import
the modules where I'm trying to generate rules. Am I missing a crucial
step? For instance, do I need also to use `addIdSpecialisations` with the
argument identifiers, and if so, need I replace all instances of those
identifiers in the module or just some of them?


Thanks, -- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Specializing expressions beyond names?

2016-02-03 Thread Conal Elliott
Hi Simon.

Thanks for the reply. Below, I try to explain more clearly what I want and
why below. If it’s still murky, and if you’re up for it, a Skype chat would
probably help a lot.

I think I’m looking for something very close to GHC’s specialization as it
is now, and I’m wondering how to best leverage the specialization that GHC
already does. I have a GHC plugin that transforms Core programs into
reifying versions of themselves. The transformation is triggered by
application of a “function” reify ∷ a → E a for an expression GADT). reify
is more like a macro, in that its implementation relies on the (Core)
syntax of its argument, not just its semantics, but in a well-behaved way
(with a simple, non-syntactic specification). This reifying transformation
benefits from the dictionary elimination that GHC’s specializer performs,
and I’d like to benefit more. After specialization, or as part of it, I
want to reuse the work of reifying the specialized definition. Currently I
have to inline the code generated by the specializer, across modules (and
assuming that its code is available), and then reify it at each call site.
I’d rather have the option to reify specializations in the defining module
and then reuse those reified specializations at call-sites, even in other
modules. Thus, I don’t want to specialize a function foo at various types,
but the result of transforming reify foo for those types, hence my interest
in specializing expressions at least a bit more complicated than
identifiers. I expect that this scheme, or something like it, will let me
eliminate much inlining of code from other modules and then reifying these
large expressions. In other words, it lets me do “separate reification”
akin to separate compilation.

Perhaps I should be thinking of specializing reifications instead of
reifying specializations. I guess that alternative would mean having the
specializer perform reification (using a few CoreExpr rewrites) as part of
the work it does. Given foo ∷ T (where T may include polymorphism and
dictionaries), I might generate

reify_foo ∷ E Treify_foo = reify foo

and then transform the RHS to remove the reify call, resulting in E-building
Core code. Then request specializations for reify_foo.

The types are not quite this simple, due to polymorphism and dictionaries.
For instance, given

sum ∷ (Foldable f, Num a) ⇒ f a → a

generate

reify_sum ∷ (Foldable f, Num a) ⇒ E (f a → a)
reify_sum = reify sum

In Core,

reify_sum ∷ ∀ f a. Foldable f → Num a → E (f a → a)
reify_sum = λ (@ f) (@ a) ($dFoldable ∷ Foldable f) ($dNum ∷ Num a)
  → reify (sum @ f @ a $dFoldable $dNum)

Then ask for specializations of reify_sum. Since reification all happens
invisibly, reify_sum won’t ever get called in client code. Instead, I’d
have to also recognize calls to reify sum from other modules and replace
those calls with reify_sum.

Oh. Hm. Perhaps the specializer doesn’t have to invoke the reifier after
all. Maybe I can generate definitions like reify_sum and some SPECIALIZE
pragmas (or directly invoke the equivalent code GHC), and then reify the
results after the specializer runs.

I’ve started down a path of doing something similar:

   - Wait until the specializer has run.
   - Reify all top-level definitions I’m able to, adding new reifying
   definitions and reify rules that use those new definitions (as the
   specializer does). Here’s where I’m worried about the efficiency of having
   many rules with the same RHS top-level identifier.
   - Apply those rules in other modules during reification, pushing reify
   calls inward where they can meet up with other functions also reify
   rules from other modules.

Because I’m worried about the performance with many reify rules, maybe I’ll
drop the rules and instead export definitions like reify_sum (after
reify-transforming
the RHS), with predictable names, and then explicitly look for those names
across modules during reification. Or does GHC handle that situation well,
as long there are few uses (probably only one use) of each name that reify
is applied to in these rules (thanks to the specializer having already run,
yielding many differently named specializations).

As I mentioned, a Skype chat may be helpful.

Best regards, - Conal




On Wed, Feb 3, 2016 at 8:47 AM, Simon Peyton Jones 
wrote:

> I’m sorry Conal I’m not getting this.
>
>
>
> Specialisation happens when you have a named chunk of code that is
> repeatedly called at different types, and with different args.  We can
> inline it bodily to specialise to that one call site, but it’s cooler to
> make a single specialised version which can be shared among many call
> sites.  (And that approach deals with recursive functions too.)
>
>
>
> But that explanation is fundamentally about named functions, so I don’t
> understand this “general expression” bit.  Sorry!
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@hask

Re: Specializing expressions beyond names?

2016-01-31 Thread Conal Elliott
A related question: if there are a great many rules of the form "reify (foo
...) = ...", where 'reify' is always present (and the outermost application
head) but for many different argument expressions, will rule matching be
linear (expensive) in the number of such rules?

-- Conal

On Sun, Jan 31, 2016 at 1:58 PM, Conal Elliott  wrote:

> It seems to be the case that SPECIALIZE pragmas are syntactically
> restricted to type specializations of a *name* (identifier) rather than a
> general expression. Is my understanding correct here? If so, is there any
> reason for this restriction?
>
> I ask because I’m reifying Core code (into code that constructs a
> corresponding run-time representation for further processing), and I’m
> looking for a clean way to integrate that process with GHC, to support
> separate compilation and to avoid interfering with GHC’s regular flow. It
> occurred to me that I could enable separate compilation via a pragma of the
> form “{-# SPECIALIZE reify foo ∷ E t #-}” for some t, where E t is a
> reified form of values of type t. Type checking would infer the
> specialized type of foo, and the usual specialization phase would do its
> usual thing on that specialization, leaving “reify foo = reify
> specialized_foo”, and then the reification compiler plugin would
> transform the right-hand side, pushing the reify inward. Some reify calls
> may remain (e.g., due to polymorphism), triggering future rule
> applications. As much as possible of the fully-reified version would be
> factored out of the generated rule’s RHS for cheap reuse.
>
>
> Thanks, - Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Specializing expressions beyond names?

2016-01-31 Thread Conal Elliott
It seems to be the case that SPECIALIZE pragmas are syntactically
restricted to type specializations of a *name* (identifier) rather than a
general expression. Is my understanding correct here? If so, is there any
reason for this restriction?

I ask because I’m reifying Core code (into code that constructs a
corresponding run-time representation for further processing), and I’m
looking for a clean way to integrate that process with GHC, to support
separate compilation and to avoid interfering with GHC’s regular flow. It
occurred to me that I could enable separate compilation via a pragma of the
form “{-# SPECIALIZE reify foo ∷ E t #-}” for some t, where E t is a
reified form of values of type t. Type checking would infer the specialized
type of foo, and the usual specialization phase would do its usual thing on
that specialization, leaving “reify foo = reify specialized_foo”, and then
the reification compiler plugin would transform the right-hand side,
pushing the reify inward. Some reify calls may remain (e.g., due to
polymorphism), triggering future rule applications. As much as possible of
the fully-reified version would be factored out of the generated rule’s RHS
for cheap reuse.


Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: More aggressive dictionary removal?

2016-01-28 Thread Conal Elliott
I just split the "library code" (data types and instances) and the client
code (type-specialized use) into two modules. Same great results, as long
as both modules are compiled with -O (not even -O2). Sweet!

On Thu, Jan 28, 2016 at 10:12 AM, Conal Elliott  wrote:

> Hah! I had misread the signatures in the Core output. I'm getting exactly
> the dictionary removal I wanted. Fantastic!
>
> I'm attaching my sample source code and the Core it produces.
>
> Sorry for the misdirection, and kudos for specialis/zation in GHC!
>
> -- Conal
>
> On Thu, Jan 28, 2016 at 4:54 AM, Simon Peyton Jones  > wrote:
>
>> Aggressive inlining is one way, but specialisation ought to get a long
>> way, and makes fewer copies of the specialised code.
>>
>>
>>
>> It’s hard to help without a concrete example
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
>> Elliott
>> *Sent:* 28 January 2016 00:05
>> *To:* ghc-devs@haskell.org
>> *Subject:* More aggressive dictionary removal?
>>
>>
>>
>> I'm looking for pointers on getting GHC to eliminate more overloading &
>> polymorphism. I think this sort of thing mainly happens in the Specialise
>> module. The default GHC flag settings get me a couple levels of
>> monomorphization and dictionary removal, but I want to go further. I've
>> tried -fspecialise-aggressively, but it didn't seem to make a difference,
>> and I haven't found this flag described in the GHC user's guide. Anyone
>> have pointers to more information?
>>
>> Thanks, - Conal
>>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: More aggressive dictionary removal?

2016-01-28 Thread Conal Elliott
Hah! I had misread the signatures in the Core output. I'm getting exactly
the dictionary removal I wanted. Fantastic!

I'm attaching my sample source code and the Core it produces.

Sorry for the misdirection, and kudos for specialis/zation in GHC!

-- Conal

On Thu, Jan 28, 2016 at 4:54 AM, Simon Peyton Jones 
wrote:

> Aggressive inlining is one way, but specialisation ought to get a long
> way, and makes fewer copies of the specialised code.
>
>
>
> It’s hard to help without a concrete example
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 28 January 2016 00:05
> *To:* ghc-devs@haskell.org
> *Subject:* More aggressive dictionary removal?
>
>
>
> I'm looking for pointers on getting GHC to eliminate more overloading &
> polymorphism. I think this sort of thing mainly happens in the Specialise
> module. The default GHC flag settings get me a couple levels of
> monomorphization and dictionary removal, but I want to go further. I've
> tried -fspecialise-aggressively, but it didn't seem to make a difference,
> and I haven't found this flag described in the GHC user's guide. Anyone
> have pointers to more information?
>
> Thanks, - Conal
>


SpecT.dump-simpl
Description: Binary data
{-# LANGUAGE KindSignatures, GADTs, FlexibleInstances, FlexibleContexts, DeriveFunctor #-}
{-# OPTIONS_GHC -Wall #-}

{-# OPTIONS_GHC -O2 -ddump-simpl -ddump-to-file #-}

module Foo (foo) where

-- Type-level naturals, old-school
data Z
data S n

-- | Uniform pairs
data Pair a = a :# a deriving Functor

-- Top-down, depth-typed, perfect, binary, leaf trees
data Tree :: * -> * -> * where
  L :: a -> Tree Z a
  B :: Pair (Tree n a) -> Tree (S n) a

instance Functor (Tree Z) where
  fmap f (L a ) = L (f a)
  -- {-# INLINABLE fmap #-}

instance Functor (Tree n) => Functor (Tree (S n)) where
  fmap f (B ts) = B ((fmap.fmap) f ts)
  -- {-# INLINABLE fmap #-}

-- Specialization works (within this module at least) with or without INLINABLE.

type Unop a = a -> a

foo :: Unop (Tree (S (S (S (S (S (S (S (S (S (S (S Z))) Int)
foo = fmap (+1)

-- With this alternative instance, I get nowhere with specialization:

-- instance Functor (Tree n) where
--   fmap f (L a ) = L (f a)
--   fmap f (B ts) = B ((fmap.fmap) f ts)
--   {-# INLINABLE fmap #-}
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


More aggressive dictionary removal?

2016-01-27 Thread Conal Elliott
I'm looking for pointers on getting GHC to eliminate more overloading &
polymorphism. I think this sort of thing mainly happens in the Specialise
module. The default GHC flag settings get me a couple levels of
monomorphization and dictionary removal, but I want to go further. I've
tried -fspecialise-aggressively, but it didn't seem to make a difference,
and I haven't found this flag described in the GHC user's guide. Anyone
have pointers to more information?

Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ghci and unfoldings?

2016-01-20 Thread Conal Elliott
Thanks for the additional tips. I'm having very inconsistent results with
unfolding definitions from other modules in ghci, even with all of these
flags. I'll keep poking at it until I have some consistent info and
questions.

-- Conal

On Wed, Jan 20, 2016 at 7:46 AM, Simon Peyton Jones 
wrote:

> Ah….It seems that to get unfoldings exposed in the *module you are
> compiling* you need *both*
>
> · -fno-omit-interface-pragmas
>
> · -fexpose-all-unfoldings
>
>
>
> And GHCi and –O0 both imply –fomit-interface-pragmas.
>
>
>
> To see the unfoldings on *imported* functions  you need
> –fno-ignore-interface pragmas.
>
>
>
> Arguably –fexpose-all-unfoldings should override –fomit-interface-pragmas,
> which it doesn’t at the moment.  Open a ticket if you think that would be
> useful and important.  I can give guidance about the places.
>
>
>
> Simon
>
>
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 18 January 2016 17:47
> *To:* Simon Peyton Jones 
> *Cc:* Edward Z. Yang ; Andrew Farmer ;
> ghc-devs@haskell.org
>
> *Subject:* Re: ghci and unfoldings?
>
>
>
> That's the flag I would expect. It doesn't seem to help or hinder
> availability of unfoldings in GHCi. Do you think it should?
>
> And Happy Birthday, Simon!
>
> Warmly, - Conal
>
>
> On Monday, January 18, 2016, Simon Peyton Jones 
> wrote:
>
> Or -fexpose-all-unfoldings?
>
> Simon
>
> |  -Original Message-
> |  From: ghc-devs [mailto:ghc-devs-boun...@haskell.org
> ] On Behalf Of
> |  Edward Z. Yang
> |  Sent: 18 January 2016 06:37
> |  To: Conal Elliott 
> |  Cc: Andrew Farmer ; ghc-devs@haskell.org
> |  Subject: Re: ghci and unfoldings?
> |
> |  Does passing -fobject-code solve your problem?
> |
> |  Edward
> |
> |  Excerpts from Conal Elliott's message of 2016-01-17 22:18:49 -0800:
> |  > Hi Brandon. Thanks for the reply. I’m not sure that it addresses
> |  what
> |  > I was trying to ask. GHCi *does* invoke plugins and even reloads
> |  those
> |  > plugins dynamically when their source code changes. So in this sense
> |  > ghci does enable optimization, even if it doesn’t perform much
> |  > optimization on its own. And of course plugins and unfolding are not
> |  just about optimization.
> |  >
> |  > I’m not looking for ghci to do optimization, but rather to enable me
> |  > to more easily develop my GHC plugins. It’s *almost* there already.
> |  I
> |  > just need access to unfoldings from other modules for my plugin’s
> |  use.
> |  >
> |  > For context, I’m rebuilding my Haskell-to-hardware compiler
> |  > <https://github.com/conal/talk-2015-haskell-to-hardware>, which
> |  relies
> |  > on giving a non-standard but principled interpretation of Haskell
> |  > programs via a conversion through the language of cartesian closed
> |  categories (CCCs).
> |  > The first back-end is hardware generation (e.g., via Verilog), and I
> |  > have plans for several other CCC-based interpretations.
> |  >
> |  > In addition to facilitating my plugin development, hosting in ghci
> |  > will make it much more pleasant for others to *use* the plugin
> |  during
> |  > exploratory programming, just as with ghci use in general. With
> |  access
> |  > to unfoldings, users will be able to generate circuit diagrams and
> |  > Verilog like those in my compiler talk immediately and directly from
> |  > within ghci. I also intend to make a GPU back-end for fast
> |  interactive
> |  > graphics etc, which would be much more fun in ghci than with batch
> |  compilation.
> |  > I hope this explanation clarifies my goals and motivation. I hope
> |  > there’s a way to access unfoldings from ghci currently or with a
> |  small
> |  > amount of effort.
> |  >
> |  > Regards, - Conal
> |  >
> |  > On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery
> |  
> |  > wrote:
> |  >
> |  > > On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott 
> |  wrote:
> |  > >
> |  > >> I'm developing a GHC plugin (using HERMIT), and I'd like to use
> |  > >> ghci to speed up development. I'm able to do so, except that my
> |  > >> plugin critically needs access to unfoldings, which appear to be
> |  > >> unavailable in ghci. A little experimenting with ghc shows me
> |  that
> |  > >> "-O" is the key, but "-O" is incompatible with "--interactive"
> |  (as
> |  > >> in ghci). Is there any way to persuade gh

Re: ghci and unfoldings?

2016-01-18 Thread Conal Elliott
The minimum flags I've found to get ghci to provide unfoldings are -O and
-object-code. And it appears that both flags need to be present the first
time I load a module into GHCi. (I'm putting the flags in an OPTIONS_GHC
pragma.)

On Mon, Jan 18, 2016 at 9:46 AM, Conal Elliott  wrote:

> That's the flag I would expect. It doesn't seem to help or hinder
> availability of unfoldings in GHCi. Do you think it should?
>
> And Happy Birthday, Simon!
>
> Warmly, - Conal
>
>
> On Monday, January 18, 2016, Simon Peyton Jones 
> wrote:
>
>> Or -fexpose-all-unfoldings?
>>
>> Simon
>>
>> |  -Original Message-
>> |  From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of
>> |  Edward Z. Yang
>> |  Sent: 18 January 2016 06:37
>> |  To: Conal Elliott 
>> |  Cc: Andrew Farmer ; ghc-devs@haskell.org
>> |  Subject: Re: ghci and unfoldings?
>> |
>> |  Does passing -fobject-code solve your problem?
>> |
>> |  Edward
>> |
>> |  Excerpts from Conal Elliott's message of 2016-01-17 22:18:49 -0800:
>> |  > Hi Brandon. Thanks for the reply. I’m not sure that it addresses
>> |  what
>> |  > I was trying to ask. GHCi *does* invoke plugins and even reloads
>> |  those
>> |  > plugins dynamically when their source code changes. So in this sense
>> |  > ghci does enable optimization, even if it doesn’t perform much
>> |  > optimization on its own. And of course plugins and unfolding are not
>> |  just about optimization.
>> |  >
>> |  > I’m not looking for ghci to do optimization, but rather to enable me
>> |  > to more easily develop my GHC plugins. It’s *almost* there already.
>> |  I
>> |  > just need access to unfoldings from other modules for my plugin’s
>> |  use.
>> |  >
>> |  > For context, I’m rebuilding my Haskell-to-hardware compiler
>> |  > <https://github.com/conal/talk-2015-haskell-to-hardware>, which
>> |  relies
>> |  > on giving a non-standard but principled interpretation of Haskell
>> |  > programs via a conversion through the language of cartesian closed
>> |  categories (CCCs).
>> |  > The first back-end is hardware generation (e.g., via Verilog), and I
>> |  > have plans for several other CCC-based interpretations.
>> |  >
>> |  > In addition to facilitating my plugin development, hosting in ghci
>> |  > will make it much more pleasant for others to *use* the plugin
>> |  during
>> |  > exploratory programming, just as with ghci use in general. With
>> |  access
>> |  > to unfoldings, users will be able to generate circuit diagrams and
>> |  > Verilog like those in my compiler talk immediately and directly from
>> |  > within ghci. I also intend to make a GPU back-end for fast
>> |  interactive
>> |  > graphics etc, which would be much more fun in ghci than with batch
>> |  compilation.
>> |  > I hope this explanation clarifies my goals and motivation. I hope
>> |  > there’s a way to access unfoldings from ghci currently or with a
>> |  small
>> |  > amount of effort.
>> |  >
>> |  > Regards, - Conal
>> |  >
>> |  > On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery
>> |  
>> |  > wrote:
>> |  >
>> |  > > On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott 
>> |  wrote:
>> |  > >
>> |  > >> I'm developing a GHC plugin (using HERMIT), and I'd like to use
>> |  > >> ghci to speed up development. I'm able to do so, except that my
>> |  > >> plugin critically needs access to unfoldings, which appear to be
>> |  > >> unavailable in ghci. A little experimenting with ghc shows me
>> |  that
>> |  > >> "-O" is the key, but "-O" is incompatible with "--interactive"
>> |  (as
>> |  > >> in ghci). Is there any way to persuade ghci to make unfoldings
>> |  available?
>> |  > >
>> |  > >
>> |  > > I think unfoldings are only done as part of optimization, and the
>> |  > > bytecode backend doesn't support optimization at all.
>> |  > >
>> |  > > --
>> |  > > brandon s allbery kf8nh   sine nomine
>> |  > > associates
>> |  > > allber...@gmail.com
>> |  > > ballb...@sinenomine.net
>> |  > > unix, openafs, kerberos, infrastructure, xmonad
>> |  > >
>> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fsine
>> |  > >
>> |  nomine.net&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cbaf2ef5
>> |  > >
>> |  5f8af447b42e608d31fd1cec1%7c72f988bf86f141af91ab2d7cd011db47%7c1&sda
>> |  > > ta=qMNmL5LmkgMp0ebkr6SzPQIwhySqOicZgEdW%2fhe6Q%2b0%3d
>> |  > >
>> |  ___
>> |  ghc-devs mailing list
>> |  ghc-devs@haskell.org
>> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h
>> |  askell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-
>> |  devs%0a&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cbaf2ef55f8af
>> |  447b42e608d31fd1cec1%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=veoz
>> |  Ab6M7N9jZaJZ9tgXZ%2fI8jq7U%2b4YM1FcSXvqTcaw%3d
>>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ghci and unfoldings?

2016-01-18 Thread Conal Elliott
That's the flag I would expect. It doesn't seem to help or hinder
availability of unfoldings in GHCi. Do you think it should?

And Happy Birthday, Simon!

Warmly, - Conal

On Monday, January 18, 2016, Simon Peyton Jones 
wrote:

> Or -fexpose-all-unfoldings?
>
> Simon
>
> |  -Original Message-
> |  From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of
> |  Edward Z. Yang
> |  Sent: 18 January 2016 06:37
> |  To: Conal Elliott 
> |  Cc: Andrew Farmer ; ghc-devs@haskell.org
> |  Subject: Re: ghci and unfoldings?
> |
> |  Does passing -fobject-code solve your problem?
> |
> |  Edward
> |
> |  Excerpts from Conal Elliott's message of 2016-01-17 22:18:49 -0800:
> |  > Hi Brandon. Thanks for the reply. I’m not sure that it addresses
> |  what
> |  > I was trying to ask. GHCi *does* invoke plugins and even reloads
> |  those
> |  > plugins dynamically when their source code changes. So in this sense
> |  > ghci does enable optimization, even if it doesn’t perform much
> |  > optimization on its own. And of course plugins and unfolding are not
> |  just about optimization.
> |  >
> |  > I’m not looking for ghci to do optimization, but rather to enable me
> |  > to more easily develop my GHC plugins. It’s *almost* there already.
> |  I
> |  > just need access to unfoldings from other modules for my plugin’s
> |  use.
> |  >
> |  > For context, I’m rebuilding my Haskell-to-hardware compiler
> |  > <https://github.com/conal/talk-2015-haskell-to-hardware>, which
> |  relies
> |  > on giving a non-standard but principled interpretation of Haskell
> |  > programs via a conversion through the language of cartesian closed
> |  categories (CCCs).
> |  > The first back-end is hardware generation (e.g., via Verilog), and I
> |  > have plans for several other CCC-based interpretations.
> |  >
> |  > In addition to facilitating my plugin development, hosting in ghci
> |  > will make it much more pleasant for others to *use* the plugin
> |  during
> |  > exploratory programming, just as with ghci use in general. With
> |  access
> |  > to unfoldings, users will be able to generate circuit diagrams and
> |  > Verilog like those in my compiler talk immediately and directly from
> |  > within ghci. I also intend to make a GPU back-end for fast
> |  interactive
> |  > graphics etc, which would be much more fun in ghci than with batch
> |  compilation.
> |  > I hope this explanation clarifies my goals and motivation. I hope
> |  > there’s a way to access unfoldings from ghci currently or with a
> |  small
> |  > amount of effort.
> |  >
> |  > Regards, - Conal
> |  >
> |  > On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery
> |  
> |  > wrote:
> |  >
> |  > > On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott 
> |  wrote:
> |  > >
> |  > >> I'm developing a GHC plugin (using HERMIT), and I'd like to use
> |  > >> ghci to speed up development. I'm able to do so, except that my
> |  > >> plugin critically needs access to unfoldings, which appear to be
> |  > >> unavailable in ghci. A little experimenting with ghc shows me
> |  that
> |  > >> "-O" is the key, but "-O" is incompatible with "--interactive"
> |  (as
> |  > >> in ghci). Is there any way to persuade ghci to make unfoldings
> |  available?
> |  > >
> |  > >
> |  > > I think unfoldings are only done as part of optimization, and the
> |  > > bytecode backend doesn't support optimization at all.
> |  > >
> |  > > --
> |  > > brandon s allbery kf8nh   sine nomine
> |  > > associates
> |  > > allber...@gmail.com
> |  > > ballb...@sinenomine.net
> |  > > unix, openafs, kerberos, infrastructure, xmonad
> |  > >
> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fsine
> |  > >
> |  nomine.net&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cbaf2ef5
> |  > >
> |  5f8af447b42e608d31fd1cec1%7c72f988bf86f141af91ab2d7cd011db47%7c1&sda
> |  > > ta=qMNmL5LmkgMp0ebkr6SzPQIwhySqOicZgEdW%2fhe6Q%2b0%3d
> |  > >
> |  ___
> |  ghc-devs mailing list
> |  ghc-devs@haskell.org
> |  https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h
> |  askell.org%2fcgi-bin%2fmailman%2flistinfo%2fghc-
> |  devs%0a&data=01%7c01%7csimonpj%40064d.mgd.microsoft.com%7cbaf2ef55f8af
> |  447b42e608d31fd1cec1%7c72f988bf86f141af91ab2d7cd011db47%7c1&sdata=veoz
> |  Ab6M7N9jZaJZ9tgXZ%2fI8jq7U%2b4YM1FcSXvqTcaw%3d
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Plugin from ghci REPL?

2016-01-17 Thread Conal Elliott
Is it possible to have GHC plugins get invoked from the ghci *REPL* (in
addition to loaded source modules)? I'm doing some monomorphization-based
transformation, and currently I write scads of trivial monomorphic
specialization definitions like

> sumt6 = sum :: Tree 6 Int -> Int

I'd instead love to enter "let sumt6 = sum :: Tree 6 Int -> Int" or
(better) just "sum :: Tree 6 Int -> Int" into the REPL and have my plugin
run, without having to keep monkeying with a source file and reloading. As
I understand it, an expression is turned into "let it = ...", so maybe the
expression option would come for free with the ability to run plugins on
in-REPL definitions.

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ghci and unfoldings?

2016-01-17 Thread Conal Elliott
Oh! I spoke too soon. Yes, that flag does seem to make unfoldings
available. Thanks! Now more experimentation. Thanks again!

-- Conal

On Sun, Jan 17, 2016 at 10:45 PM, Conal Elliott  wrote:

> Thanks for the suggestion. That flag doesn't appear to help. Still no
> unfolding info.
>
> On Sun, Jan 17, 2016 at 10:37 PM, Edward Z. Yang  wrote:
>
>> Does passing -fobject-code solve your problem?
>>
>> Edward
>>
>> Excerpts from Conal Elliott's message of 2016-01-17 22:18:49 -0800:
>> > Hi Brandon. Thanks for the reply. I’m not sure that it addresses what I
>> was
>> > trying to ask. GHCi *does* invoke plugins and even reloads those plugins
>> > dynamically when their source code changes. So in this sense ghci does
>> > enable optimization, even if it doesn’t perform much optimization on its
>> > own. And of course plugins and unfolding are not just about
>> optimization.
>> >
>> > I’m not looking for ghci to do optimization, but rather to enable me to
>> > more easily develop my GHC plugins. It’s *almost* there already. I just
>> > need access to unfoldings from other modules for my plugin’s use.
>> >
>> > For context, I’m rebuilding my Haskell-to-hardware compiler
>> > <https://github.com/conal/talk-2015-haskell-to-hardware>, which relies
>> on
>> > giving a non-standard but principled interpretation of Haskell programs
>> via
>> > a conversion through the language of cartesian closed categories (CCCs).
>> > The first back-end is hardware generation (e.g., via Verilog), and I
>> have
>> > plans for several other CCC-based interpretations.
>> >
>> > In addition to facilitating my plugin development, hosting in ghci will
>> > make it much more pleasant for others to *use* the plugin during
>> > exploratory programming, just as with ghci use in general. With access
>> to
>> > unfoldings, users will be able to generate circuit diagrams and Verilog
>> > like those in my compiler talk immediately and directly from within
>> ghci. I
>> > also intend to make a GPU back-end for fast interactive graphics etc,
>> which
>> > would be much more fun in ghci than with batch compilation.
>> > I hope this explanation clarifies my goals and motivation. I hope
>> there’s a
>> > way to access unfoldings from ghci currently or with a small amount of
>> > effort.
>> >
>> > Regards, - Conal
>> >
>> > On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery 
>> > wrote:
>> >
>> > > On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott 
>> wrote:
>> > >
>> > >> I'm developing a GHC plugin (using HERMIT), and I'd like to use ghci
>> to
>> > >> speed up development. I'm able to do so, except that my plugin
>> critically
>> > >> needs access to unfoldings, which appear to be unavailable in ghci. A
>> > >> little experimenting with ghc shows me that "-O" is the key, but
>> "-O" is
>> > >> incompatible with "--interactive" (as in ghci). Is there any way to
>> > >> persuade ghci to make unfoldings available?
>> > >
>> > >
>> > > I think unfoldings are only done as part of optimization, and the
>> bytecode
>> > > backend doesn't support optimization at all.
>> > >
>> > > --
>> > > brandon s allbery kf8nh   sine nomine
>> > > associates
>> > > allber...@gmail.com
>> > > ballb...@sinenomine.net
>> > > unix, openafs, kerberos, infrastructure, xmonad
>> > > http://sinenomine.net
>> > >
>>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ghci and unfoldings?

2016-01-17 Thread Conal Elliott
Thanks for the suggestion. That flag doesn't appear to help. Still no
unfolding info.

On Sun, Jan 17, 2016 at 10:37 PM, Edward Z. Yang  wrote:

> Does passing -fobject-code solve your problem?
>
> Edward
>
> Excerpts from Conal Elliott's message of 2016-01-17 22:18:49 -0800:
> > Hi Brandon. Thanks for the reply. I’m not sure that it addresses what I
> was
> > trying to ask. GHCi *does* invoke plugins and even reloads those plugins
> > dynamically when their source code changes. So in this sense ghci does
> > enable optimization, even if it doesn’t perform much optimization on its
> > own. And of course plugins and unfolding are not just about optimization.
> >
> > I’m not looking for ghci to do optimization, but rather to enable me to
> > more easily develop my GHC plugins. It’s *almost* there already. I just
> > need access to unfoldings from other modules for my plugin’s use.
> >
> > For context, I’m rebuilding my Haskell-to-hardware compiler
> > <https://github.com/conal/talk-2015-haskell-to-hardware>, which relies
> on
> > giving a non-standard but principled interpretation of Haskell programs
> via
> > a conversion through the language of cartesian closed categories (CCCs).
> > The first back-end is hardware generation (e.g., via Verilog), and I have
> > plans for several other CCC-based interpretations.
> >
> > In addition to facilitating my plugin development, hosting in ghci will
> > make it much more pleasant for others to *use* the plugin during
> > exploratory programming, just as with ghci use in general. With access to
> > unfoldings, users will be able to generate circuit diagrams and Verilog
> > like those in my compiler talk immediately and directly from within
> ghci. I
> > also intend to make a GPU back-end for fast interactive graphics etc,
> which
> > would be much more fun in ghci than with batch compilation.
> > I hope this explanation clarifies my goals and motivation. I hope
> there’s a
> > way to access unfoldings from ghci currently or with a small amount of
> > effort.
> >
> > Regards, - Conal
> >
> > On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery 
> > wrote:
> >
> > > On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott 
> wrote:
> > >
> > >> I'm developing a GHC plugin (using HERMIT), and I'd like to use ghci
> to
> > >> speed up development. I'm able to do so, except that my plugin
> critically
> > >> needs access to unfoldings, which appear to be unavailable in ghci. A
> > >> little experimenting with ghc shows me that "-O" is the key, but "-O"
> is
> > >> incompatible with "--interactive" (as in ghci). Is there any way to
> > >> persuade ghci to make unfoldings available?
> > >
> > >
> > > I think unfoldings are only done as part of optimization, and the
> bytecode
> > > backend doesn't support optimization at all.
> > >
> > > --
> > > brandon s allbery kf8nh   sine nomine
> > > associates
> > > allber...@gmail.com
> > > ballb...@sinenomine.net
> > > unix, openafs, kerberos, infrastructure, xmonad
> > > http://sinenomine.net
> > >
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: ghci and unfoldings?

2016-01-17 Thread Conal Elliott
Hi Brandon. Thanks for the reply. I’m not sure that it addresses what I was
trying to ask. GHCi *does* invoke plugins and even reloads those plugins
dynamically when their source code changes. So in this sense ghci does
enable optimization, even if it doesn’t perform much optimization on its
own. And of course plugins and unfolding are not just about optimization.

I’m not looking for ghci to do optimization, but rather to enable me to
more easily develop my GHC plugins. It’s *almost* there already. I just
need access to unfoldings from other modules for my plugin’s use.

For context, I’m rebuilding my Haskell-to-hardware compiler
<https://github.com/conal/talk-2015-haskell-to-hardware>, which relies on
giving a non-standard but principled interpretation of Haskell programs via
a conversion through the language of cartesian closed categories (CCCs).
The first back-end is hardware generation (e.g., via Verilog), and I have
plans for several other CCC-based interpretations.

In addition to facilitating my plugin development, hosting in ghci will
make it much more pleasant for others to *use* the plugin during
exploratory programming, just as with ghci use in general. With access to
unfoldings, users will be able to generate circuit diagrams and Verilog
like those in my compiler talk immediately and directly from within ghci. I
also intend to make a GPU back-end for fast interactive graphics etc, which
would be much more fun in ghci than with batch compilation.
I hope this explanation clarifies my goals and motivation. I hope there’s a
way to access unfoldings from ghci currently or with a small amount of
effort.

Regards, - Conal

On Sun, Jan 17, 2016 at 7:00 PM, Brandon Allbery 
wrote:

> On Sun, Jan 17, 2016 at 9:40 PM, Conal Elliott  wrote:
>
>> I'm developing a GHC plugin (using HERMIT), and I'd like to use ghci to
>> speed up development. I'm able to do so, except that my plugin critically
>> needs access to unfoldings, which appear to be unavailable in ghci. A
>> little experimenting with ghc shows me that "-O" is the key, but "-O" is
>> incompatible with "--interactive" (as in ghci). Is there any way to
>> persuade ghci to make unfoldings available?
>
>
> I think unfoldings are only done as part of optimization, and the bytecode
> backend doesn't support optimization at all.
>
> --
> brandon s allbery kf8nh   sine nomine
> associates
> allber...@gmail.com
> ballb...@sinenomine.net
> unix, openafs, kerberos, infrastructure, xmonad
> http://sinenomine.net
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


ghci and unfoldings?

2016-01-17 Thread Conal Elliott
I'm developing a GHC plugin (using HERMIT), and I'd like to use ghci to
speed up development. I'm able to do so, except that my plugin critically
needs access to unfoldings, which appear to be unavailable in ghci. A
little experimenting with ghc shows me that "-O" is the key, but "-O" is
incompatible with "--interactive" (as in ghci). Is there any way to
persuade ghci to make unfoldings available?

Thanks, - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Inlining of methods (dictionary accessors) in GHC 7.10?

2016-01-12 Thread Conal Elliott
I don't know that I can give an example, because I'm using the GHC API
indirectly, via HERMIT. Andrew Farmer noticed that the dictionary accessors
have special rules rather than unfoldings, and he was able to extend HERMIT
to do the equivalent of applying those rules. It's working fine, and the
supporting HERMIT code is reasonably simple.

Cheers,
- Conal

On Wed, Jan 6, 2016 at 1:25 AM, Simon Peyton Jones 
wrote:

> Quite possibly.  Maybe you can give a tiny concrete example?
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 06 January 2016 05:38
> *To:* ghc-devs@haskell.org
> *Subject:* Inlining of methods (dictionary accessors) in GHC 7.10?
>
>
>
> Did something about change with method inlining between GHC 7.8.2 and
> 7.10.3? I don't mean methods attached to instances, but rather the method
> name itself, which I understand is defined as simple field accessors into a
> dictionary. I do inlining indirectly via HERMIT, and the method names are
> no longer successfully inlining to the accessors. The dictionaries
> themselves inline fine, as do field accessors for algebraic types with
> named fields.
>
> -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Inlining of methods (dictionary accessors) in GHC 7.10?

2016-01-05 Thread Conal Elliott
Sorry for the editing error. I meant "Did something about change with ...".

On Tue, Jan 5, 2016 at 9:38 PM, Conal Elliott  wrote:

> Did something about change with method inlining between GHC 7.8.2 and
> 7.10.3? I don't mean methods attached to instances, but rather the method
> name itself, which I understand is defined as simple field accessors into a
> dictionary. I do inlining indirectly via HERMIT, and the method names are
> no longer successfully inlining to the accessors. The dictionaries
> themselves inline fine, as do field accessors for algebraic types with
> named fields.
>
> -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Inlining of methods (dictionary accessors) in GHC 7.10?

2016-01-05 Thread Conal Elliott
Did something about change with method inlining between GHC 7.8.2 and
7.10.3? I don't mean methods attached to instances, but rather the method
name itself, which I understand is defined as simple field accessors into a
dictionary. I do inlining indirectly via HERMIT, and the method names are
no longer successfully inlining to the accessors. The dictionaries
themselves inline fine, as do field accessors for algebraic types with
named fields.

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


Re: Pruning GADT case alternatives with uninhabitable coercion parameters

2014-06-24 Thread Conal Elliott
My first go is at
https://github.com/conal/hermit-extras/blob/master/src/HERMIT/Extras.hs#L1030
. It type-checks. I haven't tried running it yet. Comments most welcome!

-- Conal


On Tue, Jun 24, 2014 at 4:10 PM, Conal Elliott  wrote:

> I'm glad for the interest and help. I can make an initial go of it. My
> current simple plan is to traverse expressions, collecting type equalities
> from bound coercion variables as I descend, combining them progressively
> with successive type unifications. The traversal is thus parametrized by a
> TvSubst and yields a Maybe TvSubst. The coercion variables will come from
> lambdas, let bindings and case alternatives. If an added equality is not
> unifiable given the current TvSubst, we've reached a contradiction. If the
> contradiction arises for one of the variables in a case alternative, then
> remove that alternative.
>
> How does this strategy sound?
>
> Some issues:
>
> *   Nominal vs representational type equalities.
> *   Will I want to normalize the types (with normaliseType) before
> unifying?
> *   How can I unify while carrying along a type substitution environment?
> The Unify module exports tcUnifyTy, which takes no such environment, but
> not unify, which does.
>
> -- Conal
>
>
> On Tue, Jun 24, 2014 at 4:43 AM, Simon Peyton Jones  > wrote:
>
>>  we need to do a bit more work to re-connect to source pattern locations
>> and nested patterns? I can’t assess very well yet if this is a real problem
>> though
>>
>>
>>
>> That is a very good point.
>>
>>
>>
>> Nevertheless, given
>>
>> · the typechecked HsSyn (i.e. still in source form, but with
>> type inference fully completed
>>
>> · the independent contradiction-detector described below (which
>> is independent of whether the contradiction problems it is given come from
>> HsSyn or Core)
>>
>> it would be easy to give source-localised error messages
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* Dimitrios Vytiniotis
>> *Sent:* 24 June 2014 11:58
>> *To:* Simon Peyton Jones; Conal Elliott; ghc-devs@haskell.org
>> *Cc:* Nikolaos S. Papaspyrou (nic...@softlab.ntua.gr); George Karachalias
>>
>> *Subject:* RE: Pruning GADT case alternatives with uninhabitable
>> coercion parameters
>>
>>
>>
>>
>>
>> Yes it would be better in the sense that we don’t really want to be
>> dealing with unification variables and evidence when we simply use the
>> constraint solver to detect inconsistencies in possibly missing patterns,
>> but the concern has been that if we are already desugared and in core maybe
>> we need to do a bit more work to re-connect to source pattern locations and
>> nested patterns? I can’t assess very well yet if this is a real problem
>> though …
>>
>>
>>
>> In general I agree that a simple constraint solver for Core might be an
>> independently useful tool for this kind of optimization. (I think George
>> had thought about this too).
>>
>>
>>
>> Thanks!
>>
>> d-
>>
>>
>>
>>
>>
>>
>>
>> *From:* Simon Peyton Jones
>> *Sent:* Tuesday, June 24, 2014 11:41 AM
>> *To:* Conal Elliott; ghc-devs@haskell.org
>> *Cc:* Dimitrios Vytiniotis; Nikolaos S. Papaspyrou (
>> nic...@softlab.ntua.gr); George Karachalias; Simon Peyton Jones
>> *Subject:* RE: Pruning GADT case alternatives with uninhabitable
>> coercion parameters
>>
>>
>>
>> Conal
>>
>>
>>
>> This also relates to detecting redundant or overlapped patterns in source
>> programs. I know that Dimitrios is looking at this with Tom, Nikolas,
>> George who I’m cc’ing him.
>>
>>
>>
>> I think their current approach may be to integrate the overlap checking
>> with the constraint solver in the type checker.  But that isn’t going to
>> work for optimising Core.
>>
>>
>>
>> An alternative approach would be to implement a specialised constraint
>> solver.  It could be MUCH simpler than the one in the inference engine,
>> because (a) there are no unification variables to worry about, (b) there is
>> no need to gather evidence.  More or less it’s task could be to answer the
>> question
>>
>> IsC |- Ddefinitely a contradiction?
>>
>> where C are the “given” constraints (from enclosing pattern matches) and
>> D are the “wanted” constraints (from the current pattern match that may be
>> unreachable).
>>
>>
>>
>> I don’t think it

Re: Pruning GADT case alternatives with uninhabitable coercion parameters

2014-06-24 Thread Conal Elliott
I'm glad for the interest and help. I can make an initial go of it. My
current simple plan is to traverse expressions, collecting type equalities
from bound coercion variables as I descend, combining them progressively
with successive type unifications. The traversal is thus parametrized by a
TvSubst and yields a Maybe TvSubst. The coercion variables will come from
lambdas, let bindings and case alternatives. If an added equality is not
unifiable given the current TvSubst, we've reached a contradiction. If the
contradiction arises for one of the variables in a case alternative, then
remove that alternative.

How does this strategy sound?

Some issues:

*   Nominal vs representational type equalities.
*   Will I want to normalize the types (with normaliseType) before unifying?
*   How can I unify while carrying along a type substitution environment?
The Unify module exports tcUnifyTy, which takes no such environment, but
not unify, which does.

-- Conal


On Tue, Jun 24, 2014 at 4:43 AM, Simon Peyton Jones 
wrote:

>  we need to do a bit more work to re-connect to source pattern locations
> and nested patterns? I can’t assess very well yet if this is a real problem
> though
>
>
>
> That is a very good point.
>
>
>
> Nevertheless, given
>
> · the typechecked HsSyn (i.e. still in source form, but with type
> inference fully completed
>
> · the independent contradiction-detector described below (which
> is independent of whether the contradiction problems it is given come from
> HsSyn or Core)
>
> it would be easy to give source-localised error messages
>
>
>
> Simon
>
>
>
> *From:* Dimitrios Vytiniotis
> *Sent:* 24 June 2014 11:58
> *To:* Simon Peyton Jones; Conal Elliott; ghc-devs@haskell.org
> *Cc:* Nikolaos S. Papaspyrou (nic...@softlab.ntua.gr); George Karachalias
>
> *Subject:* RE: Pruning GADT case alternatives with uninhabitable coercion
> parameters
>
>
>
>
>
> Yes it would be better in the sense that we don’t really want to be
> dealing with unification variables and evidence when we simply use the
> constraint solver to detect inconsistencies in possibly missing patterns,
> but the concern has been that if we are already desugared and in core maybe
> we need to do a bit more work to re-connect to source pattern locations and
> nested patterns? I can’t assess very well yet if this is a real problem
> though …
>
>
>
> In general I agree that a simple constraint solver for Core might be an
> independently useful tool for this kind of optimization. (I think George
> had thought about this too).
>
>
>
> Thanks!
>
> d-
>
>
>
>
>
>
>
> *From:* Simon Peyton Jones
> *Sent:* Tuesday, June 24, 2014 11:41 AM
> *To:* Conal Elliott; ghc-devs@haskell.org
> *Cc:* Dimitrios Vytiniotis; Nikolaos S. Papaspyrou (nic...@softlab.ntua.gr);
> George Karachalias; Simon Peyton Jones
> *Subject:* RE: Pruning GADT case alternatives with uninhabitable coercion
> parameters
>
>
>
> Conal
>
>
>
> This also relates to detecting redundant or overlapped patterns in source
> programs. I know that Dimitrios is looking at this with Tom, Nikolas,
> George who I’m cc’ing him.
>
>
>
> I think their current approach may be to integrate the overlap checking
> with the constraint solver in the type checker.  But that isn’t going to
> work for optimising Core.
>
>
>
> An alternative approach would be to implement a specialised constraint
> solver.  It could be MUCH simpler than the one in the inference engine,
> because (a) there are no unification variables to worry about, (b) there is
> no need to gather evidence.  More or less it’s task could be to answer the
> question
>
> IsC |- Ddefinitely a contradiction?
>
> where C are the “given” constraints (from enclosing pattern matches) and D
> are the “wanted” constraints (from the current pattern match that may be
> unreachable).
>
>
>
> I don’t think it would be hard to implement such a function.  I’d be happy
> to help advise if someone wants to take it on.
>
>
>
> Dimitrios: If we had such a function, then maybe it’d be better to use it
> for the pattern-matching overlap detection too?
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org
> ] *On Behalf Of *Conal Elliott
> *Sent:* 20 June 2014 18:59
> *To:* ghc-devs@haskell.org
> *Subject:* Pruning GADT case alternatives with uninhabitable coercion
> parameters
>
>
>
> I'm looking for tips on pruning away impossible branches in `case`
> expressions on GADTs, due to uninhabited coercion parameter types.
>
> Here's a simple example (rendered by HERMIT) from a type-specializion of

Pruning GADT case alternatives with uninhabitable coercion parameters

2014-06-20 Thread Conal Elliott
I'm looking for tips on pruning away impossible branches in `case`
expressions on GADTs, due to uninhabited coercion parameter types.

Here's a simple example (rendered by HERMIT) from a type-specializion of
the Foldable instance a GADT for perfect leaf trees in which the tree depth
is part of the type:

> case ds of wild (Sum Int)
>   L (~# :: S (S Z) ~N Z) a1 -> f a1
>   B n1 (~# :: S (S Z) ~N S n1) uv -> ...

Note the kind of the coercion parameter to the leaf constructor (`L`): `S
(S Z) ~N Z`, i.e., 2 == 0. I think we can safely remove this branch as
impossible.

The reasoning gets subtler, however.
After inlining and simplifying in the second (`B`) alternative, the
following turns up:

> case ds0 of wild0 (Sum Int)
>   L (~# :: n1 ~N Z) a1 -> f0 a1
>   B n2 (~# :: n1 ~N S n2) uv0 -> ...

Now I want to remove the first `L` alternative with `n1 ~ Z`, given that
the kind `S (S Z) ~N S n1` is inhabited (since we're in the first `B`
alternative), so that `n1 ~ S Z`. With more inlining, more such equalities
pile up. Soon we get to an impossible `B` alternative, whose removal would
then eliminate the rest of the recursive unfolding.

My questions:

*   Does this sort of transformation already live in GHC somewhere, and if
so, where?
*   Are there gotchas / sources of unsoundness in the transformation I'm
suggesting?
*   Is anyone else already working on this sort of transformation?

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Constructing coercions for associated type?

2014-05-25 Thread Conal Elliott
Looks perfect. It'll take some time to put the pieces together, but I think
it'll work. Thanks, Richard!-- Conal


On Sun, May 25, 2014 at 11:42 AM, Richard Eisenberg wrote:

> Does FamInstEnv.normaliseType work for you? FamInstEnv is in the types/
> directory. FamInst.tcGetFamInstEnvs may also be helpful. FamInst is in the
> typecheck/ directory.
>
> Richard
>
> On May 25, 2014, at 12:42 PM, Conal Elliott  wrote:
>
> > I'm working on a GHC plugin in which I need to programmatically
> construct a coercion for an associated type, given the type function name
> and the type argument. For instance, I have the following class:
> >
> > > class Encodable a where
> > >   type Encode a
> > >   encode :: a -> Encode a
> > >   decode :: Encode a -> a
> >
> > along with a type instance, say `Int -> Bool`. In a GHC plugin, how can
> I apply a type function to an argument type to get back the resulting type
> and the associated coercion? (Given the latter, I think the former comes
> from `coercionKind`).
> >
> > -- Conal
> > ___
> > ghc-devs mailing list
> > ghc-devs@haskell.org
> > http://www.haskell.org/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Constructing coercions for associated type?

2014-05-25 Thread Conal Elliott
I'm working on a GHC plugin in which I need to programmatically construct a
coercion for an associated type, given the type function name and the type
argument. For instance, I have the following class:

> class Encodable a where
>   type Encode a
>   encode :: a -> Encode a
>   decode :: Encode a -> a

along with a type instance, say `Int -> Bool`. In a GHC plugin, how can I
apply a type function to an argument type to get back the resulting type
and the associated coercion? (Given the latter, I think the former comes
from `coercionKind`).

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Simplifying casts and beta-reduction

2014-05-08 Thread Conal Elliott
Thanks, Simon. I'll keep poking around.


On Thu, May 8, 2014 at 12:54 AM, Simon Peyton Jones
wrote:

>  Yes, that’s right: simplCast is the guy.  I can’t explain why it’s not
> working for you, though
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 08 May 2014 04:19
> *To:* Simon Peyton Jones
> *Cc:* ghc-devs@haskell.org
> *Subject:* Re: Simplifying casts and beta-reduction
>
>
>
> I'm still sorting through how to optimize these almost-beta-redexes in the
> form `((\ x -> u) |> co) v`, shifting coercions to enable beta-reduction
> (as described in section 3.1 of "Evidence normalization"). Is it done by
> `simplCast` (with help from `simplCoercion`), as called indirectly from
> `simplifyExpr` in `SimplCore`? I think I'm now calling `simplifyExpr` from
> HERMIT but I'm not getting the cast-shifting I'm looking for.
>
> -- Conal
>
>
>
> On Wed, May 7, 2014 at 1:02 PM, Conal Elliott  wrote:
>
>  Very useful, indeed! Exactly what I was looking for. Thanks, Simon. Now
> I've read the evidence normalization and the deferred types paper, and I
> have a much better understanding of what's going on.
>
> -- Conal
>
>
>
> On Wed, May 7, 2014 at 1:28 AM, Simon Peyton Jones 
> wrote:
>
>  Absolutely. There’s a whole module that does this: OptCoercion.  If you
> want to see what programs look like without coercion optimisation, try
> –fno-opt-coercion.
>
>
>
> The rules are described in our paper *Evidence normalization in System
> FC: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/
> <http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/>*
>
>
>
> I hope that’s useful.
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 07 May 2014 04:50
> *To:* ghc-devs@haskell.org
> *Subject:* Simplifying casts and beta-reduction
>
>
>
> I'm looking for tools to help simplify Core terms that involve casts. In
> particular, I want to beta-reduce when the function is wrapped with a cast.
> Do the GHC sources have such utility functions?
>
> Here is an example of a lambda expression with a cast. In context, it's
> applied to two type arguments and two dictionary arguments and returns a
> function of one more argument. (The function `(-->)` is defined as `(f -->
> h) g = h . g . f`.)
>
> > ((\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> > case $dEncodable of _
> >   D:Encodable _ tpl_B3 ->
> > case $dEncodable1 of _
> >   D:Encodable tpl_B2 _ ->
> > \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
> eta))
> > )
> >  `cast` (forall a8 b.
> >  _R
> >  -> _R
> >  ->  b>_R
> >  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >  :: (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode a8 -> Encode b)
> >   ~#
> > (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode (a8 -> b
>
> I can imagine pushing the `cast` down through the type lambdas while
> stripping off `forall` coercions, then pushing the remaining `cast` through
> the dictionary arguments, while stripping off the outer `_R
> ->` coercion wrappers, and then pushing the cast into the `case`
> alternatives and the lambda body, leaving something like
>
> >  (\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> >  case $dEncodable of _
> >D:Encodable _ tpl_B3 ->
> >  case $dEncodable1 of _
> >D:Encodable tpl_B2 _ ->
> >  \ (g :: a8 -> b) ->
> >(\ (eta :: Encode a8) -> tpl_B2 (g (tpl_B3 eta)))
> >`cast` (Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >:: (Encode a8 -> Encode b)
> > ~#
> >   (Encode (a8 -> b
>
> Now, given type, dictionary, and function arguments, I think we could
> beta-reduce.
>
> Before I try implementing these transformations, does something like them
> already exist in GHC?
>
> Thanks, -- Conal
>
>
>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Simplifying casts and beta-reduction

2014-05-08 Thread Conal Elliott
Thanks, Jacques! That paper looks tremendously relevant to what I'm doing.
-- Conal


On Thu, May 8, 2014 at 5:01 AM, Jacques Carette  wrote:

>  Sorry to jump in mid-conversation, but since I read about people doing
> exactly this a few days ago, I thought this might be useful.  See the paper
> Michael D. 
> Adams<http://www.informatik.uni-trier.de/%7Eley/pers/hd/a/Adams:Michael_D=.html>,
> Andrew 
> Farmer<http://www.informatik.uni-trier.de/%7Eley/pers/hd/f/Farmer:Andrew.html>,
> José Pedro Magalhães: Optimizing SYB is easy! PEPM 
> 2014<http://www.informatik.uni-trier.de/%7Eley/db/conf/pepm/pepm2014.html#AdamsFM14>:
> 71-82
> http://www.ittc.ku.edu/csdl/fpg/files/Adams-13-OSIE.pdf
>
> where they use Hermit
> http://www.ittc.ku.edu/csdl/fpg/software/hermit.html
> http://hackage.haskell.org/package/hermit
> to do exactly this transformation [and a fair bit more].
>
> Jacques
>
>
> On 2014-05-07 11:18 PM, Conal Elliott wrote:
>
>  I'm still sorting through how to optimize these almost-beta-redexes in
> the form `((\ x -> u) |> co) v`, shifting coercions to enable
> beta-reduction (as described in section 3.1 of "Evidence normalization").
> Is it done by `simplCast` (with help from `simplCoercion`), as called
> indirectly from `simplifyExpr` in `SimplCore`? I think I'm now calling
> `simplifyExpr` from HERMIT but I'm not getting the cast-shifting I'm
> looking for.
>
>  -- Conal
>
>
> On Wed, May 7, 2014 at 1:02 PM, Conal Elliott  wrote:
>
>> Very useful, indeed! Exactly what I was looking for. Thanks, Simon. Now
>> I've read the evidence normalization and the deferred types paper, and I
>> have a much better understanding of what's going on.
>>
>> -- Conal
>>
>>
>>
>> On Wed, May 7, 2014 at 1:28 AM, Simon Peyton Jones > > wrote:
>>
>>>  Absolutely. There’s a whole module that does this: OptCoercion.  If
>>> you want to see what programs look like without coercion optimisation, try
>>> –fno-opt-coercion.
>>>
>>>
>>>
>>> The rules are described in our paper *Evidence normalization in System
>>> FC: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/
>>> <http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/>*
>>>
>>>
>>>
>>> I hope that’s useful.
>>>
>>>
>>>
>>> Simon
>>>
>>>
>>>
>>> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
>>> Elliott
>>> *Sent:* 07 May 2014 04:50
>>> *To:* ghc-devs@haskell.org
>>> *Subject:* Simplifying casts and beta-reduction
>>>
>>>
>>>
>>> I'm looking for tools to help simplify Core terms that involve casts. In
>>> particular, I want to beta-reduce when the function is wrapped with a cast.
>>> Do the GHC sources have such utility functions?
>>>
>>> Here is an example of a lambda expression with a cast. In context, it's
>>> applied to two type arguments and two dictionary arguments and returns a
>>> function of one more argument. (The function `(-->)` is defined as `(f -->
>>> h) g = h . g . f`.)
>>>
>>> > ((\ (@ a8) (@ b)
>>> > ($dEncodable  :: Encodable a8)
>>> > ($dEncodable1 :: Encodable b) ->
>>> > case $dEncodable of _
>>> >   D:Encodable _ tpl_B3 ->
>>> > case $dEncodable1 of _
>>> >   D:Encodable tpl_B2 _ ->
>>> > \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
>>> eta))
>>> > )
>>> >  `cast` (forall a8 b.
>>> >  _R
>>> >  -> _R
>>> >  ->  b>_R
>>> >  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
>>> >  :: (forall a8 b. (Encodable a8, Encodable b) =>
>>> >  (a8 -> b) -> Encode a8 -> Encode b)
>>> >   ~#
>>> > (forall a8 b. (Encodable a8, Encodable b) =>
>>> >  (a8 -> b) -> Encode (a8 -> b
>>>
>>> I can imagine pushing the `cast` down through the type lambdas while
>>> stripping off `forall` coercions, then pushing the remaining `cast` through
>>> the dictionary arguments, while stripping off the outer `_R
>>> ->` coercion wrappers, and then pushing the cast into the `case`
>>> alternatives and the lambda body, leaving something like
>>>

Re: Simplifying casts and beta-reduction

2014-05-07 Thread Conal Elliott
I'm still sorting through how to optimize these almost-beta-redexes in the
form `((\ x -> u) |> co) v`, shifting coercions to enable beta-reduction
(as described in section 3.1 of "Evidence normalization"). Is it done by
`simplCast` (with help from `simplCoercion`), as called indirectly from
`simplifyExpr` in `SimplCore`? I think I'm now calling `simplifyExpr` from
HERMIT but I'm not getting the cast-shifting I'm looking for.

-- Conal


On Wed, May 7, 2014 at 1:02 PM, Conal Elliott  wrote:

> Very useful, indeed! Exactly what I was looking for. Thanks, Simon. Now
> I've read the evidence normalization and the deferred types paper, and I
> have a much better understanding of what's going on.
>
> -- Conal
>
>
>
> On Wed, May 7, 2014 at 1:28 AM, Simon Peyton Jones 
> wrote:
>
>>  Absolutely. There’s a whole module that does this: OptCoercion.  If you
>> want to see what programs look like without coercion optimisation, try
>> –fno-opt-coercion.
>>
>>
>>
>> The rules are described in our paper *Evidence normalization in System
>> FC: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/
>> <http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/>*
>>
>>
>>
>> I hope that’s useful.
>>
>>
>>
>> Simon
>>
>>
>>
>> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
>> Elliott
>> *Sent:* 07 May 2014 04:50
>> *To:* ghc-devs@haskell.org
>> *Subject:* Simplifying casts and beta-reduction
>>
>>
>>
>> I'm looking for tools to help simplify Core terms that involve casts. In
>> particular, I want to beta-reduce when the function is wrapped with a cast.
>> Do the GHC sources have such utility functions?
>>
>> Here is an example of a lambda expression with a cast. In context, it's
>> applied to two type arguments and two dictionary arguments and returns a
>> function of one more argument. (The function `(-->)` is defined as `(f -->
>> h) g = h . g . f`.)
>>
>> > ((\ (@ a8) (@ b)
>> > ($dEncodable  :: Encodable a8)
>> > ($dEncodable1 :: Encodable b) ->
>> > case $dEncodable of _
>> >   D:Encodable _ tpl_B3 ->
>> > case $dEncodable1 of _
>> >   D:Encodable tpl_B2 _ ->
>> > \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
>> eta))
>> > )
>> >  `cast` (forall a8 b.
>> >  _R
>> >  -> _R
>> >  ->  b>_R
>> >  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
>> >  :: (forall a8 b. (Encodable a8, Encodable b) =>
>> >  (a8 -> b) -> Encode a8 -> Encode b)
>> >   ~#
>> > (forall a8 b. (Encodable a8, Encodable b) =>
>> >  (a8 -> b) -> Encode (a8 -> b
>>
>> I can imagine pushing the `cast` down through the type lambdas while
>> stripping off `forall` coercions, then pushing the remaining `cast` through
>> the dictionary arguments, while stripping off the outer `_R
>> ->` coercion wrappers, and then pushing the cast into the `case`
>> alternatives and the lambda body, leaving something like
>>
>> >  (\ (@ a8) (@ b)
>> > ($dEncodable  :: Encodable a8)
>> > ($dEncodable1 :: Encodable b) ->
>> >  case $dEncodable of _
>> >D:Encodable _ tpl_B3 ->
>> >  case $dEncodable1 of _
>> >D:Encodable tpl_B2 _ ->
>> >  \ (g :: a8 -> b) ->
>> >(\ (eta :: Encode a8) -> tpl_B2 (g (tpl_B3 eta)))
>> >`cast` (Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
>> >:: (Encode a8 -> Encode b)
>> > ~#
>> >   (Encode (a8 -> b
>>
>> Now, given type, dictionary, and function arguments, I think we could
>> beta-reduce.
>>
>> Before I try implementing these transformations, does something like them
>> already exist in GHC?
>>
>> Thanks, -- Conal
>>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Simplifying casts and beta-reduction

2014-05-07 Thread Conal Elliott
Very useful, indeed! Exactly what I was looking for. Thanks, Simon. Now
I've read the evidence normalization and the deferred types paper, and I
have a much better understanding of what's going on.

-- Conal



On Wed, May 7, 2014 at 1:28 AM, Simon Peyton Jones wrote:

>  Absolutely. There’s a whole module that does this: OptCoercion.  If you
> want to see what programs look like without coercion optimisation, try
> –fno-opt-coercion.
>
>
>
> The rules are described in our paper *Evidence normalization in System
> FC: http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/
> <http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/>*
>
>
>
> I hope that’s useful.
>
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 07 May 2014 04:50
> *To:* ghc-devs@haskell.org
> *Subject:* Simplifying casts and beta-reduction
>
>
>
> I'm looking for tools to help simplify Core terms that involve casts. In
> particular, I want to beta-reduce when the function is wrapped with a cast.
> Do the GHC sources have such utility functions?
>
> Here is an example of a lambda expression with a cast. In context, it's
> applied to two type arguments and two dictionary arguments and returns a
> function of one more argument. (The function `(-->)` is defined as `(f -->
> h) g = h . g . f`.)
>
> > ((\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> > case $dEncodable of _
> >   D:Encodable _ tpl_B3 ->
> > case $dEncodable1 of _
> >   D:Encodable tpl_B2 _ ->
> > \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
> eta))
> > )
> >  `cast` (forall a8 b.
> >  _R
> >  -> _R
> >  ->  b>_R
> >  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >  :: (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode a8 -> Encode b)
> >   ~#
> > (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode (a8 -> b
>
> I can imagine pushing the `cast` down through the type lambdas while
> stripping off `forall` coercions, then pushing the remaining `cast` through
> the dictionary arguments, while stripping off the outer `_R
> ->` coercion wrappers, and then pushing the cast into the `case`
> alternatives and the lambda body, leaving something like
>
> >  (\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> >  case $dEncodable of _
> >D:Encodable _ tpl_B3 ->
> >  case $dEncodable1 of _
> >D:Encodable tpl_B2 _ ->
> >  \ (g :: a8 -> b) ->
> >(\ (eta :: Encode a8) -> tpl_B2 (g (tpl_B3 eta)))
> >`cast` (Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >:: (Encode a8 -> Encode b)
> > ~#
> >   (Encode (a8 -> b
>
> Now, given type, dictionary, and function arguments, I think we could
> beta-reduce.
>
> Before I try implementing these transformations, does something like them
> already exist in GHC?
>
> Thanks, -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Simplifying casts and beta-reduction

2014-05-06 Thread Conal Elliott
P.S. Never mind the remark about `(-->)`. I inlined and simplified it away
in the example code.


On Tue, May 6, 2014 at 8:50 PM, Conal Elliott  wrote:

> I'm looking for tools to help simplify Core terms that involve casts. In
> particular, I want to beta-reduce when the function is wrapped with a cast.
> Do the GHC sources have such utility functions?
>
> Here is an example of a lambda expression with a cast. In context, it's
> applied to two type arguments and two dictionary arguments and returns a
> function of one more argument. (The function `(-->)` is defined as `(f -->
> h) g = h . g . f`.)
>
> > ((\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> > case $dEncodable of _
> >   D:Encodable _ tpl_B3 ->
> > case $dEncodable1 of _
> >   D:Encodable tpl_B2 _ ->
> > \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
> eta))
> > )
> >  `cast` (forall a8 b.
> >  _R
> >  -> _R
> >  ->  b>_R
> >  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >  :: (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode a8 -> Encode b)
> >   ~#
> > (forall a8 b. (Encodable a8, Encodable b) =>
> >  (a8 -> b) -> Encode (a8 -> b
>
> I can imagine pushing the `cast` down through the type lambdas while
> stripping off `forall` coercions, then pushing the remaining `cast` through
> the dictionary arguments, while stripping off the outer `_R
> ->` coercion wrappers, and then pushing the cast into the `case`
> alternatives and the lambda body, leaving something like
>
> >  (\ (@ a8) (@ b)
> > ($dEncodable  :: Encodable a8)
> > ($dEncodable1 :: Encodable b) ->
> >  case $dEncodable of _
> >D:Encodable _ tpl_B3 ->
> >  case $dEncodable1 of _
> >D:Encodable tpl_B2 _ ->
> >  \ (g :: a8 -> b) ->
> >(\ (eta :: Encode a8) -> tpl_B2 (g (tpl_B3 eta)))
> >`cast` (Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
> >:: (Encode a8 -> Encode b)
> > ~#
> >   (Encode (a8 -> b
>
> Now, given type, dictionary, and function arguments, I think we could
> beta-reduce.
>
> Before I try implementing these transformations, does something like them
> already exist in GHC?
>
> Thanks, -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Simplifying casts and beta-reduction

2014-05-06 Thread Conal Elliott
I'm looking for tools to help simplify Core terms that involve casts. In
particular, I want to beta-reduce when the function is wrapped with a cast.
Do the GHC sources have such utility functions?

Here is an example of a lambda expression with a cast. In context, it's
applied to two type arguments and two dictionary arguments and returns a
function of one more argument. (The function `(-->)` is defined as `(f -->
h) g = h . g . f`.)

> ((\ (@ a8) (@ b)
> ($dEncodable  :: Encodable a8)
> ($dEncodable1 :: Encodable b) ->
> case $dEncodable of _
>   D:Encodable _ tpl_B3 ->
> case $dEncodable1 of _
>   D:Encodable tpl_B2 _ ->
> \ (g :: a8 -> b) (eta :: Encode a8) -> tpl_B2 (g (tpl_B3
eta))
> )
>  `cast` (forall a8 b.
>  _R
>  -> _R
>  ->  b>_R
>  -> Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
>  :: (forall a8 b. (Encodable a8, Encodable b) =>
>  (a8 -> b) -> Encode a8 -> Encode b)
>   ~#
> (forall a8 b. (Encodable a8, Encodable b) =>
>  (a8 -> b) -> Encode (a8 -> b

I can imagine pushing the `cast` down through the type lambdas while
stripping off `forall` coercions, then pushing the remaining `cast` through
the dictionary arguments, while stripping off the outer `_R
->` coercion wrappers, and then pushing the cast into the `case`
alternatives and the lambda body, leaving something like

>  (\ (@ a8) (@ b)
> ($dEncodable  :: Encodable a8)
> ($dEncodable1 :: Encodable b) ->
>  case $dEncodable of _
>D:Encodable _ tpl_B3 ->
>  case $dEncodable1 of _
>D:Encodable tpl_B2 _ ->
>  \ (g :: a8 -> b) ->
>(\ (eta :: Encode a8) -> tpl_B2 (g (tpl_B3 eta)))
>`cast` (Sub (Sym (TFCo:R:Encode(->)[0] _N _N))
>:: (Encode a8 -> Encode b)
> ~#
>   (Encode (a8 -> b

Now, given type, dictionary, and function arguments, I think we could
beta-reduce.

Before I try implementing these transformations, does something like them
already exist in GHC?

Thanks, -- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


GHC rewrite rules and constructor wrappers?

2014-04-29 Thread Conal Elliott
I'm trying to sort out the relationship of GHC rewrite rules and
constructor wrappers. I have rules like

> "reify/(:<)" reifyEP (:<) = kPrim VecSP

This rule seems to fire for `reifyEP ($W:<)` rather than `reifyEP (:<)`. If
I'm tracking (uncertain), `($W:<)` inlines to `(:<)`. Sometimes I'm able to
preserve the `$W` form, but sometimes I get the bare form when inlining a
definition from another already-compiled module. In those cases, I don't
know how to get my rules to fire.

Advice and explanation appreciated, including pointers explanations of the
role of these wrappers in GHC.

-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Help with cast error

2014-04-24 Thread Conal Elliott
Thanks for the summary and paper pointer! I'll study up.  -- Conal


On Thu, Apr 24, 2014 at 12:58 AM, Simon Peyton Jones
wrote:

>  (a ~ b)  is a *boxed*, *nominal* equality.
>
> (a ~R# b)  is an *unboxed, representational* equality
>
>
>
> So it is rightly rejected.
>
>
> For the boxed/unboxed thing, the paper “practical aspects…” gives more
> detail.
> http://research.microsoft.com/en-us/um/people/simonpj/papers/ext-f/
>
>
>
> I think you already know about the nominal/representational distinction.
>
>
>
> Simon
>
>
>
> *From:* Glasgow-haskell-users [mailto:
> glasgow-haskell-users-boun...@haskell.org] *On Behalf Of *Conal Elliott
> *Sent:* 24 April 2014 01:29
> *To:* glasgow-haskell-us...@haskell.org; ghc-devs@haskell.org; Richard
> Eisenberg; Simon Peyton Jones
> *Subject:* Help with cast error
>
>
>
> I'd appreciate help with a cast-related Core Lint error I'm getting with a
> GHC plugin I'm working on:
>
> Argument value doesn't match argument type:
> Fun type:
> Enc (Vec ('S 'Z) Bool) ~ (Bool, ()) =>
> EP (Enc (Vec ('S 'Z) Bool)) -> EP (Bool, ())
> Arg type:
> ~R# (Enc (Vec ('S 'Z) Bool)) (Bool, ())
> Arg:
> CO Sub (TFCo:R:EncVec[0] <'Z>_N _N)
>; (Sub TFCo:R:EncBool[0], Sub (TFCo:R:EncVec0[0] _N))_R
>
> (I omitted the module prefixes for brevity.) Do I have a role wrong here,
> or maybe something more fundamental?
>
> I can easily supply more info if it'd help.
>
> Thanks, -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Help with cast error

2014-04-23 Thread Conal Elliott
I'd appreciate help with a cast-related Core Lint error I'm getting with a
GHC plugin I'm working on:

Argument value doesn't match argument type:
Fun type:
Enc (Vec ('S 'Z) Bool) ~ (Bool, ()) =>
EP (Enc (Vec ('S 'Z) Bool)) -> EP (Bool, ())
Arg type:
~R# (Enc (Vec ('S 'Z) Bool)) (Bool, ())
Arg:
CO Sub (TFCo:R:EncVec[0] <'Z>_N _N)
   ; (Sub TFCo:R:EncBool[0], Sub (TFCo:R:EncVec0[0] _N))_R

(I omitted the module prefixes for brevity.) Do I have a role wrong here,
or maybe something more fundamental?

I can easily supply more info if it'd help.

Thanks, -- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Help with coercion & roles?

2014-04-14 Thread Conal Elliott
This explanation-with-example is very helpful. Thanks, Richard! I'll noodle
some more. A fairly simple & robust solution may be to add `Cast` to my
expression GADT.

-- Conal


On Mon, Apr 14, 2014 at 2:02 PM, Richard Eisenberg wrote:

> So what do you think? Is there a sound coercion I can build for `co'`?
>
>
> In a word, "no". The problem is that E, as you describe, is a GADT.
> Therefore, it cares exactly which types it is parameterized by. We can see
> this in evidence in the dump, which labels E's second parameter as nominal.
> To draw out the problem, let's look at a simpler example:
>
> > newtype Age = MkAge Int
> > data G a where
> >   MkGInt :: G Int
> >   MkGAge :: G Age
>
> Here, `G` would similarly get a nominal role, because we can't lift
> representational coercions (such as NTCo:Age :: Age ~R Int) through the `G`
> type constructor. If we could, we could then have (MkGAge |> ...) :: G Int,
> which goes against our definition of G -- the only value inhabitant of G
> Int should be MkGInt.
>
> The best you can do here is to try to raise the inner coercion to be
> nominal, by unSubCo_maybe. If that fails, I think you've gone beyond the
> ability of GHC's type system.
>
> Of course, I would like to help you with a way forward -- let me know if
> there's a way I can.
>
> Richard
>
> On Apr 14, 2014, at 4:12 PM, Conal Elliott  wrote:
>
> Hi Richard,
>
> I'm working on compiling Haskell to hardware, as outlined at
> https://github.com/conal/lambda-ccc/blob/master/doc/notes.md (with links
> to a few recent blog posts). The first step is to convert Core into other
> Core that evaluates to a reified form, represented as a type-parametrized
> GADT. This GADT (in `LambdaCCC.Lambda`):
>
> > data E :: (* -> *) -> (* -> *) where ...
>
> The parameter is also type-parametrized, and is for the primitives. I have
> such a type designed for hardware generation (in `LambdaCCC.Prim`)
>
> > data Prim :: * -> * where ...
>
> and then the combination of the two:
>
> > type EP = E Prim
>
> So that's what `EP` is.
>
> With `-ddump-tc`, I get
>
> > TYPE CONSTRUCTORS
> >   ...
> >   E :: (* -> *) -> * -> *
> >   data E ($a::* -> *) $b
> > No C type associated
> > Roles: [representational, nominal]
> > RecFlag NonRecursive, Not promotable
> > = ...
> >   EP :: * -> *
> >   type EP = E Prim
>
> The use of `EP` rather than the more general `E` is only temporary, while
> I'm learning more details of Core (and of HERMIT which I'm using to
> manipulate Core).
>
> I'm now working on reification in the presence of casts. The rule I'm
> trying to implement is
>
> > evalEP e |> co  -->  evalEP (e |> co').
>
> Here, `evalEP :: EP a -> a` and `co :: a ~ b`, so `co' :: EP a ~ EP b`.
>
> I'm trying to build `co'` from `co`, which led to these questions.
>
> So what do you think? Is there a sound coercion I can build for `co'`?
>
> -- Conal
>
>
> On Mon, Apr 14, 2014 at 11:54 AM, Richard Eisenberg wrote:
>
>> Hi Conal,
>>
>> In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the
>> `HasIf` class indeed has a nominal parameter. So, it seems that this part,
>> at least, is OK.
>>
>> What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what
>> you're saying.) If that's the case, you won't be able to pass the result of
>> NTCo:HasIf[0] to a coercion built from EP.
>>
>> Popping up a level, what are you trying to do here? If EP's role is
>> indeed nominal, then I don't believe there's a fix here, as the coercion it
>> seems you're trying to build may be unsound. (It looks to me like you want
>> something proving `EP (Bool -> Bool -> Bool -> Bool) ~R EP (HasIf Bool)`,
>> but if EP's role is nominal, then this is indeed bogus.)
>>
>> Richard
>>
>> On Apr 14, 2014, at 2:23 PM, Conal Elliott  wrote:
>>
>> Thanks for the pointers! I don't quite know how to get to the form you
>> recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
>> _N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
>> the following code:
>>
>> > class HasIf a where
>> >   ifThenElse :: Bool -> a -> a -> a
>> >
>> > instance HasIf Bool where
>> >   ifThenElse i t e = (i && t) || (not i && e)
>>
>> With `--dump-tc`, I see
>>
>> > TYPE SIGNATURES

Re: Help with coercion & roles?

2014-04-14 Thread Conal Elliott
Hi Richard,

I'm working on compiling Haskell to hardware, as outlined at
https://github.com/conal/lambda-ccc/blob/master/doc/notes.md (with links to
a few recent blog posts). The first step is to convert Core into other Core
that evaluates to a reified form, represented as a type-parametrized GADT.
This GADT (in `LambdaCCC.Lambda`):

> data E :: (* -> *) -> (* -> *) where ...

The parameter is also type-parametrized, and is for the primitives. I have
such a type designed for hardware generation (in `LambdaCCC.Prim`)

> data Prim :: * -> * where ...

and then the combination of the two:

> type EP = E Prim

So that's what `EP` is.

With `-ddump-tc`, I get

> TYPE CONSTRUCTORS
>   ...
>   E :: (* -> *) -> * -> *
>   data E ($a::* -> *) $b
> No C type associated
> Roles: [representational, nominal]
> RecFlag NonRecursive, Not promotable
> = ...
>   EP :: * -> *
>   type EP = E Prim

The use of `EP` rather than the more general `E` is only temporary, while
I'm learning more details of Core (and of HERMIT which I'm using to
manipulate Core).

I'm now working on reification in the presence of casts. The rule I'm
trying to implement is

> evalEP e |> co  -->  evalEP (e |> co').

Here, `evalEP :: EP a -> a` and `co :: a ~ b`, so `co' :: EP a ~ EP b`.

I'm trying to build `co'` from `co`, which led to these questions.

So what do you think? Is there a sound coercion I can build for `co'`?

-- Conal


On Mon, Apr 14, 2014 at 11:54 AM, Richard Eisenberg wrote:

> Hi Conal,
>
> In your case, the `_N` on the argument to NTCo:HasIf[0] is correct -- the
> `HasIf` class indeed has a nominal parameter. So, it seems that this part,
> at least, is OK.
>
> What's the -ddump-tc on EP? Is EP's role nominal? (I think so, given what
> you're saying.) If that's the case, you won't be able to pass the result of
> NTCo:HasIf[0] to a coercion built from EP.
>
> Popping up a level, what are you trying to do here? If EP's role is indeed
> nominal, then I don't believe there's a fix here, as the coercion it seems
> you're trying to build may be unsound. (It looks to me like you want
> something proving `EP (Bool -> Bool -> Bool -> Bool) ~R EP (HasIf Bool)`,
> but if EP's role is nominal, then this is indeed bogus.)
>
> Richard
>
> On Apr 14, 2014, at 2:23 PM, Conal Elliott  wrote:
>
> Thanks for the pointers! I don't quite know how to get to the form you
> recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
> _N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
> the following code:
>
> > class HasIf a where
> >   ifThenElse :: Bool -> a -> a -> a
> >
> > instance HasIf Bool where
> >   ifThenElse i t e = (i && t) || (not i && e)
>
> With `--dump-tc`, I see
>
> > TYPE SIGNATURES
> > TYPE CONSTRUCTORS
> >   HasIf :: * -> Constraint
> >   class HasIf a
> > Roles: [nominal]
> > RecFlag NonRecursive
> > ifThenElse :: Bool -> a -> a -> a
> > COERCION AXIOMS
> >   axiom Main.NTCo:HasIf :: HasIf a = Bool -> a -> a -> a
> > INSTANCES
> >   instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10
>
> Do I need to convert the nominal coercion I got from GHC
> (`Simple.NTCo:HasIf[0] _N` in this case) to a
> representational one? If so, how?
> My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to
> apply `mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which
> then produces
>
> > (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] _N)))_R
>
> And still I get "Role incompatibility: expected nominal, got
> representational in `Sym (Simple.NTCo:HasIf[0] _N)`".
>
> I also tried wrapping `mkSubCo` around the entire coercion (applying
> `mkSubCo . mkAppCo (Refl Nominal ep)`), and I see the same result:
>
> > (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] _N)))_R
>
> -- Conal
>
>
>
> On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg wrote:
>
>> I agree with Simon, but just `Sub` the `_N`, not the
>> whole coercion.
>>
>> There are actually two problems here. The one Simon identified, and also
>> the fact that Simple.NTCo:HasIf[0] produces a representational coercion.
>> How do I know? Because of the `NT` -- it's a newtype axiom and must produce
>> representational coercions. Furthermore, unless the newtype definition is
>> inferred to require a nominal parameter, the newtype would expect a
>> representational coercion, not the nominal one you are passing. Check the
>> dump (using -ddump-tc) of the newtype ax

Re: Help with coercion & roles?

2014-04-14 Thread Conal Elliott
Thanks for the pointers! I don't quite know how to get to the form you
recommend from the existing coercion, which is `Simple.NTCo:HasIf[0]
_N`. (Note the `_N`.) I got that coercion in GHC 7.8.2 from
the following code:

> class HasIf a where
>   ifThenElse :: Bool -> a -> a -> a
>
> instance HasIf Bool where
>   ifThenElse i t e = (i && t) || (not i && e)

With `--dump-tc`, I see

> TYPE SIGNATURES
> TYPE CONSTRUCTORS
>   HasIf :: * -> Constraint
>   class HasIf a
> Roles: [nominal]
> RecFlag NonRecursive
> ifThenElse :: Bool -> a -> a -> a
> COERCION AXIOMS
>   axiom Main.NTCo:HasIf :: HasIf a = Bool -> a -> a -> a
> INSTANCES
>   instance HasIf Bool -- Defined at ../test/HasIf.hs:4:10

Do I need to convert the nominal coercion I got from GHC
(`Simple.NTCo:HasIf[0] _N` in this case) to a
representational one? If so, how?
My current formulation (tweaked to use `mkSubCo` and `mkAppCo`) is to apply
`mkAppCo (mkSubCo (Refl Nominal ep))` to the given coercion, which then
produces

> (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] _N)))_R

And still I get "Role incompatibility: expected nominal, got
representational in `Sym (Simple.NTCo:HasIf[0] _N)`".

I also tried wrapping `mkSubCo` around the entire coercion (applying
`mkSubCo . mkAppCo (Refl Nominal ep)`), and I see the same result:

> (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] _N)))_R

-- Conal



On Mon, Apr 14, 2014 at 4:39 AM, Richard Eisenberg wrote:

> I agree with Simon, but just `Sub` the `_N`, not the
> whole coercion.
>
> There are actually two problems here. The one Simon identified, and also
> the fact that Simple.NTCo:HasIf[0] produces a representational coercion.
> How do I know? Because of the `NT` -- it's a newtype axiom and must produce
> representational coercions. Furthermore, unless the newtype definition is
> inferred to require a nominal parameter, the newtype would expect a
> representational coercion, not the nominal one you are passing. Check the
> dump (using -ddump-tc) of the newtype axiom to be sure.
>
> Though putting a `Sub` on `` and changing the Refl constructor on
> `` would work, you would then be violating an invariant of GHC's
> Coercion type: that we prefer `TyConAppCo tc ...` over `AppCo (Refl
> (TyConApp tc [])) ...`.
>
> In sum, here is the coercion I think you want:
>
> (LambdaCCC.Lambda.EP (Sym (Simple.NTCo:HasIf[0] _R)))_R
>
> This is one of the problems with roles -- they are *very* fiddly within
> GHC, and it's hard for a non-expert in roles to get them right.
>
> Have you seen docs/core-spec/core-spec.pdf? That is updated w.r.t. roles
> and may be of help.
>
> Let me know if I can help further!
> Richard
>
> On Apr 14, 2014, at 5:45 AM, Simon Peyton Jones 
> wrote:
>
> I think you need a ‘Sub’.
>
> A cast  (e `cast` g) requires a representational coercion.  I think you
> have given it a (stronger) nominal one.  Sub gets from one to t’other.
>
> Simon
>
>  *From:* Glasgow-haskell-users [mailto:glasgow-
> haskell-users-boun...@haskell.org] *On Behalf Of *Conal Elliott
> *Sent:* 14 April 2014 06:00
> *To:* ghc-devs@haskell.org; glasgow-haskell-us...@haskell.org
> *Subject:* Help with coercion & roles?
>
>
> I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and
> running into trouble with coercions & roles. Error message from Core Lint:
>
> Warning: In the expression:
>
>
>
>   LambdaCCC.Lambda.lamvP#
>
> @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
>
> @ (Simple.HasIf GHC.Types.Bool)
>
> "tpl"#
>
> ((LambdaCCC.Lambda.varP#
>
> @ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
>
> "tpl"#)
>
>  `cast` (_N (Sym (Simple.NTCo:HasIf[0] 
> _N))
>
>  ∷ LambdaCCC.Lambda.EP
>
>   (GHC.Types.Bool
>
>→ GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
>
>   ~#
>
> LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))
>
>  Role incompatibility: expected nominal, got representational
>
> in _N (Sym (Simple.NTCo:HasIf[0] _N))
>
> Do you see anything inconsistent/incompatible in the coercions or roles
> above? I constructed the nominal EP Refl coercion, and applied it (AppCo)
> an existing coercion of a simpler type.
>
> Thanks,
> -- Conal
> ___
> Glasgow-haskell-users mailing list
> glasgow-haskell-us...@haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Help with coercion & roles?

2014-04-13 Thread Conal Elliott
I’m working on a GHC plugin (as part of my Haskell-to-hardware work) and
running into trouble with coercions & roles. Error message from Core Lint:

Warning: In the expression:

  LambdaCCC.Lambda.lamvP#
@ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
@ (Simple.HasIf GHC.Types.Bool)
"tpl"#
((LambdaCCC.Lambda.varP#
@ (GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
"tpl"#)
 `cast` (_N (Sym (Simple.NTCo:HasIf[0]
_N))
 ∷ LambdaCCC.Lambda.EP
  (GHC.Types.Bool
   → GHC.Types.Bool → GHC.Types.Bool → GHC.Types.Bool)
  ~#
LambdaCCC.Lambda.EP (Simple.HasIf GHC.Types.Bool)))
 Role incompatibility: expected nominal, got representationalin
_N (Sym (Simple.NTCo:HasIf[0]
_N))

Do you see anything inconsistent/incompatible in the coercions or roles
above? I constructed the nominal EP Refl coercion, and applied it (AppCo)
an existing coercion of a simpler type.

Thanks,
-- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Finding & assembling class dictionaries from GHC plugins?

2013-11-12 Thread Conal Elliott
Hi Simon. Yes, I'd appreciate such a call, with at least one of the HERMIT
folks in the conversation as well. They'll be implementing whatever we come
up with as an improvement to HERMIT, and I'll be using the result. I'll
follow up about choosing a time that works for all.  -- Conal






On Mon, Nov 11, 2013 at 1:49 PM, Simon Peyton-Jones
wrote:

>  Conal
>
>
>
> Email is not good for this.  I think it’d be more productive to have a
> Skype call, with both of use looking at GHC’s source code.
>
>
>
> If you’d like to do that, do suggest a time.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 07 November 2013 18:15
>
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> On Wed, Nov 6, 2013 at 11:44 PM, Simon Peyton-Jones 
> wrote:
>
>  Well, you are writing a function
>
> reify :: CoreExpr -> HsExpr RdrName
>
>
> Not exactly. I'm reifying CoreExpr directly to another CoreExpr. (The
> target CoreExpr calls into an API for GADT-typed lambda 
> terms<https://github.com/conal/lambda-ccc/blob/master/src/LambdaCCC/Lambda.hs>.
> All works swimmingly as long as I'm able to avoid dictionary construction,
> but I'm no longer able to do so.) I haven't explored your suggestion of
> translating to HsExpr instead. Do you know of any plugins that work this
> way? Do you really believe it would work out? For instance, I wouldn't know
> where to insert type annotations, and I'd have to back-translate names. I
> imagine there are other challenges I don't foresee.
>
>
>  It takes as its input a CoreExpr and produces as its output a
> reification of the input.  I don’t see why you need start by converting
> Core to HsExpr. Just write reify directly!
>
>
>
> I wasn't suggesting converting a CoreExpr to an HsExpr. Rather, I was
> wondering out loud how I might get the type-checker's help to generate Core
> to find/assemble a Typeable dictionary for a given Core type (since I'm
> starting with Core). One idea is translate the core type cty to an HsType
> hty, use hty in a very simple HsExpr like "Dict :: Dict hty" (where Dict is
> from Ed K's constraints package), use the typechecker to convert that
> simple HsExpr to a CoreExpr, and then extract the dictionary-forming
> sub-CoreExpr. Or something simpler along the same lines.
>
> Thanks for the help,
>
> -- Conal
>
>
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 07 November 2013 01:08
>
>
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> Thanks for the suggestion. I hadn't considered backing up to an HsExpr. I
> guess we'd have to start by converting the Core Type to an HsType to form a
> type-annotated HsExpr. Am I on the right track here?
>
> -- Conal
>
>
>
> On Wed, Nov 6, 2013 at 5:59 AM, Simon Peyton-Jones 
> wrote:
>
>  Hmm. One route would be to build a HsExpr (rather than a CoreExpr) for
> the reification of your CoreExpr, and stick that into the maw of the type
> checker.  That would hand off all this dictionary construction to the type
> checker, which is designed for the purpose.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 05 November 2013 23:41
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> Hi Simon,
>
> Here's some context on what I'm after. I'll try to include enough to
> clarify what I'm after, without dragging you into unnecessary detail.
>
> I have a Core expression, which I'm systematically translating to a
> related Core expression. The second one reifies the first one, so that the
> generated code *evaluates* to a run-time (not compile/Core-time)
> representation akin to the original Core expression. In this second
> (reified) representation, I need some run-time representation of types. I
> use Typeable constraints in my representation, and these constraints don't
> appear in the original Core representation. For instance, I have the
> following constructor for function application in a GADT of lambda
> expressions:
>
> > (:^) :: (Typeable a, Typeable b) =

Re: Things stopping pure Haskell code from having a cross-platform single semantics?

2013-11-11 Thread Conal Elliott
For a few more such leaks, see
http://hackage.haskell.org/package/base-4.6.0.1/docs/System-Info.html , as
mentioned in http://conal.net/blog/posts/notions-of-purity-in-haskell .  --
Conal


On Mon, Nov 11, 2013 at 7:01 AM, Ryan Newton  wrote:

> Haskell isn't like Java byte code in having a single semantics for a
> program irrespective of where it is run.  In particular, "Int" has a
> platform-defined width -- so the same (pure) code can yield different
> answers on different machines.
>
> numCapabilities was also a "leak" of platform information, which did not
> require IO. But, happily, now it does not appear in the [Trustworthy]
> module, Control.Concurrent.
>
> Ok, what else?  What other holes are there that allow my pure functions to
> change their answer on different machines?  I'm making a list of these in a
> paper and I want to make sure I give a full account.
>
> Thanks,
>   -Ryan
>
>
> ___
> ghc-devs mailing list
> ghc-devs@haskell.org
> http://www.haskell.org/mailman/listinfo/ghc-devs
>
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Finding & assembling class dictionaries from GHC plugins?

2013-11-07 Thread Conal Elliott
On Wed, Nov 6, 2013 at 11:44 PM, Simon Peyton-Jones
wrote:

>  Well, you are writing a function
>
> reify :: CoreExpr -> HsExpr RdrName
>
>
Not exactly. I'm reifying CoreExpr directly to another CoreExpr. (The
target CoreExpr calls into an API for GADT-typed lambda
terms<https://github.com/conal/lambda-ccc/blob/master/src/LambdaCCC/Lambda.hs>.
All works swimmingly as long as I'm able to avoid dictionary construction,
but I'm no longer able to do so.) I haven't explored your suggestion of
translating to HsExpr instead. Do you know of any plugins that work this
way? Do you really believe it would work out? For instance, I wouldn't know
where to insert type annotations, and I'd have to back-translate names. I
imagine there are other challenges I don't foresee.


> It takes as its input a CoreExpr and produces as its output a reification
> of the input.  I don’t see why you need start by converting Core to HsExpr.
> Just write reify directly!
>

I wasn't suggesting converting a CoreExpr to an HsExpr. Rather, I was
wondering out loud how I might get the type-checker's help to generate Core
to find/assemble a Typeable dictionary for a given Core type (since I'm
starting with Core). One idea is translate the core type cty to an HsType
hty, use hty in a very simple HsExpr like "Dict :: Dict hty" (where Dict is
from Ed K's constraints package), use the typechecker to convert that
simple HsExpr to a CoreExpr, and then extract the dictionary-forming
sub-CoreExpr. Or something simpler along the same lines.

Thanks for the help,

-- Conal


>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 07 November 2013 01:08
>
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> Thanks for the suggestion. I hadn't considered backing up to an HsExpr. I
> guess we'd have to start by converting the Core Type to an HsType to form a
> type-annotated HsExpr. Am I on the right track here?
>
> -- Conal
>
>
>
> On Wed, Nov 6, 2013 at 5:59 AM, Simon Peyton-Jones 
> wrote:
>
>  Hmm. One route would be to build a HsExpr (rather than a CoreExpr) for
> the reification of your CoreExpr, and stick that into the maw of the type
> checker.  That would hand off all this dictionary construction to the type
> checker, which is designed for the purpose.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 05 November 2013 23:41
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> Hi Simon,
>
> Here's some context on what I'm after. I'll try to include enough to
> clarify what I'm after, without dragging you into unnecessary detail.
>
> I have a Core expression, which I'm systematically translating to a
> related Core expression. The second one reifies the first one, so that the
> generated code *evaluates* to a run-time (not compile/Core-time)
> representation akin to the original Core expression. In this second
> (reified) representation, I need some run-time representation of types. I
> use Typeable constraints in my representation, and these constraints don't
> appear in the original Core representation. For instance, I have the
> following constructor for function application in a GADT of lambda
> expressions:
>
> > (:^) :: (Typeable a, Typeable b) => E (a -> b) -> E a -> E b
>
> My reification plugin takes a Core application expression, recursively
> reifies the function and argument expressions, and makes an expression that
> applies (:^) to the two recursive results. However--and the point of this
> thread--I also need to come up with Core expressions for the two Typeable
> dictionaries.
>
> So, to clarify my request, given a Core type representation t, I want to
> construct a Core expression that evaluates to the dictionary for Typeable t
> if one exists, or fail if there isn't one. Note that t is not necessarily
> an atomic type; it could instead be something like [(Bool,Int -> String)].
>
> I'm happy to Skype-chat if it'd help.
>
> Thanks,  - Conal
>
>
>
>
>
> On Tue, Nov 5, 2013 at 2:37 PM, Simon Peyton-Jones 
> wrote:
>
>   We just don't know how to start — ie how call the right functions from
> the type checker. Are there any resources explaining the relevant subset of
> the TcRnIf API?
>
> And I for my part don’t know where 

Re: Finding & assembling class dictionaries from GHC plugins?

2013-11-06 Thread Conal Elliott
Thanks for the suggestion. I hadn't considered backing up to an HsExpr. I
guess we'd have to start by converting the Core Type to an HsType to form a
type-annotated HsExpr. Am I on the right track here?

-- Conal


On Wed, Nov 6, 2013 at 5:59 AM, Simon Peyton-Jones wrote:

>  Hmm. One route would be to build a HsExpr (rather than a CoreExpr) for
> the reification of your CoreExpr, and stick that into the maw of the type
> checker.  That would hand off all this dictionary construction to the type
> checker, which is designed for the purpose.
>
>
>
> Simon
>
>
>
> *From:* conal.elli...@gmail.com [mailto:conal.elli...@gmail.com] *On
> Behalf Of *Conal Elliott
> *Sent:* 05 November 2013 23:41
> *To:* Simon Peyton-Jones
> *Cc:* Nicolas Frisby; ghc-devs@haskell.org
> *Subject:* Re: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> Hi Simon,
>
> Here's some context on what I'm after. I'll try to include enough to
> clarify what I'm after, without dragging you into unnecessary detail.
>
> I have a Core expression, which I'm systematically translating to a
> related Core expression. The second one reifies the first one, so that the
> generated code *evaluates* to a run-time (not compile/Core-time)
> representation akin to the original Core expression. In this second
> (reified) representation, I need some run-time representation of types. I
> use Typeable constraints in my representation, and these constraints don't
> appear in the original Core representation. For instance, I have the
> following constructor for function application in a GADT of lambda
> expressions:
>
> > (:^) :: (Typeable a, Typeable b) => E (a -> b) -> E a -> E b
>
> My reification plugin takes a Core application expression, recursively
> reifies the function and argument expressions, and makes an expression that
> applies (:^) to the two recursive results. However--and the point of this
> thread--I also need to come up with Core expressions for the two Typeable
> dictionaries.
>
> So, to clarify my request, given a Core type representation t, I want to
> construct a Core expression that evaluates to the dictionary for Typeable t
> if one exists, or fail if there isn't one. Note that t is not necessarily
> an atomic type; it could instead be something like [(Bool,Int -> String)].
>
> I'm happy to Skype-chat if it'd help.
>
> Thanks,  - Conal
>
>
>
>
>
> On Tue, Nov 5, 2013 at 2:37 PM, Simon Peyton-Jones 
> wrote:
>
>   We just don't know how to start — ie how call the right functions from
> the type checker. Are there any resources explaining the relevant subset of
> the TcRnIf API?
>
> And I for my part don’t know where to start helping you!  Conal wrote
>
>
>
> I don't think I need to construct dictionaries for new Typeable instances.
> I only need to find and assemble *existing* Typeable instances into
> combinations like Typeable [(Bool,Int -> String)], and I don't know how to
> do so in a GHC plug-in
>
>
>
> That’s exactly what the constraint solver does.  (TcSimplify and
> friends.)  But again I need more context.
>
>
>
> I gather you are talking to Pedro too?  He knows a lot about this stuff.
>
>
>
> Also there are a bunch of folk (Luite, Edsko) worked on the new front-end
> plugin stuff, and are much more expert in it than me.
>
>
>
> We could have a skype call if that would help
>
>
>
> S
>
>
>
>
>
> *From:* Nicolas Frisby [mailto:nicolas.fri...@gmail.com]
> *Sent:* 05 November 2013 14:36
> *To:* Simon Peyton-Jones
> *Cc:* ghc-devs@haskell.org; Conal Elliott
> *Subject:* RE: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> On Nov 5, 2013 3:14 AM, "Simon Peyton-Jones" 
> wrote:
>
> >
> > A core-level plug-in can’t generate fresh instances.  There are some new
> plug-in hooks that fit earlier in the pipeline, which can.  Maybe you can
> use that, and generate a data type decl with “deriving Typeable”?
>
> We're willing to do some awkward shoehorning in HERMIT to make this work
> in limited circumstances. (Hopefully including Conal's.)
>
> We just don't know how to start — ie how call the right functions from the
> type checker. Are there any resources explaining the relevant subset of the
> TcRnIf API?
>
> Thanks.
>
> >
> >
> > From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Conal
> Elliott
> > Sent: 04 November 2013 20:08
> > To: ghc-devs@haskell.org
> > Subject: Finding & assembling clas

Re: Finding & assembling class dictionaries from GHC plugins?

2013-11-05 Thread Conal Elliott
Hi Simon,

Here's some context on what I'm after. I'll try to include enough to
clarify what I'm after, without dragging you into unnecessary detail.

I have a Core expression, which I'm systematically translating to a related
Core expression. The second one reifies the first one, so that the
generated code *evaluates* to a run-time (not compile/Core-time)
representation akin to the original Core expression. In this second
(reified) representation, I need some run-time representation of types. I
use Typeable constraints in my representation, and these constraints don't
appear in the original Core representation. For instance, I have the
following constructor for function application in a GADT of lambda
expressions:

> (:^) :: (Typeable a, Typeable b) => E (a -> b) -> E a -> E b

My reification plugin takes a Core application expression, recursively
reifies the function and argument expressions, and makes an expression that
applies (:^) to the two recursive results. However--and the point of this
thread--I also need to come up with Core expressions for the two Typeable
dictionaries.

So, to clarify my request, given a Core type representation t, I want to
construct a Core expression that evaluates to the dictionary for Typeable t
if one exists, or fail if there isn't one. Note that t is not necessarily
an atomic type; it could instead be something like [(Bool,Int -> String)].

I'm happy to Skype-chat if it'd help.

Thanks,  - Conal



On Tue, Nov 5, 2013 at 2:37 PM, Simon Peyton-Jones wrote:

>  We just don't know how to start — ie how call the right functions from
> the type checker. Are there any resources explaining the relevant subset of
> the TcRnIf API?
>
> And I for my part don’t know where to start helping you!  Conal wrote
>
>
>
> I don't think I need to construct dictionaries for new Typeable instances.
> I only need to find and assemble *existing* Typeable instances into
> combinations like Typeable [(Bool,Int -> String)], and I don't know how to
> do so in a GHC plug-in
>
>
>
> That’s exactly what the constraint solver does.  (TcSimplify and
> friends.)  But again I need more context.
>
>
>
> I gather you are talking to Pedro too?  He knows a lot about this stuff.
>
>
>
> Also there are a bunch of folk (Luite, Edsko) worked on the new front-end
> plugin stuff, and are much more expert in it than me.
>
>
>
> We could have a skype call if that would help
>
>
>
> S
>
>
>
>
>
> *From:* Nicolas Frisby [mailto:nicolas.fri...@gmail.com]
> *Sent:* 05 November 2013 14:36
> *To:* Simon Peyton-Jones
> *Cc:* ghc-devs@haskell.org; Conal Elliott
> *Subject:* RE: Finding & assembling class dictionaries from GHC plugins?
>
>
>
> On Nov 5, 2013 3:14 AM, "Simon Peyton-Jones" 
> wrote:
>
> >
> > A core-level plug-in can’t generate fresh instances.  There are some new
> plug-in hooks that fit earlier in the pipeline, which can.  Maybe you can
> use that, and generate a data type decl with “deriving Typeable”?
>
> We're willing to do some awkward shoehorning in HERMIT to make this work
> in limited circumstances. (Hopefully including Conal's.)
>
> We just don't know how to start — ie how call the right functions from the
> type checker. Are there any resources explaining the relevant subset of the
> TcRnIf API?
>
> Thanks.
>
> >
> >
> > From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Conal
> Elliott
> > Sent: 04 November 2013 20:08
> > To: ghc-devs@haskell.org
> > Subject: Finding & assembling class dictionaries from GHC plugins?
> >
> >
> >
> > I'm working on a GHC plugin (for compiling Haskell to hardware), and I
> need to synthesize Typeable (and maybe other) class dictionaries for a wide
> range of types, including composite types (functions, pairs, lists, etc).
> Can it be done, and how? I think I'm mainly looking for mechanics of
> finding existing class instances (however they're defined) and assembling
> them (for parametrized/composite dictionaries), rather than mechanisms
> specific to Typeable.
> >
> > Thanks, -- Conal
> >
> >
> > ___
> > ghc-devs mailing list
> > ghc-devs@haskell.org
> > http://www.haskell.org/mailman/listinfo/ghc-devs
> >
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: Finding & assembling class dictionaries from GHC plugins?

2013-11-05 Thread Conal Elliott
Hi Simon,

I don't think I need to construct dictionaries for new Typeable instances.
I only need to find and assemble *existing* Typeable instances into
combinations like Typeable [(Bool,Int -> String)], and I don't know how to
do so in a GHC plug-in. Pointers greatly appreciated!

-- Conal


On Tue, Nov 5, 2013 at 1:13 AM, Simon Peyton-Jones wrote:

>  I’m not sure what you mean by “synthesise”.
>
>
>
> Typeable instances can no longer be hand-written; they must be derived by
> GHC.  That’s to keep them type-secure.
>
>
>
> A core-level plug-in can’t generate fresh instances.  There are some new
> plug-in hooks that fit earlier in the pipeline, which can.  Maybe you can
> use that, and generate a data type decl with “deriving Typeable”?
>
>
> Simon
>
>
>
> *From:* ghc-devs [mailto:ghc-devs-boun...@haskell.org] *On Behalf Of *Conal
> Elliott
> *Sent:* 04 November 2013 20:08
> *To:* ghc-devs@haskell.org
> *Subject:* Finding & assembling class dictionaries from GHC plugins?
>
>
>
> I'm working on a GHC plugin (for compiling Haskell to hardware), and I
> need to synthesize Typeable (and maybe other) class dictionaries for a wide
> range of types, including composite types (functions, pairs, lists, etc).
> Can it be done, and how? I think I'm mainly looking for mechanics of
> finding existing class instances (however they're defined) and assembling
> them (for parametrized/composite dictionaries), rather than mechanisms
> specific to Typeable.
>
> Thanks, -- Conal
>
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Finding & assembling class dictionaries from GHC plugins?

2013-11-04 Thread Conal Elliott
I'm working on a GHC plugin (for compiling Haskell to hardware), and I need
to synthesize Typeable (and maybe other) class dictionaries for a wide
range of types, including composite types (functions, pairs, lists, etc).
Can it be done, and how? I think I'm mainly looking for mechanics of
finding existing class instances (however they're defined) and assembling
them (for parametrized/composite dictionaries), rather than mechanisms
specific to Typeable.

Thanks, -- Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs


Re: [Haskell-cafe] Poll & plea: State of GUI & graphics libraries in Haskell

2013-10-02 Thread Conal Elliott
Hi Paul. Is there a way to use GLFW with GUI elements other than OpenGL
display windows, e.g., text boxes and sliders?  -- Conal


On Tue, Oct 1, 2013 at 11:23 PM, Paul Liu  wrote:

> Thanks. I've just built GHC HEAD on Mac OS X Lion, and tested by
> installing libraries with --enable-shared and loading a GLFW program
> into GHCi. Using ghci -fno-ghci-sandbox, everything works great
> including closing and restarting GL window multiple times. Can't wait
> for the  official release of GHC 7.8!
>
> On Tue, Oct 1, 2013 at 12:09 PM, Carter Schonwald
>  wrote:
> > thats the linker bug.
> >
> > the glfw stuff has been tested on ghc HEAD / 7.7 by folks on
> #haskell-game
> > in recent memory. GHCI + foreign libs should work fine now (modulo thread
> > local storage related thing).
> >
> > the historical element doesn't matter any more.
> >
> > To the best of my knowledge, all such issues should be gone. Anyone who
> > cares about making sure GHCI+ gui libs play nice, PLEASE test with HEAD.
> >
> > the better this issue is properly tested (which i believe it has been),
> the
> > more we can actually prevent it from happening. This requires people to
> test
> > with HEAD GHCi now, rather than doing archaeology.
> >
> > anyone who cares, please play with GHCI in HEAD. If your lib doesn't work
> > with ghci, please report a bug. It would be a new bug because it wont' be
> > the previous reasons it hasnt' worked.
> >
> >
> > tl;dr to the best of my knowledge this issue is resolved in HEAD. Test
> HEAD.
> > Help us make sure it stays resolved by testing HEAD.
> >
> > thanks
> > -Carter
> >
> >
> >
> >
> > On Tue, Oct 1, 2013 at 1:20 PM, Paul Liu  wrote:
> >>
> >> I reported a problem with statically linked GLFW library on Mac OS X
> >> Lion in this thread:
> >>
> >> http://www.haskell.org/pipermail/haskell-cafe/2012-January/097355.html
> >>
> >> I do not know why this is broken on Mac OS X Lion, but not on Linux or
> >> Windows. There was an EnableGUI hack for GHC 7.2 (and previous
> >> versions) and OS X version before Lion, but it no longer works. So I'm
> >> not sure if it is OS X Lion, or GLFW, or GHC, or a combination of them
> >> that caused this problem.
> >>
> >> Regards,
> >> Paul Liu
> >>
> >> On Tue, Oct 1, 2013 at 7:04 AM, Carter Schonwald
> >>  wrote:
> >> > Hey simon, the two issues that have recurrently bit ghci interaction
> >> > with
> >> > foreign GUI libs are
> >> > 1) the ghci linker.  This is fixed in head by now having ghci use the
> >> > system
> >> > linker
> >> > 2) some GUI libs require thread local state, and ghci has a flag for
> >> > that
> >> > 3)  I'm not aware of anyone reporting newly broken libs wrt GUI
> bindings
> >> > when 7.6 rolled out.  The only fix that's relevant to 7.8 is the
> >> > dylinker
> >> > bit, but that would have been a problem historically too.
> >> >
> >> > I believe a number of folks in #haskell-game have recently tested
> point
> >> > one.
> >> > (Though I should ask to double check)
> >> >
> >> > At the very least, I'm not aware of hearing of such a 7.6 specific
> ghci
> >> > breakage before.
> >> >
> >> >
> >> > On Tuesday, October 1, 2013, Simon Peyton-Jones wrote:
> >> >>
> >> >> Dear GHC devs
> >> >>
> >> >>
> >> >>
> >> >> See below (in red).  I do not know the details of this, but it sounds
> >> >> like
> >> >> a pretty serious problem, and it used to work.  Is whatever-it-is
> >> >> confirmed
> >> >> fixed in 7.8?  Do we have a test that’ll trip if it breaks again?
>  (I’m
> >> >> guessing that the latter might be hard.)
> >> >>
> >> >>
> >> >>
> >> >> Thanks
> >> >>
> >> >>
> >> >>
> >> >> Simon
> >> >>
> >> >>
> >> >>
> >> >> -Original Message-
> >> >> From: Haskell-Cafe [mailto:haskell-cafe-boun...@haskell.org] On
> Behalf
> >> >> Of
> >> >> Paul Liu
> >> >> Sent: 30 September 2013 07:18
> >> >> To: Conal Elliott
> >> >> Cc: Haske

Module import and use in GHC plugin?

2013-05-29 Thread Conal Elliott
In writing GHC plugins, how can I (a) add a module import (preferably
qualified) and (b) make vars/ids for names imported from the newly imported
module (to insert in the transformed Core code)?

If it's not possible to do what I want, I'd be willing to require an
explicit import (say "import qualified Foo") in client code, as a temporary
workaround.
So far I've been unable to import even from the base package. Maybe I'm
missing something basic that you folks have learned.

My simple & unsuccessful attempt is at
https://github.com/conal/plugin-import-id . Help greatly appreciated.

Thanks,

  - Conal
___
ghc-devs mailing list
ghc-devs@haskell.org
http://www.haskell.org/mailman/listinfo/ghc-devs