
Robert Will wrote:
Yes, apart from the use in Macros and such, preprocessing is really a workaround for problems that should not be there. That's why every new programming language comes without a preprocessor, but after some time when incompatibilities arise, a preprocessor appears. That's because programmers tend to do a "local fix" instead of eliminate the root problem, that is, incompatibilities between systems.
Well, I hate to repeat myself, but this oversimplifies things a bit and ignores the fact that macros are quite useful as a syntactic abstraction, see one of my previous posts. One of the main goals in writing good SW is avoiding redundancy, and if the language in question doesn't allow us to abstract what we want to do several times, let's use macros! It's infinitely better than using cut-n-paste with slight variations. The real question should be what preprocessor to use. Admittedly, CPP is not ideal for Haskell, because it's totally unaware of the language it is processing, has no mechanisms for hygienic macros (see, e.g. Scheme), etc. Template Haskell might be a better choice, but only if one doesn't care about portability between different Haskell systems.
[...] I think what Haskellers (and others) can do in most cases is to factor out platform dependent parts to mini-modules which have different implementations but the same interface.
Again, this is a valid argument for toy programs/libraries, but there are cases where this is particularly bad: I definitely won't duplicate hundreds of "foreign imports", just because WinDoze DLLs have a different calling convention C. This would be a maintenance nightmare.
[...] So please no preprocessing in any code!
A more realistic plea would be: As little preprocessing as possible in a few selected places! Cheers, S.