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 ...


38

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 ...


28

Many Lispers will tell you that what makes Lisp special is homoiconicity, which means that the code's syntax is represented using the same data structures as other data. For example, here's a simple function (using Scheme syntax) for calculating the hypotenuse of a right-angled triangle with the given side lengths: (define (hypot x y) (sqrt (+ (square ...


23

A dissenting opinion: Lisp's homoiconicity is far less of a useful thing than most Lisp fans would have you believe. To understand syntactic macros, it's important to understand compilers. The job of a compiler is to turn human-readable code into executable code. From a very high-level perspective, this has two overall phases: parsing and code ...


19

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 ...


18

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, ...


12

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 ...


12

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 ...


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

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 ...


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 ...


11

As a rule, you should only use macros, when a better alternative does not exist. They should not be used to generate code; you should simply write the code instead (if the code is type-agnostic, write a template instead). They should not be used to define constants; constants should be defined using one of these: (static) constexpr/const variables, ...


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

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

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 ...


9

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 ...


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 ...


9

Using macros to create code that's syntactically identical to C but semantically different is almost always evil, especially in an unsafe language like C where the fact that something compiles in no way guarantees it actually has defined behavior at run time. If you must use a macro for something, you generally want to make it clear that a macro is being ...


9

When are macros idiomatic and when should they be avoided? Macros are idiomatic only when there is no alternative to their use. Examples are include guards (they are the only portable form), embedded domain-specific languages, special compiler support not available through other language features (embedding built-in macros like __FILE__, stringifying ...


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 its ...


8

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 ...


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

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 ...


7

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 ...



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