On 25-Jan-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Tue, 25 Jan 2000 18:12:32 +0100, jwit <[EMAIL PROTECTED]> pisze:
> 
> > What I'm getting at is some kind of way to get your
> > hands on an abstract syntax representation of a Haskell
> > expression/datatype/module, modifying it, re-typechecking it,
> > and then transforming it back into a Haskell value.
> 
> In other words you want to embed a Haskell compiler in your program.
> 
> It could be useful in practice sometimes, but it's a very far concept
> from a simple extension of the language to allow reflection.
> 
> Haskell is quite complex and can be compiled. IMHO the distance
> between the source code and the running program is very big in the
> case of Haskell. In other words, much is done at compile time instead
> of runtime. I like this principle, because it allows an elegant and
> powerful language with lots of static checking and optimizations,
> even though it makes reflection harder.
> 
> A function definition is the specification of what an identifier
> means in its scope, not the physical bytes of its compiled or
> source code. It can be inlined, instantiated, unfolded, analyzed for
> strictness, rewritten using RULES etc. - it does not have to appear
> in a physical form that can be examined by the program. C's dlopen()
> is different because C is a more low level language - in C there is
> a closer correspondence between the source function and the execution
> time object.

Well, Mercury has the same approach as Haskell, in the sense of being
a language which at least aims at being elegant and powerful with
lots of static checking and optimizations.  But we do support
dynamic linking (on some platforms), using an interface built
on top of dlopen() and dlsym().

Supporting dynamic linking need not inhibit optimization to any
significant degree, I believe.  At worst, you may need to disable
inter-module dead-function elimination.  Even that need only be done
if dynamic linking is used.

The next stage of support for reflection, being able to at run-time
get your hands on an abstract syntax representation of a Haskell
expression/datatype/module, does have a higher cost.  The compiler
needs to keep information around at run-time which it would otherwise
not need.  In Mercury we currently support that for types, but not
for expressions or modules.

One way of reducing the cost of this feature is to require
programmers to explicitly mark with some declaration
those entities for which the compiler should keep the
information around at run-time.  ISO Prolog takes this
approach; predicates for which you can use the
`clause/2' builtin to look up their definition
need to be declared "dynamic" using a `:- dynamic' declaration.
Ada takes the converse approach: by default, it keeps
around some tables to allow you to convert enumeration constants
into strings, but there is a standard pragma which allows
you to suppress that for a given enumeration.

The final stage -- being able to take a representation of
a Haskell expression, re-typechecking it, and then transforming
it back into a Haskell value -- does not actually _require_
any language or runtime support, I think; you can program
it in standard Haskell.  Though I guess some support might be
required if you want to introduce new types at run-time.

-- 
Fergus Henderson <[EMAIL PROTECTED]>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED]        |     -- the last words of T. S. Garp.

Reply via email to