
In Bryan's recent test of GHC 7.8 against all of Hackage, there were three spurious errors caused by lack of role abstraction. Here are the class definitions where a nominal parameter is inferred, probably against the wishes of the author: from logict-0.2.3/Control.Monad.Logic.Class:
class (MonadPlus m) => MonadLogic m where msplit :: m a -> m (Maybe (a, m a))
from monadLib-3.5.2/MonadLib:
class (Monad m) => ReaderM m i | m -> i where ask :: m i
from base/Control.Arrow:
class Arrow a => ArrowApply a where app :: a (a b c, b) c
In each of these, the last parameter of the class is given a nominal role because it appears as the parameter of a type variable. However, in each case, it appears as the parameter of a *class* type variable. This means that, if we somehow knew that the class author wanted the class to be usable with GND, we could simply check every instance declaration for that class to make sure that the relevant concrete instantiation has the right role. For example, when the user writes, for example
instance ArrowApply Foo where �
we check that Foo's first parameter has a representational role. If it doesn't, then the instance is rejected. An alternative, somewhat heavier idea would be to represent roles as class constraints. We could have
class NextParamNominal (c :: k) class NextParamRepresentational (c :: k)
GHC could "generate" instances for every datatype definition. For example:
type role Map nominal representational data Map k v = �
would induce
instance NextParamNominal Map instance NextParamRepresentational (Map k)
Users would not be able to write these instances -- they would have to be generated by GHC. (Alternatively, there could be no instances, just a little magic in the constraint solver. Somewhat like Coercible.) Then, the classes above would just have to add a superclass, like this:
class (Arrow a, NextParamRepresentational a) => ArrowApply a where app :: a (a b c, b) c
The role inference mechanism would be made aware of role constraints and use this one to derive that ArrowApply is OK for GND. This "heavier" approach has a similar upshot to the first idea of just checking at instance declarations, but it is more customizable and transparent to users (I think). I'm not sure I'm advocating for this change (or volunteering to implement before the release candidate), but I wanted to document the idea and get any feedback that is out there. This would fix the breakage we've seen without totally changing the kind system. Thanks, Richard PS: Due credit is to migmit for suggesting the type-class idea on glasgow-haskell-users.
From johan.tibell at gmail.com Tue Oct 1 04:50:48 2013 From: johan.tibell at gmail.com (Johan Tibell) Date: Mon, 30 Sep 2013 21:50:48 -0700 Subject: Is evacuate for StgMutArrPtrs and StgArrPtrs expensive to GC? Message-ID:
X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000 X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000
Hi, When I benchmark Data.HashMap.insert from unordered-containers (inserting the keys [0..10000]) the runtime is dominated by GC: $ cat Test.hs module Main where import Control.DeepSeq import Control.Exception import Control.Monad import qualified Data.HashMap.Strict as HM import Data.List (foldl') main = do let ks = [0..10000] :: [Int] evaluate (rnf ks) forM_ ([0..1000] :: [Int]) $ \ x -> do evaluate $ HM.null $ foldl' (\ m k -> HM.insert k x m) HM.empty ks $ perf record -g ./Test +RTS -s 6,187,678,112 bytes allocated in the heap 3,309,887,128 bytes copied during GC 1,299,200 bytes maximum residency (1002 sample(s)) 118,816 bytes maximum slop 5 MB total memory in use (0 MB lost due to fragmentation) Tot time (elapsed) Avg pause Max pause Gen 0 11089 colls, 0 par 1.31s 1.30s 0.0001s 0.0005s Gen 1 1002 colls, 0 par 0.49s 0.51s 0.0005s 0.0022s INIT time 0.00s ( 0.00s elapsed) MUT time 1.02s ( 1.03s elapsed) GC time 1.80s ( 1.80s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 2.82s ( 2.84s elapsed) %GC time 63.7% (63.5% elapsed) Alloc rate 6,042,264,963 bytes per MUT second Productivity 36.3% of total user, 36.1% of total elapsed $ perf report 41.46% Test Test [.] evacuate 15.47% Test Test [.] scavenge_block 11.04% Test Test [.] s3cN_info 8.74% Test Test [.] s3aZ_info 3.59% Test Test [.] 0x7ff5 2.83% Test Test [.] scavenge_mut_arr_ptrs 2.69% Test libc-2.15.so [.] 0x147fd9 2.51% Test Test [.] allocate 2.00% Test Test [.] s3oo_info 0.91% Test Test [.] todo_block_full 0.87% Test Test [.] hs_popcnt64 0.80% Test Test [.] s3en_info 0.62% Test Test [.] s3el_info Is GC:ing StgMutArrPtrs and StgArrPtrs, which I create a lot of, more expensive than GC:ing normal heap objects (i.e. for standard data types)? -- Johan
From johan.tibell at gmail.com Tue Oct 1 05:43:01 2013 From: johan.tibell at gmail.com (Johan Tibell) Date: Mon, 30 Sep 2013 22:43:01 -0700 Subject: Is evacuate for StgMutArrPtrs and StgArrPtrs expensive to GC? In-Reply-To:
References: Message-ID: X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000 X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000
The code for 'allocate' in rts/sm/Storage.c doesn't seem that
expensive. An extra branch compared to inline allocation and
allocation is done in the next nursery block (risking fragmentation?).
-- Johan
On Mon, Sep 30, 2013 at 9:50 PM, Johan Tibell
Hi,
When I benchmark Data.HashMap.insert from unordered-containers (inserting the keys [0..10000]) the runtime is dominated by GC:
$ cat Test.hs module Main where
import Control.DeepSeq import Control.Exception import Control.Monad import qualified Data.HashMap.Strict as HM import Data.List (foldl')
main = do let ks = [0..10000] :: [Int] evaluate (rnf ks) forM_ ([0..1000] :: [Int]) $ \ x -> do evaluate $ HM.null $ foldl' (\ m k -> HM.insert k x m) HM.empty ks
$ perf record -g ./Test +RTS -s 6,187,678,112 bytes allocated in the heap 3,309,887,128 bytes copied during GC 1,299,200 bytes maximum residency (1002 sample(s)) 118,816 bytes maximum slop 5 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause Gen 0 11089 colls, 0 par 1.31s 1.30s 0.0001s 0.0005s Gen 1 1002 colls, 0 par 0.49s 0.51s 0.0005s 0.0022s
INIT time 0.00s ( 0.00s elapsed) MUT time 1.02s ( 1.03s elapsed) GC time 1.80s ( 1.80s elapsed) EXIT time 0.00s ( 0.00s elapsed) Total time 2.82s ( 2.84s elapsed)
%GC time 63.7% (63.5% elapsed)
Alloc rate 6,042,264,963 bytes per MUT second
Productivity 36.3% of total user, 36.1% of total elapsed
$ perf report 41.46% Test Test [.] evacuate 15.47% Test Test [.] scavenge_block 11.04% Test Test [.] s3cN_info 8.74% Test Test [.] s3aZ_info 3.59% Test Test [.] 0x7ff5 2.83% Test Test [.] scavenge_mut_arr_ptrs 2.69% Test libc-2.15.so [.] 0x147fd9 2.51% Test Test [.] allocate 2.00% Test Test [.] s3oo_info 0.91% Test Test [.] todo_block_full 0.87% Test Test [.] hs_popcnt64 0.80% Test Test [.] s3en_info 0.62% Test Test [.] s3el_info
Is GC:ing StgMutArrPtrs and StgArrPtrs, which I create a lot of, more expensive than GC:ing normal heap objects (i.e. for standard data types)?
-- Johan
From simonpj at microsoft.com Tue Oct 1 08:10:29 2013 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Tue, 1 Oct 2013 08:10:29 +0000 Subject: FW: [Haskell-cafe] Poll & plea: State of GUI & graphics libraries in Haskell In-Reply-To:
References: Message-ID: <59543203684B2244980D7E4057D5FBC1485F5C18@DB3EX14MBXC306.europe.corp.microsoft.com> X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000 X-List-Received-Date: Sat, 12 Oct 2013 07:41:27 -0000
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-bounces at haskell.org] On Behalf Of Paul Liu
Sent: 30 September 2013 07:18
To: Conal Elliott
Cc: Haskell Cafe
Subject: Re: [Haskell-cafe] Poll & plea: State of GUI & graphics libraries in Haskell
Hi Conal,
I wasn't able to make it to last Saturday's FARM track, but I think
there was a good chance that Paul would have demonstrated his Euterpea
music library, which includes a GUI interface (called MUI) written on
top of GLFW. I wrote its initial implementation (around 2009?) with a
monadic interface that let you wire together UI components with
signals (I believe Dan later wrote an arrow interface, but I could be
wrong). It was actually inspired by the ideas behind your Phooey UI
library. It should be very easy to extract this part out as a
standalone package if there is enough interest.
The only issue with it (and all other UI libraries) is that it doesn't
play nicely in GHCi. It used to work pretty well with GHC 7.2 and 7.4
on almost all platforms (Mac needs an extra hack), but GHC 7.6 broke
Mac (and perhaps Windows too). GHC 7.8 supposedly should fix this
problem.
BTW, as also the author of the GLFW library on HackageDB, I've done
barely minimal to keep this Haskell binding afloat. I'm actually
leaning towards GLFW-b library, which is better maintained, and
provides similar binding for GLFW C library but with a saner interface
(no dependency on the OpenGL library, for example). If you don't need
the two extra things that GLFW does (choice of either dynamic or
static linking to GLFW C, and an embedded bitmap font), I suggest you
try out GLFW-b if you are only looking for a think graphics layer with
input+window+OpenGL.
The only thing keeping GLFW-b from becoming a good foundation for a
pure Haskell UI lib is IMHO the lack of a light-weight,
cross-platform, and full-featured font rendering solution. I believe
many other libraries (including Diagram) are having the same problem.
On Thu, Sep 26, 2013 at 8:32 PM, Conal Elliott
I'm polling to see whether there are will and expertise to reboot graphics
and GUIs work in Haskell. I miss working on functional graphics and GUIs in
Haskell, as I've been blocked for several years (eight?) due to the absence
of low-level foundation libraries having the following properties:
* cross-platform,
* easily buildable,
* GHCi-friendly, and
* OpenGL-compatible.
The last several times I tried Gtk2hs, I was unable to compile it on my Mac.
Years ago when I was able to compile, the GUIs looked and interacted like a
Linux app, which made them awkward and upleasant to use. wxHaskell (whose
API and visual appearance I prefered) has for years been incompatible with
GHCi, in that the second time I open a top-level window, the host process
(GHCi) dies abruptly. Since my GUI & graphics programs are often one-liners,
and I tend to experiment a lot, using a full compilation greatly thwarts my
flow. For many years, I've thought that the situation would eventually
improve, since I'm far from the only person who wants GUIs or graphics from
Haskell.
About three years ago, I built a modern replacement of my old Pan and
Vertigo systems (optimized high-level functional graphics in 2D and 3D),
generating screamingly fast GPU rendering code. I'd love to share it with
the community, but I'm unable to use it even myself.
Two questions:
* Am I mistaken about the current status? I.e., is there a solution for
Haskell GUI & graphics programming that satisfies the properties I'm looking
for (cross-platform, easily buildable, GHCi-friendly, and
OpenGL-compatible)?
* Are there people willing and able to fix this situation? My own
contributions would be to test and to share high-level composable and
efficient GUI and graphics libraries on top of a working foundation.
Looking forward to replies. Thanks,
-- Conal
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe at haskell.org
--
Regards,
Paul Liu
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe at haskell.org
participants (1)
-
Richard Eisenberg