Re: Mutually-recursive/cyclic module imports

2008-09-03 Thread John Meacham
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

2008-09-01 Thread Iavor Diatchki
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

2008-08-26 Thread John Meacham
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

2008-08-21 Thread Chris Smith
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

2008-08-17 Thread Duncan Coutts
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

2008-08-17 Thread Isaac Dupree

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

2008-08-16 Thread Isaac Dupree

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

2008-08-15 Thread Ian Lynagh
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

2008-08-15 Thread Isaac Dupree

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