views:

252

answers:

7

Hello, I'm making a simple compiler for a simple pet language I'm creating and coming from a C background(though I'm writing it in Ruby) I wondered if a preprocessor is necessary.

What do you think? Is a "dumb" preprocessor still necessary in modern languages? Would C#'s conditional compilation capabilities be considered a "preprocessor"? Does every modern language that doesn't include a preprocessor have the utilities necessary to properly replace it? (for instance, the C++ preprocessor is now mostly obsolete(though still depended upon) because of templates.)

+6  A: 

The preprocessor is a cheap method to provide incomplete metaprogramming facilities to a language in an ugly fashion.

Prefer true metaprogramming or Lisp-style macros instead.

A. Wood
Well said. Anybody who designs a language today without macros or something equivalent should have their language design license taken away. See Converge (http://ConvergePL.Org/) for how to do a powerful compile-time metaprogramming system in a non-homoiconic language with lots of syntax.
Jörg W Mittag
+2  A: 

I think that preprocessors are a crutch to keep a language with poor expressive power walking.

I have seen so much abuse of preprocessors that I hate them with a passion.

Peter Tillemans
+5  A: 

C's preprocessing can do really neat things, but if you look at the things it's used for you realize it's often for just adding another level of abstraction.

  • Preprocessing for different operations on different platforms? It's basically a layer of abstraction for platform independence.
  • Preprocessing for easily adding complex code? Abstraction because the language isn't generic enough.
  • Preprocessing for adding extensions into your code? Abstraction because your code / your language isn't flexible enough.

So my answer is: you don't need a preprocessor if your language is high-level enough *. I wouldn't call preprocessing evil or useless, I just say that the more abstract the language gets, the less reason I can think for it needing preprocessing.

* What's high-level enough? That is, of course, entirely subjective.

EDIT: Of course, I'm only really referring to macros. Using preprocessors for interfacing with other code files or for defining constants is evil.

Oak
+1 for *It's basically a layer of abstraction for platform independence.*
Viktor Sehr
A: 

A preprocessor is a separated phase of compilation. While preprocessing can be useful in some cases, the headaches and bugs it can cause make it a problem.

In C, preprocessor is used mostly for:

  1. Including data - While powerful, the most common use-cases do not need such power, and "import"/"using" stuff(like in Java/C#) is much cleaner to use, and few people need the remaining cases;
  2. Defining constants - Why not just provide a "const" statement
  3. Macros - While C-style macros are very powerful(they can include statements such as returns), they also harm readability. Generics/Templates are cleaner and, while less powerful in a few ways, they are easier to understand.
  4. Conditional compilation - This is possibly the most legitimate use-case for preprocessors, but once again it's painful for readability. Separating platform-specific code in platform-specific source code and using common if statements ends up being better for readability.

So my answer is while powerful, the preprocessor harms readability and/or isn't the best way to deal with some problems. Newer languages tend to consider code maintenance very important, and for those reasons the preprocessor appears to be obsolete.

luiscubal
I think you are making the problem bigger than it is. Yes, getting the phase transitions right is a hard problem. But it is a *solved* hard problem: the Scheme community figured it out decades ago. You just need to steal their work.
Jörg W Mittag
In Scheme, there doesn't appear to be a preprocessor. Meaning that if it exists, it appears to have been done right.
luiscubal
Why would conditional compilation be the most legitimate use-case for a preprocessor? Delphi handles conditional compilation just fine without a preprocessor...
Marjan Venema
@Marjan Venema: Precisely. So even that use-case has better alternatives, which only reduces even further the need for preprocessors.
luiscubal
@luiscubal: ah, I didn't pick up on that inference...
Marjan Venema
A: 

It's your language so you can build whatever capabilities you want into the language itself, without a need for a preprocessor. I don't think a preprocessor should be necessary, and it adds a layer of complexity and obscurity on top of a language. Most modern languages don't have preprocessors, and in C++ you only use it when you have no other choice.

By the way, I believe D handles conditional compilation without a preprocessor.

Alex - Aotea Studios
for some reason, D feels like a fictional C++ extension which happens to have an actual compiler
Viktor Sehr
D has `static if` which is an `if` statement that gets evaluated at compile time instead of runtime.
Jörg W Mittag
A: 

It depends on exactly what other features you offer. For example, if I have a const int N, do you offer for me to take N variables? Have N member variables, take an argument to construct all of them? Create N functions? Perform N operations that don't necessarily work in loops (for example, pass N arguments)? N template arguments? Conditional compilation? Constants that aren't integral?

The C preprocessor is so absurdly powerful in the proper hands, you'd need to make a seriously powerful language not to warrant one.

DeadMG
+3  A: 
Norman Ramsey