runtime reflection for classes

With Data.Generics, we can get an object's type, constructor and fields. I think there should be way to get the object's class(es) and methods. E. g. I want to find out whether the object's type implements Show, and if so, call the show method (and if not, call some replacement). See http://www.haskell.org//pipermail/haskell/2005-November/016992.html see also http://java.sun.com/docs/books/tutorial/reflect/ I know this is again specific to one-parameter type classes. But still, these things occur frequently, don't they. As for classes with more parameters, I guess implementation-wise it is about how to get a representation of the dictionary, and syntax-wise it is about how to specify what dictionary we want. Also I know that Metaprogramming should be done at compile time rather than at run time (as far as possible), and I know that Template Haskell does offer a lot in that direction. But with TH, you construct an abstract source code representation. My idea here is different: I want to write concrete source code that inspects (runtime) type information. (So I don't have to worry about monads generating unique names etc.) Respectfully submitted, -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------

Hello Johannes, Thursday, February 09, 2006, 1:43:38 PM, you wrote: JW> With Data.Generics, we can get an object's type, constructor and fields. really, SYB way to metaprogramming is just to encode information about type in the datastructure. you can do somethiong in this fashion just by coupling together value and functions that is able to show, map and otherwise process this value. due to simple changes in the compiler, functions that translate value into such self-describing structure, are generated automatically. but they can be written manually or by TH 9it was used before compiler was modified). so it is not exact compile-time vs dynamic inspection of metainformation, it's just a general datatype which hoilds all the metainformation about value and therefore can be inspected at run-time to dynamically decide what to do with that value in its current state, information coupled together with value, don't include that you want, but this can be changed. again, this change need to either change a compiler so that it can pack his information when converting "a->Dynamic", or you can write these data manually, or again TH can be used and you will be limited only by the volume of information, available for TH code. except for this, extensing SYB don't require any extensions to the language -- Best regards, Bulat mailto:bulatz@HotPOP.com

Bulat Ziganshin wrote:
again TH can be used and you will be limited only by the volume of information, available for TH code.
Is information such as "instance C t1 t2 .. " available for such code? I guess not since this would require information from the compiler (type checker), but TH splicing runs earlier? Best regards, -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------

Hello Johannes, Thursday, February 09, 2006, 2:43:49 PM, you wrote:
again TH can be used and you will be limited only by the volume of information, available for TH code.
JW> Is information such as "instance C t1 t2 .. " available for such code? JW> I guess not since this would require information from the compiler JW> (type checker), but TH splicing runs earlier? afair, this info is not available, but not because TH runs too early (info about types structure is available, for example), but just because it is not still implemented (although there was the requests about adding this feature). in meantime, you can use the usual trick: enclose the whole module text (or at least these "instance" declarations) in the [d|...|] parentheses and generate all additrional definitions using analysis of program text instead of analysis of reified typing information. at least, this way you can implement all what you want without waiting while GHC team will change something in TH/SYB. and, imho, main feature of SYB is not generation of RTTI (run-time type information) but inventing of cool combinators to process data structures dynamically, without prior knowledge of the exact type structure. that is a really far beyound of my own abilities -- Best regards, Bulat mailto:bulatz@HotPOP.com

waldmann:
With Data.Generics, we can get an object's type, constructor and fields. I think there should be way to get the object's class(es) and methods. E. g. I want to find out whether the object's type implements Show, and if so, call the show method (and if not, call some replacement). See http://www.haskell.org//pipermail/haskell/2005-November/016992.html see also http://java.sun.com/docs/books/tutorial/reflect/
Depending on how evil you are, you can already do this. Call the show, and if it doesn't exist you can catch the exception that is thrown (a NoMethodError). Lambdabot actually does this when doing some fun dynamic composition of plugins. Here's a sample: catchError (process m a b cmd str) (\ex -> case (ex :: IRCError) of (IRCRaised (NoMethodError _)) -> process_ m cmd str _ -> throwError ex)) Cheers, Don

Donald Bruce Stewart wrote:
Depending on how evil you are, you can already do this. Call the show, and if it doesn't exist you can catch the exception that is thrown
Brilliant. By the way, this idea also solves the problem of not being able to define defaults for record fields, like so: import Control.Exception data Thing = Thing { foo :: Int, bar :: Int } deriving Show wrap :: Thing -> IO Thing wrap x = ( foo x `seq` bar x `seq` return x ) `Control.Exception.catch` \ _ -> ( foo x `seq` return $ x { bar = 2 } ) `Control.Exception.catch` \ _ -> ( bar x `seq` return $ x { foo = 4 } ) `Control.Exception.catch` \ _ -> return $ Thing { foo = 4, bar = 2 } main = do wrap ( Thing { foo = 5 } ) >>= print wrap ( Thing { bar = 7 } ) >>= print wrap ( Thing { } ) >>= print -- -- Johannes Waldmann -- Tel/Fax (0341) 3076 6479/80 -- ---- http://www.imn.htwk-leipzig.de/~waldmann/ -------
participants (3)
-
Bulat Ziganshin
-
dons@cse.unsw.edu.au
-
Johannes Waldmann