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

Unfortunately for me, they don't mention macros in this tour of rust. Even after reading the official book, I'm still not comfortable with macro and macro syntax. Do you have any recommendations?


Note that I wouldn't expect a beginner to Rust to care about writing macros at all. Macros are something that you might introduce to a project eventually in order to abstract over some project-specific boilerplate (and only as a last resort; there are usually better abstractions to reach for first).

I say this because someone coming from a functional language might be betrayed by their instincts here: it is relatively rare for Rust users to write macros themselves, and macro-heavy Rust code would generally be regarded as peculiar/unidiomatic.


It's true that writing macros is out of scope for an intro guide, but the first "hello world" example uses the println! macro so you have to understand how to use them right from the start. They're all over the standard library. I struggled with explaining this when writing my own guide to Rust - do you dive straight into explaining macro syntax in the first chapter, or just explain how this one macro works and move on? Or don't explain it at all, which is the (sensible) choice that this tour takes.

Unfortunately the language documentation isn't helpful either, looking at the docs for println! [0] doesn't explain the arguments that it takes (other than referring to format!, which is another macro [1]...) or what the return value of the macro is.

[0] https://doc.rust-lang.org/std/macro.println.html [1] https://doc.rust-lang.org/std/macro.format.html


> the first "hello world" example uses the println! macro so you have to understand how to use them right from the start

You don't "have to" understand the `println!` implementation in order to use it. It certainly helps like it does for any other API, but it can be treated as a blackbox, and still be able to use it.


This is the essence of teaching: planning out what to gloss over and explain later.

I see many tech:nerd people explain this bottom-up instead of bottom-down because they can’t imagine skipping details for later. The reality is that students are intrigued by “I’ll explain what that means later” and it builds interest.

I explain how our website works by first telling a big lie: your computer requests a webpage and we have one big computer that replied with the answer. I then explain that I just lied. I then break it down: a web page requires many elements. Each requested individually. I then explain we don’t have one big computer but a cluster behind a load balancer. I then explain the many benefits of a load balancer. Then I explain that the web cluster depends on databases and other services.

All-in-all I expose 5-6 “lies” as I break down each component.

I’ve gotten positive feedback from both non-developers, entry-level developers, and expert developers.

I’ve also seen people give a bottom up description and everyone was confused at the end.

Why do top-down descriptions work better even though they initially gloss over (lie) To the audience?

Because the high level description gives The audience a mental roadmap to follow. Then we back up and walk through that roadmap in more detail. Then we walk through again in even more detail.

The entire time the audience understands where we are going and fits each bit of new information into their mental model, expanding it as we go.

Here’s how it feels to be explained to in a bottom-up manner: imagine I spent an hour with you listing out left and right turns. At the end of the hour I tell you “and that’s how You drive from NYC fo San Francisco”. JFC, Tom, couldn’t you have started with that!?!?

Don’t be that guy.

An explanation isn’t a murder-mystery novel with a surprise ending. Start with “these butler did it” and work backwards from there.

At Bell Labs we had a saying about presentations: “first show us your conclusion slide. If we disagree, rewind to the first slide and show us your talk. You have our interest. If we agree, stop. We can all go to lunch early.”


I second this. I see too many people start with a bottom up explanation , which causes people to sour on the topic. It’s a mountain of information up front.

Some topics, this can’t be helped with as much, but in most cases, starting high level and progressively peeling back layers is a lot more effective.

That’s how most education is presented as well. It’s usually only domain experts who DON’T teach that think every little detail is valuable up front.


I think it's important to understand that println! is special (Rust forcing the ! goes a long way for that and is IMO an excellent decision, I hate "fake" macro functions in C). Although simply saying "this is a macro call, not a real function which is why it can do things a normal function call couldn't" is probably good enough for an intro.


Please file bugs when the docs aren’t helpful; this is good to know!


Thanks, I've given some thought on how to address this but haven't come to a real conclusion yet. It would be nice if there was a way to document macros with some kind of pseudo-function syntax, but then with macros you can express things which just aren't available in normal functions. println! is a good example because it basically exists to work around the fact that Rust doesn't have variadic functions (thank $diety) but then you'd have to express it with a signature that doesn't exist in the language. Or even more fundamentally, println! exists in two forms, one of which takes no arguments (and just prints a newline) and one which takes a format string and arguments. That's not easy to express in a single signature. I suppose it could all be written as prose like I've just done here.


I don't think any amount of docs could make the Rust macro syntax palatable. The problem is more fundamental, macros as they are currently implemented are a huge pain to write, even if you know what you're doing. Having to rely so much on recursion for instance adds a lot of complexity.

But on the other hand it means that people are less inclined to abuse them and they're a lot more hygienic than C-style macros...


> Having to rely so much on recursion for instance adds a lot of complexity.

I’ve written some fairly heavy Rust macro code, and I almost never need recursion— the repetition primitives generally prove sufficient for my needs. What are you doing that needs all the recursion?


I'm not sure that's the full story. You need macros in Rust for feature parity with, e.g. C++ templates with their metaprogramming capabilities, and C++ is definitely not a pure functional language.


It’s worth noting that C++ templates themselves are a purely functional language, and a Turing complete one at that


Feature parity with C++ is not a goal and neither should it be.


I do not see anything in zozbot234's comment that implies that Rust should strive for feature parity with C++. Some features, however, such as being able to use integer values as generic parameters, are arguably pretty useful.


Indeed. I think that's referred to as "const generics" in rust venacular


The Little Book of Rust Macros is a pretty good, but dense, overview of how macro_rules! can be used. (Procedural macros are a completely different beast).

https://danielkeep.github.io/tlborm/book/index.html


Also, there are a lot of uses of macro_rules! in the Rust compiler and standard library repository.

https://github.com/rust-lang/rust/search?q=macro_rules&type=

Looking at some of those and reading https://doc.rust-lang.org/rust-by-example/macros/syntax.html and https://doc.rust-lang.org/reference/macros-by-example.html can potentially be instructive.


I recommend https://m.youtube.com/watch?v=q6paRBbLgNw

Jon Gjengset series Crust of Rust is amazing.


Depending on your preference for macros, run "info m4" or "info cpp" to read the documentation.

You can use both. You can run them more than once, perhaps changing the source with a sed or perl script between passes.


Native Rust macros are generally preferred, because they prevent a few classes of error that can happen with the purely textual macros cpp and m4 use. In particular, they prevent unpaired delimiters from appearing in the macro expansion and name collisions between the macro implementation and the callsite.




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

Search: