[Haskell-cafe] Monad of no `return` Proposal

Kosyrev Serge _deepfire at feelingofgreen.ru
Tue Oct 6 09:16:32 UTC 2015

Doug McIlroy <doug at cs.dartmouth.edu> writes:
>> littering the code with #ifdefs
>>  Bonus points for keeping the #ifdefs centralized
> Littering is the right word. "Bonus" is merely less negative points.
> It is ironic that the beautiful Haskell should progress by
> adopting the worst feature of C. #ifdef is a sticking-plaster
> for non-portable code. It is inserted at global level, usually
> to effect changes at the bottom of the code hierarchy. (Maybe
> in Haskell it should be a monad, in competition with IO for
> the outermost layer.)
> Plan 9 showed the way out of ifdef, by putting (non-ifdef-ed)
> inescapably nonportable code, such as endianity, in compilation
> units and #include files in a distinct part of the file system
> tree selected by the shell. 
> Another trick is to use plain if rather than #if or #ifdef,
> and let the compiler optimize away the unwanted side of the
> branch.
> In any event, #ifdef is, as Simon evidently agrees, telling
> evidence of non-portability. It is hard to imagine an uglier
> "solution" to keeping up with the drip-drip-drip of Haskell
> evolution.

By the nature of the problem -- that is, because we want to isolate the
compiler as much as possible -- the conditionalization must be performed
as a separate pass.

The conclusion is that some sort of pre-processor is inevitable.

The remainder of the available choice space is about how ugly this
pre-processor must be -- and indeed, CPP tends towards the undesirable
end of the spectrum.

As an example of the opposite end, consider Common Lisp, which:

  1. reifies READ as the third processing phase (macroexpansion[1] and actual
     compilation being the other two)
  2. operates at expression granularity
  3. makes the full power of the language available to support the
     decision process of what subexpressions are available in which

As a rough example of how this works:


I don't know how much of Common Lisp preachery the list have suffered
over the years, but I can't help but find this uniformity between the
three parts of the language very appealing:

  - syntax-level of READ
  - macro-level of MACROEXPAND
  - semantics-level of the post-MACROEXPAND part of EVAL

Maybe, just maybe, Haskell could borrow something from that..

с уважениeм / respectfully,
Косырев Серёга
1.  Macroexpansion is actually defined by the ANSI CL standard to be a
    part of minimal compbilation, but for the purposes of illustration
    it makes sense to distinguish between them.

More information about the Haskell-Cafe mailing list