Re: Understanding UniqSupply

2018-07-23 Thread Sebastian Graf
Hi Simon,

>
>1. Judging from SimplCore, we probably want to `splitUniqSupply` after
>each iteration/transformation, either through a call to `splitUniqSupply`
>or `getUniqueSupplyM`. Is that right?
>
> I don’t understand the question.   If you use the same supply twice,
> you’ll get (precisely) the same uniques.  That may or may not be ok


I guess this was wrt. threading UniqSupply through each transformation vs.
splitting it before a transformation. We want to split or to thread,
otherwise we possibly re-use some Uniques, because it's a regular purely
functional data structure, as you noted. Each transformation will do its
own splitting/taking after that, so my question was probably bogus to begin
with.

Thanks, that cleared up a lot of things for me!


Am Mo., 23. Juli 2018 um 14:21 Uhr schrieb Simon Peyton Jones <
simo...@microsoft.com>:

> Some quick responses
>
>
>
> 1. *Splitting*
>
> What's the need for splitting anyway?
>
>
>
> Just so you can use uniques in a tree-like way, without threading the
> supply around.  No more than that.
>
>
>
> This is not needed everywhere.  For example, the Simplifier threads it
> thus:
>
>
>
> newtype SimplM result
>
>   =  SM  { unSM :: SimplTopEnv  -- Envt that does not change much
>
> -> UniqSupply   -- We thread the unique supply because
>
> -- constantly splitting it is rather
> expensive
>
> -> SimplCount
>
> -> IO (result, UniqSupply, SimplCount)}
>
>
>
> I suspect that (now that SimplM is in IO anyway) we could use an IORef
> instead, and maybe speed up the compiler.
>
>
>
> But perhaps not all uses are so simple to change.
>
>
>
> 2. *The* *tree*
>
>
>
> The crucial thing is that there /is/ a data structure – a tree, that is
> the unique supply. So if you have
>
>  f u s = ….(splitUniqueSupply us)…..(splitUniqueSupply us)….
>
> you’ll get the same trees in the two calls.  The supply is just a
> purely-functional tree.
>
>
>
> So, for example
>
>- The `unsafeInterleaveIO` makes it so that `genSym` is actually
>forced before any of the recursive calls to `mk_split` force their
>`genSym`, regardless of evaluation order
>
> I don’t think this is important, except perhaps to avoid creating a thunk.
>
>- This guarentees a certain partial order on produced uniques: Any
>parent `UniqSupply`'s `Unique` is calculated by a call to
>compiler/cbits/genSym.c#genSym() before any `Unique`s of its offsprings 
> are]
>- The order of `Unique`s on different off-springs of the same
>`UniqSupply` is determined by evaluation order as a result of
>`unsafeInterleaveIO`, much the same as when we create two different
>`UniqSupply`s by calls to `mkSplitUniqSupply`
>- So, `unfoldr (Just . takeUniqFromSupply) us) !! n` is always
>deterministic and strictly monotone, in the sense that even forcing the
>expression for n=2 before n=1 will have a lower `Unique` for n=1 than for
>n=2.
>
> I don’t think any of these points are important or relied on.  A different
> impl could behave differently.
>
>1. `takeUniqSupply` returns as 'tail' its first off-spring, whereas
>`uniqsFromSupply` always recurses into its second off-spring. By my
>intuition above, this shouldn't really make much of a difference, so what
>is the motivation for that?
>
> I think this is unimportant. I.e. it should be fine to change it.
>
>
>
>1. Judging from SimplCore, we probably want to `splitUniqSupply` after
>each iteration/transformation, either through a call to `splitUniqSupply`
>or `getUniqueSupplyM`. Is that right?
>
> I don’t understand the question.   If you use the same supply twice,
> you’ll get (precisely) the same uniques.  That may or may not be ok
>
>
>
> SImon
>
>
>
> *From:* ghc-devs  *On Behalf Of *Sebastian
> Graf
> *Sent:* 23 July 2018 12:06
> *To:* ghc-devs 
> *Subject:* Understanding UniqSupply
>
>
>
> Hi all,
>
>
>
> I'm trying to understand when it is necessary to `splitUniqSupply`, or
> even to create my own supply with `mkSplitUniqSupply`.
>
>
>
> First, my understanding of how `mkSplitUniqSupply` (
> https://hackage.haskell.org/package/ghc-8.4.1/docs/src/UniqSupply.html#mkSplitUniqSupply
> )
> works is as follows:
>
>- The `unsafeInterleaveIO` makes it so that `genSym` is actually
>forced before any of the recursive calls to `mk_split` force their
>`genSym`, regardless of evaluation order
>- This guarentees a certain partial order on produced uniques: Any
>parent `UniqSupply`'s `Unique` is calculated by a call to
>compiler/cbits/genSym.c#genSym() 

RE: Understanding UniqSupply

2018-07-23 Thread Simon Peyton Jones via ghc-devs
Some quick responses

1. Splitting
What's the need for splitting anyway?

Just so you can use uniques in a tree-like way, without threading the supply 
around.  No more than that.

This is not needed everywhere.  For example, the Simplifier threads it thus:


newtype SimplM result

  =  SM  { unSM :: SimplTopEnv  -- Envt that does not change much

-> UniqSupply   -- We thread the unique supply because

-- constantly splitting it is rather expensive

-> SimplCount

-> IO (result, UniqSupply, SimplCount)}

I suspect that (now that SimplM is in IO anyway) we could use an IORef instead, 
and maybe speed up the compiler.

But perhaps not all uses are so simple to change.

2. The tree

The crucial thing is that there /is/ a data structure – a tree, that is the 
unique supply. So if you have
 f u s = ….(splitUniqueSupply us)…..(splitUniqueSupply us)….
you’ll get the same trees in the two calls.  The supply is just a 
purely-functional tree.

So, for example

  *   The `unsafeInterleaveIO` makes it so that `genSym` is actually forced 
before any of the recursive calls to `mk_split` force their `genSym`, 
regardless of evaluation order
I don’t think this is important, except perhaps to avoid creating a thunk.

  *   This guarentees a certain partial order on produced uniques: Any parent 
`UniqSupply`'s `Unique` is calculated by a call to 
compiler/cbits/genSym.c#genSym() before any `Unique`s of its offsprings are]
  *   The order of `Unique`s on different off-springs of the same `UniqSupply` 
is determined by evaluation order as a result of `unsafeInterleaveIO`, much the 
same as when we create two different `UniqSupply`s by calls to 
`mkSplitUniqSupply`
  *   So, `unfoldr (Just . takeUniqFromSupply) us) !! n` is always 
deterministic and strictly monotone, in the sense that even forcing the 
expression for n=2 before n=1 will have a lower `Unique` for n=1 than for n=2.
I don’t think any of these points are important or relied on.  A different impl 
could behave differently.

  1.  `takeUniqSupply` returns as 'tail' its first off-spring, whereas 
`uniqsFromSupply` always recurses into its second off-spring. By my intuition 
above, this shouldn't really make much of a difference, so what is the 
motivation for that?
I think this is unimportant. I.e. it should be fine to change it.


  1.  Judging from SimplCore, we probably want to `splitUniqSupply` after each 
iteration/transformation, either through a call to `splitUniqSupply` or 
`getUniqueSupplyM`. Is that right?
I don’t understand the question.   If you use the same supply twice, you’ll get 
(precisely) the same uniques.  That may or may not be ok

SImon

From: ghc-devs  On Behalf Of Sebastian Graf
Sent: 23 July 2018 12:06
To: ghc-devs 
Subject: Understanding UniqSupply

Hi all,

I'm trying to understand when it is necessary to `splitUniqSupply`, or even to 
create my own supply with `mkSplitUniqSupply`.

First, my understanding of how `mkSplitUniqSupply` 
(https://hackage.haskell.org/package/ghc-8.4.1/docs/src/UniqSupply.html#mkSplitUniqSupply)
 works is as follows:

  *   The `unsafeInterleaveIO` makes it so that `genSym` is actually forced 
before any of the recursive calls to `mk_split` force their `genSym`, 
regardless of evaluation order
  *   This guarentees a certain partial order on produced uniques: Any parent 
`UniqSupply`'s `Unique` is calculated by a call to 
compiler/cbits/genSym.c#genSym() before any `Unique`s of its offsprings are
  *   The order of `Unique`s on different off-springs of the same `UniqSupply` 
is determined by evaluation order as a result of `unsafeInterleaveIO`, much the 
same as when we create two different `UniqSupply`s by calls to 
`mkSplitUniqSupply`
  *   So, `unfoldr (Just . takeUniqFromSupply) us) !! n` is always 
deterministic and strictly monotone, in the sense that even forcing the 
expression for n=2 before n=1 will have a lower `Unique` for n=1 than for n=2.
  *   This is of course all an implementation detail
These are the questions that bother me:

  1.  `takeUniqSupply` returns as 'tail' its first off-spring, whereas 
`uniqsFromSupply` always recurses into its second off-spring. By my intuition 
above, this shouldn't really make much of a difference, so what is the 
motivation for that?
  2.  The docs state that the character tag/domain/prefix in the call to 
`mkSplitUniqSupply` should be unique to guarantee actual uniqueness of produced 
`Unique`s. Judging from the implementation of `genSym`, which is unaware of the 
specific domain to draw the next unique from, this is an unnecessarily 

Re: [Haskell-cafe] Access violation when stack haddock haskell-src-exts since LTS 12.0

2018-07-23 Thread Sven Panne
Am Mo., 23. Juli 2018 um 05:49 Uhr schrieb Yuji Yamamoto <
whosekitenever...@gmail.com>:

> Thank you very much!
>
> I confirmed the replaced haddock executable can successfully generate the
> docs!
>

Yesterday I had quite some trouble because of the Haddock problem, too, and
I guess I'm not alone: haskell-src-exts has 165 direct reverse
dependencies, so probably hundreds of Hackage packages are affected by
this. The workaround is simple (don't use --haddock with stack), but far
from satisfying and not very obvious.

Given the fact that this affects a very central piece of the Haskell
infrastructure in its latest stable incarnation (GHC 8.4.3): Can we have an
8.4.4 with a fixed Haddock?
___
ghc-devs mailing list
ghc-devs@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs