Re: Mutually-recursive/cyclic module imports
On Mon, Sep 01, 2008 at 10:16:50PM -0700, Iavor Diatchki wrote: a free copy is available at: http://www.purely-functional.net/yav/publications/modules98.pdf (the source code, is also available at the same site). Hope that this helps, Thanks. I liked this paper and hope we can come up with a similar formal treatment of the module system for haskell' in the specification itself. describing the result of import/export statements as the minimal fixpoint of a set of equations is delightfully concise and straightforward. -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
Hi, a free copy is available at: http://www.purely-functional.net/yav/publications/modules98.pdf (the source code, is also available at the same site). Hope that this helps, -Iavor On Tue, Aug 26, 2008 at 4:33 PM, John Meacham [EMAIL PROTECTED] wrote: On Tue, Aug 26, 2008 at 04:31:33PM -0700, John Meacham wrote: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.8816 Doh! wrong paper. http://portal.acm.org/citation.cfm?id=581690.581692 anyone have a free link? John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
On Tue, Aug 26, 2008 at 04:31:33PM -0700, John Meacham wrote: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.8816 Doh! wrong paper. http://portal.acm.org/citation.cfm?id=581690.581692 anyone have a free link? John -- John Meacham - ⑆repetae.net⑆john⑈ ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
Ian Lynagh wrote: http://hackage.haskell.org/trac/haskell-prime/wiki/Defaulting#Proposal4- removedefaulting Here's a late response to the comments on that wiki page. It seems, to me, an extremely bad idea to remove defaulting *and* make that proposed change to (^) at the same time. Code can currently depend on defaulting, and if it does, then integers most likely default to the Integer type, not Int. If you just remove defaulting, then that code fails to compile, which is fine. If you remove defaulting and change (^) at the same time, then that code compiles but means something different, which is definitely not fine. It may initially seem like there's no problem, since no one would possibly want to use a number anywhere near 2 billion as an exponent for (^). The problem here is that if one is allowing types to be inferred (which is certainly true, if we're worried about defaulting), then that use of the horribly unsafe Int type can propogate through the code. Do I use this number as an exponent, and then also add it to x somewhere else? Then x is an Int as well. Then maybe I calculate (x * y) somewhere else? Okay, now y is an Int. And perhaps y is added to z? So, z is an Int. But maybe z overflows... and now a nasty bug, a numeric overflow in z, was introduced without changing my code, without a warning, by the change to the type of (^) which is used four functions away. -- Chris ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
On Sat, 2008-08-16 at 13:51 -0400, Isaac Dupree wrote: Duncan Coutts wrote: [...] I'm not saying it's a problem with your proposal, I'd just like it to be taken into account. For example do dependency chasers need to grok just import lines and {-# SOURCE -#} pragmas or do they need to calculate fixpoints. Good point. What does the dependency chaser need to figure out? - exactly what dependency order files must be compiled (e.g., ghc -c) ? - what files (e.g., .hi) are needed to be findable by the e.g. (ghc -c) ? - recompilation avoidance? It needs to work out which files the compiler will read when it compiles that module. So currently, I think we just have to read a single .hs file and discover what modules it imports. We then can map those to .hi or .hs-boot files in one of various search dirs or packages. We also need to look at {#- SOURCE #-} import pragmas since that means we look for a different file to ordinary imports. Calculating dependency order and recompilation avoidance are things the dep program has to do itself anyway. The basics is just working out what things compiling a .hs file depends on. Obviously it's somewhat dependent on the Haskell implementation. Duncan ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
Isaac Dupree wrote: Duncan Coutts wrote: [...] I'm not saying it's a problem with your proposal, I'd just like it to be taken into account. For example do dependency chasers need to grok just import lines and {-# SOURCE -#} pragmas or do they need to calculate fixpoints. Actually, good point, Duncan, that got me thinking about what we need in order to obviously not to lose much/any of the .hs-boot efficiency. (warning: another long post ahead, although the latter half of it is just an example from GHC's source) [and I re-read my post and wasn't sure about a few things, but maybe better to get feedback first -- please tell me if I'm being too verbose somewhere, too] Let's look at the total imports of a .hs and its .hs-boot, as they currently are for GHC. Either can be non-SOURCE imports (let's call them NOSOURCE), SOURCE imports, or not importing that. .hs:NOSOURCE, .hs-boot:NOSOURCE : okay .hs:NOSOURCE, .hs-boot:SOURCE : okay .hs:NOSOURCE, .hs-boot:not-imported : okay .hs:SOURCE, .hs-boot:NOSOURCE : bad, if the .hs needs SOURCE, then probably so does the .hs-boot .hs:SOURCE, .hs-boot:SOURCE : okay .hs:SOURCE, .hs-boot:not-imported : okay - the .hs-boot importing a module that the .hs doesn't is invalid, or at least useless [actually, see later example -- there may be reasons for this, but in that case, it doesn't hurt to also import the module in the .hs (assuming there's no syntactic/maintenance burden), and it provides better automatic error-checking to do so] Given the limited amount of information a .hs-boot file (or SOURCE-imported file, in my scheme) needs for being a boot-file, there is no advantage to import the modules it depends on as NOSOURCE. The compiler just has to be clever enough to ignore imports of functions that it can't find out the type of. Also, currently using SOURCE requires the imported module to have a .hs-boot. But it should work fine to look for a .hi and use that in the absence of .hi-boot, because it has strictly a superset of the information (so that my statement that SOURCE is superior to NOSOURCE when it works can be truer, for the sake of demonstration). [oops! I was wrong, it may need to NOSOURCE-import on occasion to find out a function's type - more on that in a later post?] Now, since the .hs-boot SOURCE vs NOSOURCE has been collapsed, I think we can move mostly-all .hs-boot info into the .hs file. If the .hs-boot file had imported something, the corresponding import in the .hs is imported with {-#SOURCE_FOLLOW#-} (in addition to {-#SOURCE#-} or {-#NOSOURCE#-}); otherwise it's imported with {-#SOURCE_NOFOLLOW#-} (ditto). For demonstration, I'll assume that all imports are annotated this way, with two bits of information. Presumably all imports that aren't part of an import loop are NOSOURCE (which includes all cross-package imports). Now let's look at the dependency chaser. NOSOURCE imports must not form a loop. They form dependency chains as normal. SOURCE imports depend on either a .hi or a .hi-boot for the imported module. When a X.hi-boot is demanded: only SOURCE_FOLLOW imports are dependency-chased from X.hs, through any .hs modules that don't already have a .hi or .hi-boot. In the case where .hs-boots worked, this *can* avoid cycles. If this SOURCE_FOLLOW dependency DAG doesn't have any cycles, then it should be as simple as calling (the fictional) `ghc -source X.hs` to produce X.hi. If there are cycles, and it is sometimes necessary*, GHC needs to be slightly smarter and be able to produce all the .hi-boot files at once from any graph SCCs (loops) that prevent it from being a DAG (e.g., `ghc -source X.hs Y.hs` to produce X.hi-boot and Y.hi-boot). Note that it doesn't need to be particularly smart here -- e.g., no type inference is done. *necessary loops: example 1, the data/declarations literally loop: module X1 where { import Y1(Y); data X a = End a | Both Y Y; } module Y1 where { import X1(X); data Y = Only (X (Maybe Y)); } (or kind annotations could be required for these loops in general, e.g. data X (a :: *) = ...) [hmm, in this case actually all we need is the data left-hand-side, so we could do this in two stages. But that wouldn't work out so well if their RHSs contained {-#UNPACK#-}!SomeNewtypeForInt where SomeNewtypeForInt was from the other module. But that's an optimization that it might be okay not to do, as long as it was consistently not done both for .hi-boot and .hi/.o; and it could perhaps be doable] example 2, there are just too many back-and-forths: module X2 where { import Y2(Yb); data Xa = Xa; data Xc = Xc Yb; } module Y2 where { import X2(Xa,Xc); data Yb = Yb Xa; data Yd = Yd Xc; } This second one could also be accomplished if multiple different .hs-boots were allowed per .hs, although it doesn't seem worth the annotation!! such as using SOURCE_FOLLOW[0] or [1], [2]... I'm not even going to try to write that! [oh wait, SOURCE[0-1] = SOURCE,
Re: Mutually-recursive/cyclic module imports
Duncan Coutts wrote: [...] I'm not saying it's a problem with your proposal, I'd just like it to be taken into account. For example do dependency chasers need to grok just import lines and {-# SOURCE -#} pragmas or do they need to calculate fixpoints. Good point. What does the dependency chaser need to figure out? - exactly what dependency order files must be compiled (e.g., ghc -c) ? - what files (e.g., .hi) are needed to be findable by the e.g. (ghc -c) ? - recompilation avoidance? -Isaac ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
On Fri, Aug 15, 2008 at 09:27:16AM -0400, Isaac Dupree wrote: Haskell-98 specifies that module import cycles work automatically with cross-module type inference. It has some weird interactions with defaulting and the monomorphism restriction. In Haskell-prime we're planning on removing artificial monomorphism, but defaulting will still be necessary (and can still be set differently per module). I'm not sure if defaulting actually makes this worse, but regardless, I think we should seriously consider removing defaulting anyway: http://hackage.haskell.org/trac/haskell-prime/wiki/Defaulting#Proposal4-removedefaulting Thanks Ian ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime
Re: Mutually-recursive/cyclic module imports
Isaac Dupree wrote: In the case of the proposed SOURCE imports without hs-boot files, GHC would ... Ah, another difference from the .hs-boot system: in my proposal, when a file is imported with SOURCE and dependency chasing (e.g. of data-types) is done through its imports, it won't make a difference whether those imports have SOURCE pragmas; the compiler is in SOURCE-mode already, and will look at .hi files if there are any up-to-date ones available (e.g. the imported module isn't in the SCC / import loop), and otherwise will look at the source code (if it wanted, it could make some sort of .hi-boot out of it, I suppose). As opposed to the .hs-boot mechanism where .hs-boot files must choose carefully (and perhaps differently to the corresponding .hs file) whether their imports use SOURCE (they must if it's necessary to prevent loops, but must not if that module doesn't have a .hs-boot file that contains what's needed! But sometimes it doesn't make a difference, except for recompilation!) -Isaac ___ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime