@@ -174,24 +174,22 @@ we hope for a solution to replace CPP to do conditional compilation.
174174
175175There are the following challenges when formatting a module with CPP:
176176
177−* GHC parser won't accept anything but a valid, complete module.
177+* GHC parser won't accept anything but a valid, complete module. Therefore,
178+ formatting the Haskell code between CPP directives is not an option.
178179
179−* To preserve CPP directives they must be either removed from input and
180− saved in some sort of structure or turned into a special sort of comments
181− and restored later, but that is not easy because then the formatting logic
182− itself should somehow be aware of CPP directives (mainly conditiionals)
183− and avoid performing transformations that may lead to incorrect Haskell in
184− the end. This is much, much harder than simple pretty-printing we want to
185− do.
180+* Ignoring the CPP directives and formatting the Haskell code can change
181+ the meaning of the Haskell code. An example follows.
186182
187−Here is an example that proves that CPP is hard to support if possible at all.
188183Let's suppose that we want to format the following snippet of code:
189184
190−```haskell
191−f = f1
185+```
186+$ cat test.hs
187+main = print (g && f1)
192188 where
193− f1 = g
194−#if C1
189+ f1 = h
190+ where
191+ h = True
192+#ifdef C1
195193g = g1
196194 where
197195 g1 = g2
@@ -199,50 +197,29 @@ g = g1
199197 g2 = False
200198#else
201199 g = True
202−#end
203−```
200+#endif
204201
205−After commenting CPP directives we get:
202+#ifndef C1
203+g = False
204+#endif
206205
207−```haskell
208−f = f1
209− where
210− f1 = g
211−{-[#if C1]-}
212−g = g1
213− where
214− g1 = g2
215− where
216− g2 = False
217−{-[#else]-}
218− g = True
219−{-[#end]-}
206+$ runhaskell -XCPP test.hs
207+True
220208```
221209
222−Then, after formatting we get:
210+At the time of this writing, formatting this program with `hindent`
211+produces the same output we would get if the `CPP` directives were
212+considered comments:
223213
224−```haskell
225−f = f1
226− where
227− f1 = g
228−{-[#if C1]-}
229−g = g1
230− where
231− g1 = g2
232− where
233− g2 = False
234−{-[#else]-}
235− g = True
236−{-[#end]-}
237214```
238−
239−And finally, we uncomment CPP directives:
240−
241−```haskell
242−f = f1
215+$ hindent test.hs
216+$ cat test.hs
217+main = print (g && f1)
243218 where
244− f1 = g
245−#if C1
219+ f1 = h
220+ where
221+ h = True
222+#ifdef C1
246223g = g1
247224 where
248225 g1 = g2
@@ -250,12 +227,29 @@ g = g1
250227 g2 = False
251228#else
252229 g = True
253−#end
230+#endif
231+
232+#ifndef C1
233+g = False
234+#endif
235+
236+$ runhaskell -XCPP test.hs
237+False
254238```
255239
256−Now the definition of `f` is broken when `C1` doesn't hold.
240+Running the formatter causes the output of the program to change
241+from `True` to `False` when `C1` is not defined.
242+
243+A solution could be to make the formatter more careful with CPP
244+directives, constraining how directives can be inserted in Haskell
245+code to avoid changing the meaning by reformatting. But
246+this would introduce additional complexity, and the problem would
247+need to be solved repeteadly for every tool out there which wants
248+to parse Haskell modules. If CPP is replaced with some language
249+extension or mechanism to do conditional compilation, all tools
250+will benefit from it.
257251
258−Therefore, CPP should not be supported. If the CPP extension
252+Therefore, CPP won't be supported. If the CPP extension
259253is enabled, we should signal an error right away.
260254
261255### Printing