
On Friday 16 April 2004 13:25, Wolfgang Jeltsch wrote:
The very big problem with the preprocessor approach is, in my opinion, that it's awkward to add a new platform. With Robert's approach you just add some new files and don't touch the existing code. With the preprocessor approach you need write access to the source code of the library in question, I'd say.
I find that it works a little differently in practice (when writing C, at least): 1) You write the code for one platform. 2) To add a second platform, you refactor the code by designing a portable interface to the functionality of the two platforms and splitting the code into a portable top half and two platform specific bottom halves. [In practice, the first two steps are often combined since many of us develop for two platforms at once.] 3) You add a few minor variations on the original platforms with little effort. For very closely related platforms (Win98 and Win2K, Debian and Redhat, versions 3.4 and 3.5 of <whatever>), you might have just one or two lines of changes. Suppose you need to change just one line out of 100 lines of code, do you further subdivide the platform-specific module, do you use ifdef or do you cut and paste 100 lines of code. [Complication: the person doing the port might not have access to the original platform so they can't test the modified code. No problem if you're writing a completely fresh implementation but a major issue if you have to refactor an existing implementation.] 4) You try to port it to a less familiar platform: Mac, HPUX, etc. which views the world from a different angle from Unix and Windows and have to change the design of the portable interface to all the implementations. This requires that you change the code in all implementations. [Complication: again, you may not have access to the other platforms.] Refactoring the code into multiple modules can play a part in porting code but conditional compilation plays an important role too. In particular, if you find yourself changing code that you can't test, you can use conditional compilation to leave the bulk of the code unchanged so that simple tools (e.g., diff) can help you hand-check the changes you can't check. Of course, we don't see this in Haskell much but that's because we don't try very hard to support multiple versions of a library... -- Alastair Reid