Tag Info

Hot answers tagged

46

I think the main reason is that macros are lexical. This has several consequences: The compiler has no way of checking that a macro is semantically closed, i.e. that it represents a “unit of meaning” like a function does. (Consider #define TWO 1+1 — what does TWO*TWO equal? 3.) Macros are not typed like functions are. The compiler cannot check that the ...


37

Probably the biggest difference is that C macros are expanded in the preprocessing phase, before any other compiling is done, while C++ templates are part of compilation. This means that C++ templates are type-aware and scoped, among other things, and are not simple textual substitution. They can compile to real functions, and therefore avoid most of the ...


18

Scala makes this possible too (in fact it was consciously designed to support the definition of new language constructs and even complete DSLs). Apart from higher-order functions, lambdas and currying, which are common in functional languages, there are some special language features here to enable this*: no operators - everything is a function, but ...


16

The macro is (putatively) more efficient, as it doesn't involve a function call. It can be optimised more easily, as it just involves a pointer offset lookup. The function call allows linking against the same library even if the program was compiled without the macro definition - if it was compiled with a different header, or just with a rogue declaration ...


13

Haskell Haskell has "Template Haskell" as well as "Quasiquotation": http://www.haskell.org/haskellwiki/Template_Haskell http://www.haskell.org/haskellwiki/Quasiquotation These features allow users to dramatically add to the syntax of the language outside of normal means. These are resolved at compile time as well, which I think is a big must (for ...


12

Perl allows for pre-processing of its language. While this isn't often used to the extent of radically changing the syntax in the language, it can be seen in some of the... odd modules: Acme::Bleach for really clean code Acme::Morse for writing in morse code Lingua::Romana::Perligata for writing in Latin (for examples, nouns are variables and number, ...


11

What sorts of things do people actually end up doing with macros? Writing language extensions or DSL's. To get a feel for this in Lisp-like languages, study Racket, which has several language variants: Typed Racket, R6RS, and Datalog. See also the Boo language, which gives you access to the compiler pipeline for the specific purpose of creating ...


11

I am of the opinion that if a language has macros, they should be a well planned out and integral part of the language and not of the compiler. Example, Lisp's macro system is a very powerful integrated language feature and is subject to all the rules and regulations of Lisp itself. Counter-example, C/C++ macro system is separate from the language and ...


11

This is partly a question of semantics. The basic idea of Lisp is that the program is data that can itself be manipulated. Commonly-used languages in the Lisp family, like Scheme, don't really let you add new syntax in the parser sense; it's all just space-delimited parenthesized lists. It's just that since the core syntax does so little, you can make almost ...


10

Macros can, as Scott notes, allow you hide logic. Of course, so do functions, classes, libraries, and many other common devices. But a powerful macro system can go further, enabling you to design and utilize syntax and structures not normally found in the language. This can be a wonderful tool indeed: domain-specific languages, code generators and more, all ...


10

Version control systems are those systems that allows you to capture changes and create a history for files. That's their purpose and the main reason for which they were created. Therefore if you would like to record changes you should use a version control system, any one out there will do. Nevertheless you should still make and informed decision, and pick ...


10

Tcl has a long history of supporting extensible syntax. For example, here's the implementation of a loop that iterates three variables (until stopped) over the cardinals, their squares and their cubes: proc loopCard23 {cardinalVar squareVar cubeVar body} { upvar 1 $cardinalVar cardinal $squareVar square $cubeVar cube # We borrow a 'for' loop for ...


10

Byte code weaving and macros are two different things. Byte code weaving is a way to intercept function calls, so that you can inject some sort of functionality (generally a cross-cutting concern such as logging) into a function call, either before or after the function is executed. Byte code weaving is done at the byte code level, which means that it ...


10

The Lisp family of languages is a fuzzy concept. The key aspects seems to be Support for functional programming Macros Homoiconic (The text <=> The AST, eg Lisp's love of parens) Dynamically typed Garbage Collected The big place where Scala falls down in is 3. Scala is hilariously not homoiconic and this is not a bad thing necessarily. It does have ...


10

A decorator is basically just a function. Example in Common Lisp: (defun attributes (keywords function) (loop for (key value) in keywords do (setf (get function key) value)) function) In above the function is a symbol (which would be returned by DEFUN) and we put the attributes on the symbol's property list. Now we can write it around a ...


9

I mostly use macros for adding time-saving new language constructs, that would otherwise require a bunch of boilerplate code. For example, I recently found myself wanting an imperative for-loop similar to C++/Java. However, being a functional language, Clojure didn't come with one out of the box. So I just implemented it as a macro: (defmacro for-loop ...


9

Macros in both C and C++ are a text replacement mechanism. Because of that, you can't define a macro in one source file and use it in a different source file. What you can do is define a macro in a header file and include that header in both C and C++ source files where you want to use that macro. Such a header would need to contain only code that comes ...


8

Lisp macros combine a few distinct properties: Macros define new syntax <-> they use source-code as input Macros usually are run at compile-time Macros generate source-code The best applications make use of all of those aspects. Probably the most-well known example is the (loop ...) in Common Lisp, it wouldn't be anywhere close to it's usefullness ...


8

But yes, macros can be designed and implemented better than in C/C++. The problem with macros is that they are effectively a language syntax extension mechanism that rewrites your code into something else. In the C / C++ case, there is no fundamental sanity checking. If you are careful, things are OK. If you make a mistake, or if you overuse macros you ...


7

Take a look at this posting by Matthias Felleisen to the LL1 discuss list in 2002. He suggests three main uses for macros: Data sublanguages: I can write simple-looking expressions and create complex nested lists/arrays/tables with quote, unquote, etc. neatly dressed up with macros. Binding constructs: I can introduce new binding constructs ...


7

Ruby has a quite flexible syntax, I think it's a way of "extend the language within the language itself". An example is rake. It's written in Ruby, it is Ruby, but it looks like make. To check some possibilities you can look for the keywords Ruby and metaprogramming.


7

Extending the syntax the way you're talking about allows you to create domain specific languages. So perhaps the most useful way to rephrase your question is, what other languages have good support for domain specific languages? Ruby has very flexible syntax, and a lot of DSLs have flourished there, such as rake. Groovy includes a lot of that goodness. ...


7

Rebol sounds almost like what you're describing, but a bit sideways. Rather than define specific syntax, everything in Rebol is a function call - there are no keywords. (Yes, you can redefine if and while if you truly desire to). For example, this is an if statement: if now/time < 12:00 [print "Morning"] if is a function that takes 2 arguments: a ...


6

Prolog allows defining new operators which are translated to compound terms of the same name. For example, this defines a has_cat operator and defines it as a predicate for checking if a list contains the atom cat: :- op(500, xf, has_cat). X has_cat :- member(cat, X). ?- [apple, cat, orange] has_cat. true ; false. The xf means that has_cat is a postfix ...


6

Converge is another one non-lispy metaprogramming language. And, to some extent, C++ qualifies too. Arguably, MetaOCaml is quite far from Lisp. For a totally different style of syntax extensibility, but yet quite powerful, take a look at CamlP4. Nemerle is another extensible language with a Lisp-style metaprogramming, although it is closer to languages ...


6

Although they may be used to the same end, LISP macros are quite different from Java byte-code weaving plugins. LISP macros extend LISP syntax at the LISP source code level. Since LISP macros are written at the same level as other LISP code, they are a commonly used language feature. Java byte-code weaving plugins operate at the JVM level. While many ...


6

In Python (the language) the decorators cannot modify the function, only wrap it, so they are definitely far less powerful than lisp macros. In CPython (the interpreter) the decorators can modify the function because they have access to the bytecode, but the function is compiled first and than can be fiddled with by the decorator, so it's not possible to ...


6

I think this depends on what you mean by "compose". I would say that it's mostly true but can be taken too far. First, note that in the quote you cited aphyr didn't say "macros don't compose"; the phrase was "can't be composed functionally". That more limited claim is indisputably true. Macros in Clojure aren't values[1]. They can't be passed as arguments ...


5

The very definition of #pragma is that they are non-Standard. Features which are provided as Standard are provided in some other way. Making #pragma Standard would defeat the purpose of, well, #pragma. They are nothing more than a set of implementation extensions, which happen to coincidentally be the same.


5

Does it matter how they are implemented? The early C++ compilers were just pre-processors that fed the code to a c compiler, it doesn't mean C++ is just a glorified macro. Templates remove the need for a macros by providing a safer, more efficient and specializable (even I don't think thats a real word) way of implementing code for multiple types. There ...



Only top voted, non community-wiki answers of a minimum length are eligible