Jump to page: 1 2 3
Thread overview
Macros
Aug 16, 2001
Richard Krehbiel
Aug 16, 2001
Richard Burk
Aug 16, 2001
Charles Hixson
Aug 17, 2001
Richard Krehbiel
Aug 17, 2001
Kent Sandvik
Aug 17, 2001
Richard Krehbiel
Aug 17, 2001
Charles Hixson
Aug 17, 2001
Richard Krehbiel
Aug 18, 2001
Tim Sweeney
Aug 18, 2001
Brent Schartung
Aug 20, 2001
Rajiv Bhagwat
Aug 20, 2001
Tobias Weingartner
Aug 21, 2001
Walter
Aug 22, 2001
Walter
Aug 21, 2001
Rajiv Bhagwat
Aug 21, 2001
Walter
Aug 20, 2001
Richard Krehbiel
Aug 20, 2001
Charles Hixson
Oct 26, 2001
Sean L. Palmer
Oct 28, 2001
Axel Kittenberger
C block comments nesting?
Oct 26, 2001
Sean L. Palmer
Aug 23, 2001
Roland
Sep 28, 2001
Ben Cohen
Sep 28, 2001
Ben Cohen
Sep 29, 2001
Walter
August 16, 2001
Okay, why is it that everybody thinks the C preprocessor is terrible and needs to be avoided?  C++ only has it for compatability; Java and C# and D don't have one.  I just don't get this one.

I personally have wished for *more* macro processing power.

Not for typedefs.  Not for constant definitions.  Not for #include files or guards.  For *macros*.

By "macros" I mean something that lets a programmer add power to the language translator.  Something with access to the type system of the compiler.  So I could write a generic macro that iterates through the members of any given structure and generate code to print them in context. So that I can write a package of macros that simplify binding SQL parameters, because it can detect data types.  So that I can write generics and templates using macros.

Cut from the language document:

"But [macros] have a downside:
Macros have no concept of scope; they are valid from the point of definition
to the end of the source. They cut a swath across .h files, nested code,
etc. When #include'ing tens of thousands of lines of macro definitions, it
becomes problematicalto avoid inadvertent macro expansions."

So, invent reasonable scoping and naming rules.  I don't need cpp specifically; I just want macros.

"Macros are unknown to the debugger. Trying to debug a program with symbolic data is undermined by the debugger only knowing about macro expansions, not themacros themselves."

This need not be true, even in C.

"Macros make it impossible to tokenize source code, as an earlier macro change can arbitrarilly redo tokens."

Um - I don't understand this at all.

"The purely textual basis of macros leads to arbitrary and inconsistent usage, making code using macros error prone. (Some attempt to resolve this was introduced with templates in C++.)"

Take the "purely textual basis" away, and give the macro language access to the type system.

"Macros are still used to make up for deficits in the language's expressive capabiltiy, such as for "wrappers" around header files."

But since you're fixing those language deficits, macros won't be used for that anymore.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@home.com (personal)



August 16, 2001
As far as providing some sort of macro language to the system I would
recommend that generics be used modelled after generics in Ada.  I programmed in

Ada83 for three years solid.  Generics did full type checking and allowed for
rapid
development of lists, stacks, etc of various types.  I highly recommend the
generics
model from Ada.  I have little experience with Ada95, but it extended the power
of generics and what little experience I had with it was quite impressive.
Unfortunately the project I was on was killed.  I have been doing C, C++, and
Java mostly since.  I agree that the template implementation in C++ is horribly
implemented.  In fact I used macros to do the same as templates in C++, but it
was
really more like using generics in Ada except without the strong type checking
of
Ada.  I believe that Java suffers from the lack of generics/templates.
Hopefully
when they add it, it will be modelled from Ada.  For D I believe that it would
be
wise to add generics.  When they are done well as in Ada they are most
powerful.

Richard Burk


Richard Krehbiel wrote:

> Okay, why is it that everybody thinks the C preprocessor is terrible and needs to be avoided?  C++ only has it for compatability; Java and C# and D don't have one.  I just don't get this one.
>
> I personally have wished for *more* macro processing power.
>
> Not for typedefs.  Not for constant definitions.  Not for #include files or guards.  For *macros*.
>
> By "macros" I mean something that lets a programmer add power to the language translator.  Something with access to the type system of the compiler.  So I could write a generic macro that iterates through the members of any given structure and generate code to print them in context. So that I can write a package of macros that simplify binding SQL parameters, because it can detect data types.  So that I can write generics and templates using macros.
>
> Cut from the language document:
>
> "But [macros] have a downside:
> Macros have no concept of scope; they are valid from the point of definition
> to the end of the source. They cut a swath across .h files, nested code,
> etc. When #include'ing tens of thousands of lines of macro definitions, it
> becomes problematicalto avoid inadvertent macro expansions."
>
> So, invent reasonable scoping and naming rules.  I don't need cpp specifically; I just want macros.
>
> "Macros are unknown to the debugger. Trying to debug a program with symbolic data is undermined by the debugger only knowing about macro expansions, not themacros themselves."
>
> This need not be true, even in C.
>
> "Macros make it impossible to tokenize source code, as an earlier macro change can arbitrarilly redo tokens."
>
> Um - I don't understand this at all.
>
> "The purely textual basis of macros leads to arbitrary and inconsistent usage, making code using macros error prone. (Some attempt to resolve this was introduced with templates in C++.)"
>
> Take the "purely textual basis" away, and give the macro language access to the type system.
>
> "Macros are still used to make up for deficits in the language's expressive capabiltiy, such as for "wrappers" around header files."
>
> But since you're fixing those language deficits, macros won't be used for that anymore.
>
> --
> Richard Krehbiel, Arlington, VA, USA
> rich@kastle.com (work) or krehbiel3@home.com (personal)

August 16, 2001
I don't really like macros.  Perhaps that should be "I really don't like macros".
However ..., perhaps instead:
1) OTOH, generics are quite useful.  They have been shown to work well when designed into a language.
2) And "some sort" of preprocessing would be useful.  However, since the language is designed to be embedded in HTML, perhaps it could also be embedded in XML.  This would allow any XML aware tool to act as a pre-processor.  It wouldn't need to be a basic part of the language definition, but could just be a ... reccomended practice?  Annex? Optional extra?  It would really be more a part of the "IDE" than of the language, but it could do type-aware substitutions creating "temporary files" that were fed to the compiler as needed.

August 16, 2001
Richard Krehbiel wrote:
> 
> Okay, why is it that everybody thinks the C preprocessor is terrible and needs to be avoided?  C++ only has it for compatability; Java and C# and D don't have one.  I just don't get this one.

As you rightly note, the C preprocessor isn't powerful enough for
general macro work. I think the usual position is that if you want
macros, you should be using a dedicated macro processor that's
better than C's, and that typedefs, constants, and inclusion
should be part of the language instead of a bag on the side.

> I personally have wished for *more* macro processing power.
> 
> Not for typedefs.  Not for constant definitions.  Not for #include files or guards.  For *macros*.

Have you looked into m4?

-Russell B
August 17, 2001
"Richard Krehbiel" <rich@kastle.com> wrote in message news:9lgk0b$243j$1@digitaldaemon.com...
> By "macros" I mean something that lets a programmer add power to the language translator.  Something with access to the type system of the compiler.  So I could write a generic macro that iterates through the members of any given structure and generate code to print them in context. So that I can write a package of macros that simplify binding SQL parameters, because it can detect data types.  So that I can write
generics
> and templates using macros.

I agree, there's something good about having the power to override certain restrictions put in place in the language. Yes it's like a dangerous knife, but sometimes a sharp knife is needed, as well. So I do miss the option of having some macro-processing, LISP has this power, and it's been used for very interesting solutions. This is more concerning the power to re-define statements and meta data, and not about the classical use of macros, i.e. smart inlining in order to try to produce tight code... --Kent




August 17, 2001
"Russell Bornschlegel" <kaleja@estarcion.com> wrote in message news:3B7C44FB.CC45479D@estarcion.com...
> Richard Krehbiel wrote:
> >
> > Okay, why is it that everybody thinks the C preprocessor is terrible and needs to be avoided?  C++ only has it for compatability; Java and C# and
D
> > don't have one.  I just don't get this one.
>
> As you rightly note, the C preprocessor isn't powerful enough for general macro work. I think the usual position is that if you want macros, you should be using a dedicated macro processor that's better than C's, and that typedefs, constants, and inclusion should be part of the language instead of a bag on the side.

I want a macro language that is *more* tightly integrated, with access to the type system, and a macro language that looks more like the subject language than an add-on.

So I can write a macro something like this:

macro trace_var(indent, var)
{
    printf("%*s%s %s=", indent, "", typename(var), name(var));
    if(promoted(typeof(var)) == typeof(int))
        printf("%d", var);
    else if(promoted(typeof(var)) == typeof(double))
        printf("%g", var);
    else if(typeof(var) == typeof(struct))
    {
        foreach(void m in membersof(arg))
        {
            trace_var(indent+2, m);
        }
    }
}

> > I personally have wished for *more* macro processing power.
> >
> > Not for typedefs.  Not for constant definitions.  Not for #include files
or
> > guards.  For *macros*.
>
> Have you looked into m4?

Actually, I've done a bit of work using m4.  I think it's really powerful :-) and really difficult to use.  :-(  The quoting rules always confuse me.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@home.com (personal)




August 17, 2001
"Kent Sandvik" <sandvik@excitehome.net> wrote in message news:9lhobc$at8$1@digitaldaemon.com...
>
> "Richard Krehbiel" <rich@kastle.com> wrote in message news:9lgk0b$243j$1@digitaldaemon.com...
> > By "macros" I mean something that lets a programmer add power to the language translator.  Something with access to the type system of the compiler.  So I could write a generic macro that iterates through the members of any given structure and generate code to print them in
context.
> > So that I can write a package of macros that simplify binding SQL parameters, because it can detect data types.  So that I can write
> generics
> > and templates using macros.
>
> I agree, there's something good about having the power to override certain restrictions put in place in the language. Yes it's like a dangerous
knife,
> but sometimes a sharp knife is needed, as well. So I do miss the option of having some macro-processing, LISP has this power, and it's been used for very interesting solutions. This is more concerning the power to re-define statements and meta data, and not about the classical use of macros, i.e. smart inlining in order to try to produce tight code... --Kent

Well, frankly, LISP is not the language for me.  :-/  The greatest exposure I've had to LISP is some programming in Emacs-LISP.

But what I do appreciate is that LISP's macros are very powerful, and that they look like LISP.

--
Richard Krehbiel, Arlington, VA, USA
rich@kastle.com (work) or krehbiel3@home.com (personal)



August 17, 2001
Richard Krehbiel wrote:
> ...I've had to LISP is some programming in Emacs-LISP.
> 
> But what I do appreciate is that LISP's macros are very powerful, and that
> they look like LISP.
> 
> --
> Richard Krehbiel, Arlington, VA, USA
> rich@kastle.com (work) or krehbiel3@home.com (personal)
> 
"...and they look like LISP." is a tricky one.  They sure do look the same.  But they don't act the same.  Their rules for parameter passing, e.g., are different.  And their run-time behavior is different.

Now of course, if it weren't different, there wouldn't be any reason to need it.  But it damages the internal unity of the language at the same time that it makes it more powerful.

If you're going to have macros as a distinct part of the language, then you need to enable them to be recognized at a glance, without being so obtrusive that it's hard to see anything else.  Syntax markers can be a good choice, but references as well as definitions need to be easily recognizable (and I find all upper case names QUITE UGLY), also, the marker needs to be linguistic rather than conventional.  Perhaps having macro names start with . followed by a letter (or an underscore?).  The hash mark for definitions is good.

But it would be better to design a language that didn't need macros.


August 17, 2001
"Charles Hixson" <charleshixsn@earthlink.net> wrote in message news:3B7D31A6.6020008@earthlink.net...
> But it would be better to design a language that didn't need macros.

IMHO that language is necessarily an interpreted one, because I ask specifically for full access to the type system.

Java comes pretty close; you can query class definitions, but the primitive types are troublesome.  You can make "generic" collections of Object, but the primitive types aren't objects.  And you can't do type checking at compile time either.

Java executables (.class files) carry their symbol tables, so that in the unlikely event that they're needed, they can be queried.  A purely compiled-to-native-code language shouldn't have that property.  So if the programmer's going to write code to inspect the type system, it'll need to execute during the compile phase - and that's what I call a macro language.




August 18, 2001
> Okay, why is it that everybody thinks the C preprocessor is terrible and needs to be avoided?

Because it's terrible and needs to be avoided, of course!

> C++ only has it for compatability; Java and C# and D
> don't have one.  I just don't get this one.

Historically (beginning with C), macro preprocessors have served as a kludge to compensate for a lack of language power and optimizer ability.  Macros were good an necessary in the C days, because you could often come pretty close to C++ style template programming if you were clever enough, using macros for casts and other tricks.  You could also use them to construct optimized code (i.e. by defining the body of a loop in a macro, and unrolling the loop 100 times with the macro).

With a modern language, these kludges should not be necessary.  If there is any particular case where you feel you could express a program more cleanly by using macros, then I recommend looking at that as a language or optimizer flaw to be fixed, and not a need for macros.

Unreal (the game) is probably a good production-code example.  It's around 250,000 lines of code and uses macros for the following:

1. To expose metaclass information (i.e. class names, default constructors that a serializer can call) -- like MFC's techniques.  All of this code would be unnecessary if the language supported classes as first-class objects (i.e. you can pass around a classref* which "represent" the class and exposes its static functions), static virtual functions, and static constructors.

2. To comment out large blocks of code.  Would be unnecessary if /*...*/ comments could be nested.

3. To implement debug-specific code.  This is actually unnecessary, a bad old habbit.  We would be just as well off having a global constant debug=0 or 1, and having if(debug) {...} instead of #if debug.

4. To implement platform-specific headers.  Only necessary because headers are necessary.

5. To perform template-style tricks.  If the language has a great facility for type dependency (whether like C++ templates, or more general like Haskell), all of these things would be unnecessary.  Even C++ templates aren't complete enough, i.e. there are no template typedefs (true type synonyms), and most production compilers have bizarre template bugs limiting what you can do.

I'm 100% sure the Unreal code would be simpler and cleaner if the language supported the above and all preprocessor support were eliminated.

-Tim


« First   ‹ Prev
1 2 3