Skip to content

rough draft of macros chapter #1554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 8, 2018
Merged

rough draft of macros chapter #1554

merged 2 commits into from
Oct 8, 2018

Conversation

steveklabnik
Copy link
Member

Fixes #1283

cc @abonander


### Function-like macros

Finally,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to look up what attribute this actually uses

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#[proc_macro] unless it changed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generate code to create a vector containing the specified elements.

There are some strange corners with `macro_rules!`. In the future, there
will be a second kind of declarative macro, with the `macro` keyword, that

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Macros 2.0 is intended to completely subsume macro_rules! once it's implemented and stabilized.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I thought my words here implied this, but let's be explicit!

will be a second kind of declarative macro, with the `macro` keyword, that
will work in a similar fashion, but fix some of these edge cases. With this
in mind, as well as the fact that most Rust programmers will *use* macros
more than *write* macros, we won’t discuss `macro_rules!` any further. To

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're downplaying their utility a bit here. Macros are great for repeated bits of code that doesn't extract easily into functions. The old try!() macro would be a good example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe; this matches my experience and the experience of most people I talk to. That said, I think downplaying them until macro exists is the right side to lean on. I'll relax this once we have them :)

of five string slices. We wouldn’t be able to use a function to do the same
because we wouldn’t know the number or type of values up front.

Let’s look at a slightly simplified definition of the `vec!` macro in Listing

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much detail are you planning on giving on declarative macros? I would cover simpler cases first before looking at repetition, and probably cover the different fragment types as well. It's also worth mentioning how macros can affect control flow unlike function calls, e.g. with the old try!() macro.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically none more than we've done here; we don't want to give a ton of guidance until macro macros exist.

We’ve introduced three new crates: `proc_macro`, [`syn`], and [`quote`]. The
`proc_macro` crate comes with Rust, so we didn’t need to add that to the
dependencies in *Cargo.toml*. The `proc_macro` crate allows us to convert Rust
code into a string containing that Rust code. The `syn` crate parses Rust code
Copy link

@abonander abonander Oct 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would explain proc_macro as the API that the compiler provides to proc macro crates to read and manipulate Rust code, along with some related utilities such as error reporting.

the source that the macro is operating on makes up the input `TokenStream`,
and the code we produce from our macro is the output `TokenStream`.
We'll talk more about `TokenStream` when we actually build one of these
things. Finally, the function has an attribute on it; this attribute

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth explaining TokenStream up-front since it's referenced a number of times, at least so the reader has an idea of what it is.


Attribute-like macros are similar to custom derive macros, but instead of
generating code for `#[derive]`, they allow you to create new, custom
attributes of your own. For example, you might have something like this when

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should explain that attribute macros are more powerful because they can be applied in many places and not just to enums, structs or unions.

@steveklabnik steveklabnik merged commit c0d3b65 into master Oct 8, 2018
@steveklabnik steveklabnik deleted the proc-macros branch October 8, 2018 19:06
@steveklabnik
Copy link
Member Author

I've tweaked thanks to the review; @carols10cents let's go over this again later, but I'm going to merge what I have for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants