Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Aside from Servo itself, this is the coolest and most ambitious piece of Rust code I've yet seen.

I haven't had the pleasure of using a language with a good macro facility. What other sorts of applications do macros have, aside from this and type safe println are there? Could one make a json or XML parsing library with this technique? Or a driver for a database? How does one go about acquiring an intuition for when to use or not use them?




Thanks for your kind comments. :)

> How does one go about acquiring an intuition for when to use or not use them?

Truthfully, I don't know. In this particular case, the benefits seem really clear: we get safety and performance increases.

But here's a caveat: the particular reason why this works well for regexes is because the common use case is to write the string literal corresponding to the regex into your program. This is what allows the macro facilities to kick in. For example, if the regex is derived from user input at runtime, then the `regex!` macro can't be used.

i.e., you can't do this:

    let restr = "a*";
    let re = regex!(restr);
The `regex!` macro must accept a string literal (or another macro invocation that produces a string literal).


I see. So maybe if you had a fixed XSD or XSLT at compile time you could emit a faster but specialized parser or transformer. But maybe that wouldn't work out so well in practice.

I did find an interesting slide deck from the scala universe that mentions something like F# type providers (among other things) as possible applications.

http://scalamacros.org/paperstalks/2014-02-04-WhatAreMacrosG...


A JSON or XML parsing library is certainly possible with procedural macros. I haven't had the pleasure of trying out Rust macros but if you are interested in macros in general then I suggest taking a look at the Nimrod programming language (http://nimrod-lang.org) as well as the talk on metaprogramming by the language's author: http://www.infoq.com/presentations/nimrod

The Nimrod standard library has many examples of what macros can do. For example, I have been working on an async macro (now part of the latest Nimrod release) which allows asynchronous function calls to be made in a similar fashion to ordinary blocking function calls. It's very similar to C#'s await. The way it works is that it transforms functions marked as 'async' into an iterator, while at the same time transforming any occurrences of 'await' into a yield.


I think you would ask yourself : can I compute this at compile time? (And is it useful to do so?) I don't really see how you could use that for a database driver, but for example you could create a library that uses macros to generate custom serialization/deserialization code to/from json (or whatever format) for your data structures.

(Edit: after a quick check this use case seems to be already covered by #[deriving(Encodable, Decodable)] in rust.)


You could use macros to perform compile-time checking of SQL query strings (and checking of any arguments bound to the query, as long as they're bound immediately instead of being bound later).


I guess a good rule of thumb is 'could I make this safer and faster by writing more repetitive code?'. If the problem can be solved by writing code explicitly but that quickly becomes too verbose (or error-prone), macros are a good technique.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: