Hi - here is an exchange that was off-list by accident:

---- Original Message ----
From: Brian Smith
To: Brian Hulley
Sent: Tuesday, August 22, 2006 5:50 AM

(Brian, I see that my last reply only went to you and so I forwarded
it to the list. Since you replied to me directly, I am responding to
you directly. Feel free to forward this to the list if you want).

On 8/21/06, Brian Hulley <[EMAIL PROTECTED]> wrote:
The paper "Template meta-programming for Haskell" suggests
that Template Haskell should be able to do everything that CPP
is used for at the moment,  such as conditional compilation, macros
etc, so this might be a possible option, though I have to admit apart from reading the paper and doing a few experiments with it I don't know enough about the current state of TH to know if it would be a viable replacement at the moment.

I am very interested in TH and I hope to give it a thorough workout
on an upcoming project. Until then, I don't know enough about it to
compare it to CPP. But, I think that in an Editor/IDE, a restricted
CPP would be much easier to implement than TH.

I've got a feeling that even allowing #define could break the
invariant that a module only has one meaning in a program, since #define changes the state of a symbol that's not yet been mentioned just as #undef changes the state of a defined symbol eg:


    module P where
    #define Bar
    import R

    module R where
    #ifdef Bar
            import S
    #else
            import T
    #endif

    module Q where
    import R

I think that this program will only compile if it is split into three
files, P.hs, R.hs, and Q.hs. There would be two scopes for CPP
macros: global (each macro is bound to exactly one value for all
modules, and it cannot be undefined or redefined) and file/module
(the macro is bound exactly once in a module and that binding is not
visible to other modules). Except for the "exactly once" part, this
is how GHC and cpphs already work.
So, in your example, let's assume there is no global binding for
"Bar"--if there was, then there would be a redefinition error in
P.hs. Then, P.hs defines Bar, but this binding is in scope only
inside of P.hs--R.hs does not "see" Bar as being defined. Further,
since R.hs does not contain a binding for "Bar," so module R will
always import module T and never module S.
A more concrete example is this:

module P where
#ifdef __GHC__
    import P.GHC
#else
    import P.Haskell98
#endif

In your editor/IDE you might want to support multiple Haskell
implementations. So, sometimes __GHC__ will be defined (when in GHC
"mode") and sometimes it won't. But, I recommend to handle this in
the same way that IntelliJ handles the JDK setting. That is, if the
user wants to switch the implementation he is using (even
temporarily), then when he does so, the whole program gets
reanalyzed. If the user wants to work in Hugs mode and GHC mode in
the same time, then he should create two projects in the IDE. In one
project, the implementation will be set to GHC, and the other one
Hugs. He will have to define output paths, etc. such that the two
project's ouitput files do not overlap even though their sources
will. Then, analyze each project seperately. This technique also
allows the user to build a version of the project against, say, HaXml
1.14, and other version against 1.15.

Much as I'd like to not have to deal with CPP, I agree that on
a practical realistic level it's not going to go away immediately,
but at least the guidelines you posted give a good starting point
for library authors to gradually try and reduce the dependence
on the preprocessor, if they are motivated to (which they
probably aren't ;-) )

Right. Plus, if we follow the guidelines I proposed very strictly,
then we can more easily picture what is required of a CPP
replacement. For example, if the guidelines are too prohibitive, then
we will know we need something more powerful like TH. If the
guidelines do not result in any practical loss of functionality, then
we know that we can get by with a much simpler configuaration
language.

I had a wild idea of a tool to eliminate CPP from a source
tree by first generating the set of N pre-processed source trees
(ie now pure Haskell) then running some analysis tool over these
trees to automatically factor out common code, but this would
probably be a major undertaking.

That would definitely be an interesting project, and it would be
useful for other things as well (The duplicate code detection part.)


Cabal seems to help a lot - Edison and ByteString both built on
my machine with no trouble at all. I think the more everything can
be done in Haskell the better it will be.

I agree. But, I also want it to be easy to reuse C-based libraries
whenever possible. That way, we can spend more time writing code in
Haskell that does new things instead of reimplementing old ideas in
it.

You mentioned that library maintainers might not be motivated to make
such changes. I think that people will modify their libraries if
there are compelling tools that need those modifications. In fact, I
think people would even be willing to break previous commitments to
backwards compatibility if there was any benefit to doing so--I mean,
who really uses the latest version of HaXml with GHC 5.x or Hugs
2002-xx-xx?
If there was an IntelliJ-level IDE for Haskell, and people were
writing "real world" programs in Haskell, then somebody would get
around to modifying libraries to work for "real world" programs built
using such a tool. Or, somebody that had a commercial interest (a
Haskell consultant or an IDE vender) might make these modifications.
- Brian
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to