I've been a Java and VB.Net programmer for about 4 years and a C# programmer for about 6 months. I've also used a bunch of dynamic languages like Perl, Python, PHP, and JavaScript.
I've never had a need for a preprocessor.
My question is: why do you see such extensive use of preprocessors in C, C++, and Objective-C but rarely (or never) see it in languages like Java, C#, or Scala?
Modern languages have the preprocessor included in the language itself! For C++, the preprocessor is needed only for module management and conditional inclusion for example which is very useful.
I believe it was a separate tool, because compilers were not one-tool as we know them today. I heard that very old C compilers used to produce the tokens to files, then do the rest of compilation in separate stages. The main reason I can think of is that memory and other resources were very scarce compared to what we have today.
You should look a bit more closely at Perl. Perl supports source filters, which are basically custom Perl pre-processors written in Perl :)
I disagree with what seems to be the going consensus where that cpp is un-necessary in modern languages. I have a lot of cases where I've got 3 slightly different versions of the same program, and I want to be able to make a bunch of changes for each version. With CPP, I can put them all in #if #else blocks, and I can define the #if at the compile line. in Java, I need to create some sort of static global and initialize it at compile time. I never got that to work properly.
The preprocessor in C and C++ has two different functions
pulling files together in the build process - languages like Java et al. have their own mechanisms like import to do this
performing textual substitutions - this is still needed to certain extent in C, but C++ can do it (for the most part) better using templates
So both C and C++ need it for the first of these, but C++ can junk it for the second, although it can be useful even in C++ - see this question from earlier today.
You can be sure that the modern language is written in C or C++, and in that implementation itself there are macros. You need them to deal with operating system differences for one thing. The dynamic / higher-level languages wrap, and hide many of the things that somewhere at the bottom, you need macros for.
Also, macros are used for speed sometimes. In dynamic languages, speed isn't as crucial.
The reason why you don't see the preprocessor used in Java, C#, or Scala is that those languages obviously don't have one.
One of the common uses for the C preprocessor is to help provide platform-specific code. Since C (I'm including C++ and Objective-C here) is a low-level language that needs to interface with the operating system directly, in portable code there must necessarily be different sections of the code compiled for different operating systems. You can find extensive examples of this sort of thing in a mature, highly portable code base such as zlib.
As a simple example, to close a network socket one must do something like this (at some level, this can certainly be wrapped in a function but it has to exist somewhere):
Newer languages that run on VMs do not need the different platform-specific sections of code, and can be written against the single, portable standard library.
The preprocessor also provides a way to define constants in C, which are provided by other, better, language features in newer languages.
In The Design and Evolution of C++, Bjarne Stroustrup stated that he wanted to remove the dependency on the preprocessor in C++, but was not successful.