RE: GHC 6.2
Simon Peyton-Jones [EMAIL PROTECTED] writes: So far we have not been regarding 6.2 as ultra-urgent because we don't know of anyone who is really stuck with 6.0. Please let us know if you are in fact stuck. I already mentioned that I really need large file support, and I'd add that I have some problems with profiling (segfaults, internal errors¹), both under 6.0 and 6.0.1. Is this known and/or fixed? And was there any answer to the original question: The 'strange selectee 29' crash that you reported earlier is fixed in 6.2. I saw your '.hp file contains NULs' reoprt, but there's not much we can do without a test case, unfortunately. I've never seen this one myself. Are there any other profiling bugs that I missed? (apart from the 'entries field is zero' bug in SourceForge)? When can we expect 6.2? I can work e.g. the large file issue by using multiple files, but as it's going to be fixed RSN, I haven't bothered yet. An approximate schedule would be nice, I promise not to blame anybody if it doesn't hold. :-) We're removing a lot of old/deprecated stuff in 6.2, so I want to be sure we haven't broken anything before doing the release. The best estimate I can give is 4-6 weeks, but it could be sooner if things settle down quickly. Cheers, Simon ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC 6.2
Will the arrow's notation be in 6.2, whilst this is not vital, it would be very useful. Regards, Keean Schupke. ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC 6.2
On Fri, Sep 26, 2003 at 01:16:50PM +0100, MR K P SCHUPKE wrote: Will the arrow's notation be in 6.2? Yes ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC 6.2
Simon Marlow [EMAIL PROTECTED] writes: The 'strange selectee 29' crash that you reported earlier is fixed in 6.2. Okay. I saw your '.hp file contains NULs' reoprt, but there's not much we can do without a test case, unfortunately. I've never seen this one myself. I've only seen it once, and I was using a vim script on the file. Not everything shipped with Red Hat 9 is rock solid, so it might be a vim bug. Are there any other profiling bugs that I missed? I've also gotten segmentation fault (w/ 6.0) when doing -h and -p simultaneously. I'm not sure if I can reproduce it, but I'll save a snapshot if it happens again in a reproducible manner. I did a quick test now (v. 6.0.1), and it worked okay. The best estimate I can give is 4-6 weeks, but it could be sooner if things settle down quickly. Great! -kzm -- If I haven't seen further, it is by standing in the footprints of giants ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
RE: stg_ap_v_ret porting crash: solved?
On Fri, 26 Sep 2003, Rafael Martinez Torres wrote: I enabled the flags -g Sorry , the previous mail was incomplete. send button fired. GhcRtsHcOpts= -g -optc-DDEBUG GhcRtsCcOpts= -g This is my session with gdb , ghc-6.0.1 and mips-sgi-irix65. I thinks this has nothing to do with the gmp library, but with StgPrimFloat.c , line 250 DEbugging with gdb on a multithread RTS seems not easy . When the program crash - I ask - is there any thread other than evaluator one present at RTS ? I don't understand very much on RTS internals, but, I guess a simple Hello World thread may not deal with decodeFloat operations May be the compiler gcc-3.0 is faulty for big binaries, due to MULTIGOT linker, as gcc-2.95 was , and pointers are out of control. I will try gcc-3.2 then .. Cheers. bash-2.05a$ !gdb gdb ghc/compiler/stage1/ghc-6.0.1 (gdb) set args -B./ -hello.hs (gdb) break main Breakpoint 1 at 0x1155242c: file Main.c, line 56. (gdb) run Starting program: /scratch/users/eden/6.0.1/ghc-6.0.1-mips/ghc/compiler/stage1/ghc-6.0.1 -B./ hello.hs Breakpoint 1, main (argc=3, argv=0x7fff2e84) at Main.c:56 56 startupHaskell(argc,argv,__stginit_Main); (gdb) n 108 status = rts_mainLazyIO((HaskellObj)mainIO_closure, NULL); (gdb) s rts_mainLazyIO (p=0x116b3620, ret=0x0) at SchedAPI.h:54 54 createIOThread(nat stack_size, StgClosure *closure) { (gdb) n 59t = createThread(stack_size); .. .. .. 428 scheduleThread(tso); (gdb) n 429 return waitThread(tso, ret); (gdb) n waitThread (tso=0x41c, ret=0x116b3620) at Schedule.c:2276 2276{ (gdb) n 2280 m = stgMallocBytes(sizeof(StgMainThread), waitThread); (gdb) n 2281 m-tso = tso; (gdb) n .. .. .. (gdb) n 2291 main_threads = m; (gdb) n 2297 stat = waitThread_(m); (gdb) n 0x1153c0e8 in waitThread () Current language: auto; currently asm (gdb) s Single stepping until exit from function waitThread, which has no line number information. 0x1153b164 in updateStablePtrTable () (gdb) n Single stepping until exit from function updateStablePtrTable, which has no line number information. Program received signal SIGSEGV, Segmentation fault. __decodeFloat (man=0x7fff2d00, exp=0x7fff2d10, flt=66.641) at StgPrimFloat.c:250 250 if (sign 0) Current language: auto; currently c (gdb) quit The program is running. Exit anyway? (y or n) y ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
ghc --make, recompilation problems? (was: GHC 6.2)
We're removing a lot of old/deprecated stuff in 6.2, so I want to be sure we haven't broken anything before doing the release. The best estimate I can give is 4-6 weeks, but it could be sooner if things settle down quickly. talking about broken things: I've been reluctant to mention it so far, because I can't even give a reproducable example, and the problem only occurs on very large projects, so without a clue as to what might cause it, I certainly couldn't narrow down such an example, should I manage to pin down one. there seems to be a problem in ghc --make's recompilation dependency checks, which means that recompilation might produce inconsistent executables. the usual effect is a problem-free rebuild, followed by inexplicable crashes of the executable. removing the .hi/.o files and calling ghc --make again reliably solves the problem, which is why I suspect recompilation-only dependency checks (type/class changes not propagated to dependent modules?). sorry about this rather useless piece of information, but perhaps other people on this list have other parts of the puzzle, and it would be nice to get rid of this (haskell programs don't crash like this!-). cheers, claus ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: ghc --make, recompilation problems? (was: GHC 6.2)
On Fri, Sep 26, 2003 at 02:07:57PM +0100, Claus Reinke wrote: talking about broken things: I've been reluctant to mention it so far, because I can't even give a reproducable example, and the problem only occurs on very large projects, so without a clue as to what might cause it, I certainly couldn't narrow down such an example, should I manage to pin down one. there seems to be a problem in ghc --make's recompilation dependency checks, I have noticed that if you make 2 programs in the same directory then you can end up with the first Main.o being used for the second program (at least I assumed that was what was happening. I didn't actually investigate). I can't remember if the new behaviour was in 6.0.1 or not. I don't know if this can actually causes crashes rather than just a program that does what you don't want or a link failure, though. Ian ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: GHC 6.2
Simon Peyton-Jones [EMAIL PROTECTED] writes: So far we have not been regarding 6.2 as ultra-urgent because we don't know of anyone who is really stuck with 6.0. Please let us know if you are in fact stuck. I already mentioned that I really need large file support, and I'd add that I have some problems with profiling (segfaults, internal errors¹), both under 6.0 and 6.0.1. Is this known and/or fixed? And was there any answer to the original question: When can we expect 6.2? I can work e.g. the large file issue by using multiple files, but as it's going to be fixed RSN, I haven't bothered yet. An approximate schedule would be nice, I promise not to blame anybody if it doesn't hold. :-) -kzm ¹ If it's not a known issue, I can tar up one of these. It's a fairly large example, but it seems to be consistently happening. -- If I haven't seen further, it is by standing in the footprints of giants ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
getSignalMask ghc6.0.1
I'm trying to understand the ghc signal implementation. I can't do much with the provided examples, because getSignalMask exits the program with: Fail: invalid argument Action: getSignalMask Reason: Invalid argument I'm using FreeBSD 5.0 with ghc6.0.1. Is there any tutorials or explanations about posix signals/threads in ghc out there? Shawn ___ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
Re: learning to love laziness
On Thu, 25 Sep 2003 12:59:37 -0700 Mark Tullsen [EMAIL PROTECTED] wrote: Haskell has lazy/lifted products and not true products. Aren't lazy products true products? What makes something a product is: fst (x,y) = x snd (x,y) = y for all x and y. This holds with lazy products but not eager ones fst (3,_|_) = _|_ /= 3 I'd think the problem is that Haskell isn't consistently lazy (for good reason!). Haskell has eager coproducts (case analysis). If you didn't use pattern matching (or used lazy pattern matching), then this problem wouldn't come up. Of course, lazy coproducts (pattern matching) is somewhat uninteresting (f ~True = 1;f ~False = 2; f False == 1) Maybe from seeing this, it's clearer why laws such as x = (fst x,snd x) do not hold. Neither does the following law hold (uncurry . curry) f = f which is unfortunate (for a language named after Haskell *Curry*). To see why it doesn't hold, compare t1 and t2 in this program: f (_,_) = 1 t1 = f undefined t2 = (uncurry . curry) f undefined ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: learning to love laziness
On Fri, 26 Sep 2003, Derek Elkins wrote: On Thu, 25 Sep 2003 12:59:37 -0700 Mark Tullsen [EMAIL PROTECTED] wrote: Haskell has lazy/lifted products and not true products. Aren't lazy products true products? What makes something a product is: fst (x,y) = x snd (x,y) = y for all x and y. This holds with lazy products but not eager ones fst (3,_|_) = _|_ /= 3 Right, strict languages do not have true products either. A strict language without side-effects, and in which no expression can loop infinitely or cause an error (because these are side-effects of a sort), COULD have true products. The reason Haskell doesn't is that true categorical products have to satisfy an additional law, (fst x, snd x) = x and Haskell's products don't, since (_|_, _|_) /= _|_ The key question is: can we write a program which distinguishes these two values? And we certainly can, for example seq (_|_,_|_) 0 = 0 seq_|_0 = _|_ or case (_|_,_|_) of (_,_) - 0= 0 case_|_of (_,_) - 0= _|_ But of course, *fst and snd* can't distinguish the two! So if we only operated on products using fst and snd, then we could pretend that these two values *were* equal, even though they're not in the implementation, and thus say that Haskell had true products. This leads some people to suggest that the behaviour of seq and pattern matching be changed, so as not to distinguish these two values either. A possible change would be to make both seq and case lazy for product types, so that if x were a pair, then seq x y would NOT force the evaluation of x, and case x of (a,b) - e would behave as case x of ~(a,b) - e, i.e. x would be demanded only when one of a or b was needed. This would be a good thing, in that Haskell would have a nicer algebra, but a bad thing, in that it would conceal a difference which is really present in the implementation, thus denying the programmer a degree of control over what the implementation does. Namely, a programmer would no longer be able to move the evaluation of a pair earlier than its components are needed, by using a seq or a case (or in any other way). Unfortunately, that control may sometimes be vitally important. Anyone who has removed space leaks from Haskell programs knows the importance of controlling evaluation order, so as, for example to drop pointers to garbage earlier. Consider an expression such as if ...condition containing the last pointer to a very large datastructure... then (a,b) else (c,d) where a, b, c and d are perhaps expressions which *build* a very large data-structure. Evaluating this expression early enables a lot of garbage to be collected, but evaluating a component early allocates a lot of memory before it is needed. Thus it's important to be able to force just the pair structure, without forcing components, and this distinguishes _|_ from (_|_,_|_), however it is done. Space debugging does, to quite a large extent, involve inserting seq in judiciously chosen places. These places are hard to predict in advance (before seeing the heap profile). If Haskell had true products, and it turned out that the place needing a seq happened to have a pair type, then that simple fix would not be applicable. The programmer would need to refactor the program, replacing the pair by another type representing a lifted product, before the space leak could be fixed. That might require changing an arbitrarily large part of the program, which is clearly not desirable. So there are good arguments both for and against having true products. The debate has raged many times during the Haskell design process. In the end, the argument that Haskell's designers should not make finding and fixing space leaks any harder than it already is won, and I think that was the right decision -- but it is a trade-off, and one must recognise that. Incidentally, exactly the same problem arises for functions: Haskell does not have true functions either, because _|_ and \x - _|_ are not equal. John Hughes ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
RE: Library Infrastructure Proposal Home Page
I think the proposal is great. Here's some random comments: It might be worth saying earlier on that the library infrastructure is expected to be a layer underneath the platform's native package support (if such support exists). For example, I've never used Python's Distutils, but I have a bunch of Python packages on my system that were installed using the native package system on top of Distutils (I presume). FreeBSD's ports is both a source and binary package system. A FreeBSD system functions perfectly well using only binary packages. To a certain extent Gentoo is the same, although they place far less emphasis on binary packages. FreeBSD (in source or binary mode), and Gentoo, have no support for recompiling packages when something they depend on has changed. This is the biggest failing of these systems IMHO. The 3rd paragraph of 2.1 therefore isn't correct - there's still a big problem for source-based distributions. However, this is not *our* problem, it's theirs - when a dependency is updated, everything that depends on it should be recompiled. ./Setup.lhs bdist: wouldn't it be better to create a source RPM than a binary RPM? Once you have a source RPM the RPM tools can be used to build a binary RPM. Similarly for FreeBSD and Gentoo - I'd expect Setup.lhs to produce a port skeleton/ebuild for me, not a binary package. The PackageConfig file: I'd leave out 'provides' and 'isDefault' unless we have a convincing example which needs them. Possibly add: 'haddock_html_root :: String' and 'haddock_interface :: String' for documentation. I'm thinking about removing 'extra_ghc_opts' - it's highly dodgy when combined with 'auto'. I agree with Ross's comments about data vs. code. Let's abstract as much as possible as data. Cheers, Simon ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: Library Infrastructure Proposal Home Page
* Simon Marlow [EMAIL PROTECTED] [2003-09-26 12:08 +0100]: FreeBSD (in source or binary mode), and Gentoo, have no support for recompiling packages when something they depend on has changed. This is the biggest failing of these systems IMHO. The 3rd paragraph of 2.1 therefore isn't correct - there's still a big problem for source-based distributions. However, this is not *our* problem, it's theirs - when a dependency is updated, everything that depends on it should be recompiled. This is true for the FreeBSD base system, but it is recommended nowadays to use sysutils/portupgrade for managing ports. With portupgrade you can simply do `portupgrade -rf changed_pkg` to recompile all packages depending on the changed one. The only reason why portupgrade is not part of the base system is that it is written in ruby and we are not willing to include ruby in the base. BTW, as David Roundy pointed out already, the haskell config file should be in /usr/local/etc for FreeBSD please. Or better, in $LOCALBASE/etc, where LOCALBASE is a variable pointing to /usr/local by default. Regards, Olli -- Oliver Braun -- obraun @ { unsane.org | FreeBSD.org | haskell.org } pgp0.pgp Description: PGP signature ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: GHC 6.2
Simon Peyton-Jones [EMAIL PROTECTED] writes: So far we have not been regarding 6.2 as ultra-urgent because we don't know of anyone who is really stuck with 6.0. Please let us know if you are in fact stuck. I already mentioned that I really need large file support, and I'd add that I have some problems with profiling (segfaults, internal errors¹), both under 6.0 and 6.0.1. Is this known and/or fixed? And was there any answer to the original question: When can we expect 6.2? I can work e.g. the large file issue by using multiple files, but as it's going to be fixed RSN, I haven't bothered yet. An approximate schedule would be nice, I promise not to blame anybody if it doesn't hold. :-) -kzm ¹ If it's not a known issue, I can tar up one of these. It's a fairly large example, but it seems to be consistently happening. -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: lexer puzzle
Brandon Michael Moore [EMAIL PROTECTED] writes: Or was that supposed to be composition of a constructor with a function, A . f? Function composition, and higher order functions in general are likely to confuse an imperative programmer, but I think there isn't much syntax can do there. I think there is a problem with too much overloaded syntax. Perhaps it is time to put non-ASCII characters to good use? For instance, function composition could use the degree sign: ° and leave the . for module qualification. Template Haskell could use double-angle quotation marks: « » and the section sign: § and avoid clashing with list comprehensions and the function application operator. Implicit parameters could use an inverted question mark: ¿ And so on, just look for places where the semantics depend on spaces in the right (or wrong) place. -kzm -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: lexer puzzle
On Fri, Sep 26, 2003 at 08:59:12AM +0200, Ketil Z. Malde wrote: Brandon Michael Moore [EMAIL PROTECTED] writes: Or was that supposed to be composition of a constructor with a function, A . f? Function composition, and higher order functions in general are likely to confuse an imperative programmer, but I think there isn't much syntax can do there. I think there is a problem with too much overloaded syntax. Perhaps it is time to put non-ASCII characters to good use? For instance, function composition could use the degree sign: and leave the . for module qualification. why not the actual functional composition operator: or we could also make good use ofand all the other fun mathematical operators. Template Haskell could use double-angle quotation marks: and the section sign: and avoid clashing with list comprehensions and the function application operator. Implicit parameters could use an inverted question mark: And so on, just look for places where the semantics depend on spaces in the right (or wrong) place. I would love to be able to use unicode to make my programs more readable. just as an alternate syntax for awkward ascii constructs. and as operator, function names when they make sense. this could probably be done with a preprocessor, but wolud be easier in the compiler to work out the layout rule and handle language extensions and whatnot. John -- --- John Meacham - California Institute of Technology, Alum. - [EMAIL PROTECTED] --- ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: lexer puzzle
Hi. I'm really new to Haskell, just learning it, and I must say I'm pretty overwhelmed by the large variety of constructs. (=, -, \ to name a few) Would that be \ as in TREX row variable polymorphism? Just remember most operators are just library functions. It's only =, -, =, -, :: that are really part of the language, and {,},; for grouping. Did I miss any? Yes, you missed \, which is used for function abstraction: (\x - x*x) 3 And ( , ) for tuples. And I don't think - is part of the language - it only appears in the type syntax, not term syntax. If you allow it, you have to allow * as well. --KW 8-) -- Keith Wansbrough [EMAIL PROTECTED] http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: lexer puzzle
Keith Wansbrough [EMAIL PROTECTED] writes: And I don't think - is part of the language - it only appears in the type syntax, not term syntax. If you allow it, you have to allow * as well. Errm, you just gave an example of - in the term syntax... (\x - x*x) 3 Regards, Malcolm ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: lexer puzzle
Keith Wansbrough [EMAIL PROTECTED] writes: And I don't think - is part of the language - it only appears in the type syntax, not term syntax. If you allow it, you have to allow * as well. Errm, you just gave an example of - in the term syntax... (\x - x*x) 3 Guilty... sorry! :-( --KW 8-) -- Keith Wansbrough [EMAIL PROTECTED] http://www.cl.cam.ac.uk/users/kw217/ University of Cambridge Computer Laboratory. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: lexer puzzle
On vrijdag, sep 26, 2003, at 09:16 Europe/Amsterdam, John Meacham wrote: On Fri, Sep 26, 2003 at 08:59:12AM +0200, Ketil Z. Malde wrote: I think there is a problem with too much overloaded syntax. Perhaps it is time to put non-ASCII characters to good use? For instance, function composition could use the degree sign: and leave the . for module qualification. why not the actual functional composition operator: or we could also make good use ofand all the other fun mathematical operators. This is very readable, but not very writable. Until I get a keyboard with a key, I would prefer to restrict the syntax to ASCII/whatever and simply make it the editor's responsibility to display source code using special characters. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Modeling multiple inheritance
On Thu, 25 Sep 2003 [EMAIL PROTECTED] wrote: Brandon Michael Moore wrote: So I defined a class to model the inheritance relationships class SubType super sub | sub - super where upCast :: sub - super Now I can define a default instance of HasFooMethod: instance (HasFooMethod super args result, SubClass super sub) = HasFooMethod sub args result where foo sub args = foo (upCast sub) args This will propagate foo methods down the inheritance hierarcy. If a new class C is derived from A, I just need to say One problem is that the subclass relationship needs the functional dependency Does anyone know of clever solutions that would model multiple inheritance while preserving the functional dependencies (unsafe compiler flags are fine too), or ways to reduce the pain of overloading resolution without the functional dependency? Yes. The code included. The solution is trivial: in case of a multiple inheritance, a class has a _sequence_ of superclasses rather than a single superclass. Like instance SubClass (Object,()) ClassA instance SubClass (Object,()) ClassB -- Multiple inheritance (including the diamond!) instance SubClass (ClassA,(ClassB,())) ClassC instance SubClass (ClassA,(ClassB,(ClassC,( ClassD And we need some intelligence to traverse the sequence. But even a computer can do that. That should solve my problem. Putting all the superclasses in a tuple should work. I'm worried about large class hierarchies. If it works on the java.* classes I should be fine. Have you used this approach before? I'm worried about compile time, runtime costs from the casts (hopefully they compile out), and maybe exceeding maximum stack depth in context reduction. This is a clever solution. I like it. Now, is anyone up to encoding the Dylan MRO in Haskell type classes? ;) I would like to propose a different solution: a dual of typeclasses in the value domain. Function foo is just a regular function foo:: Object - Int - Int foo x y = y We then need a class MApplicable fn args result with a method mapply. The trick is that the method should take any object of a type castable and cast it to the type of the first argument of fn. The cast can be made safe and statically checkable, using the type heap. Actually, we can use the type heap to model the dispatch table (whose rows are functions and columns are object/classes). Given a function and an object, we can search in many way for the applicable combination. What type heap? It sounds like you are talking about information from an OO runtime, or are you talking about the collection of instances. I tried a system where method names were also represented by data types, but without your solution for multiple inheritance I couldn't get the implementation inheritance I wanted. How would you implement this dispatch table? What are the advantages of this approach over the type class encoding? I'm worried that generating bindings would be a problem if the dispatch table needs to be a monolithic value with a very interesting type in some file. Brandon And now, the code for the solution that works. Compiler flags: -fglasgow-exts -fallow-overlapping-instances -fallow-undecidable-instances data Object = Object data ClassA = ClassA data ClassB = ClassB data ClassC = ClassC data ClassD = ClassD class SubClass super sub | sub - super where upCast :: sub - super instance SubClass (Object,()) ClassA instance SubClass (Object,()) ClassB -- Multiple inheritance (including the diamond!) instance SubClass (ClassA,(ClassB,())) ClassC instance SubClass (ClassA,(ClassB,(ClassC,( ClassD class HasFooMethod cls args result where foo :: cls - args - result instance (SubClass supers sub, HasFooMethod supers args result) = HasFooMethod sub args result where foo obj args = foo (upCast obj) args instance (HasFooMethod cls args result) = HasFooMethod (cls,()) args result where foo (x,()) = foo x instance (HasFooMethod cls args result) = HasFooMethod (x,cls) args result where foo (x,y) = foo y instance HasFooMethod Object Int Int where foo _ x = x test1::Int = foo Object (1::Int) test2::Int = foo ClassA (2::Int) test3::Int = foo ClassD (3::Int) -- Likewise for another method: class HasBarMethod cls args result where bar :: cls - args - result instance (SubClass supers sub, HasBarMethod supers args result) = HasBarMethod sub args result where bar obj args = bar (upCast obj) args instance (HasBarMethod cls args result) = HasBarMethod (cls,()) args result where bar (x,()) = bar x instance (HasBarMethod cls args result) = HasBarMethod (x,cls) args result where bar (x,y) = bar y instance HasBarMethod ClassB Bool Bool where bar _ x = x test4::Bool = bar ClassB True test5::Bool = bar ClassC True test6::Bool = bar ClassD True
Re: Modeling multiple inheritance
Brandon Michael Moore wrote regarding the first solution: chain of super-classes: I'm worried about large class hierarchies. If it works on the java.* classes I should be fine. Have you used this approach before? I'm worried about compile time, runtime costs from the casts (hopefully they compile out), and maybe exceeding maximum stack depth in context reduction. I didn't use the approach for anything as complex as all java.* classes. The only run-time costs are evaluating the chain of fst . snd . fst . The length and the composition of the chain is statically known. Perhaps the compiler can do something smart here. The maximum length of the chain is the maximum depth of the inheritance tree. It shouldn't be too big. A cast from a subclass to a superclass has to be executed anyway (if not by your code then by JVM). If the maximum stack depth is exceeded, we can repeat the compilation with a compiler flag to allocate a bigger stack. In my experience the only time I've seen the derivation stack depth exceeded is when the derivation truly diverges. What type heap? It sounds like you are talking about information from an OO runtime, or are you talking about the collection of instances. The other solution I talked so confusingly before is that of generic functions. For that, we need a way to obtain a value representation of a type. Several such representations exists: e.g., Typable, representation as an integer, etc. All our objects must be members of the class Typable. A method (generic function foo) would have the following signature: foo:: (Typable object) = object - Int -Int For example, if foo is defined for ClassA object only, we can write foo obj arg = if inherit_from (typeof obj) (typeof (undefined::ClassA)) then particular_instance_foo (coerce obj) arg else error miscast If bar is defined for classB and redefined in classC, we can write bar obj arg = if inherit_from (typeof obj) (typeof (undefined::ClassC)) then particular_instance1_bar (coerce obj) arg else if inherit_from (typeof obj) (typeof (undefined::ClassB)) then particular_instance2_bar (coerce obj) arg else error miscast The functions inherit_from and coerce avail themselves of a table that records the relationship between types using their value representations. The disadvantage of this approach is that the cast errors become run-time errors. OTH, because type representations and the whole inheritance graph are values, we can do much more. We can check for proper and improper diamond inheritance, we can do a rather sophisticated dispatch. Types heap and several ways of doing safe casts are discussed in http://www.haskell.org/pipermail/haskell/2003-August/012372.html http://www.haskell.org/pipermail/haskell/2003-August/012355.html See also: http://citeseer.nj.nec.com/cheney02lightweight.html http://citeseer.nj.nec.com/context/1670116/0 The Sketch of a Polymorphic Symphony http://homepages.cwi.nl/~ralf/polymorphic-symphony/ ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe