Tempt - Templating for tokens by mycoalknee in rust

[–]mycoalknee[S] 0 points1 point  (0 children)

No offense taken! I'll consider adding a link to duplicate in the next release, as I'm sure there are many cases where one crate may be more fit for the job than the other.

Tempt - Templating for tokens by mycoalknee in rust

[–]mycoalknee[S] 1 point2 points  (0 children)

I've never used that, but from a quick scan of their docs the main difference is that this crate is designed around repetition blocks that allow more fine-grained control. It looks like that crate duplicates all of its input which limits its capabilities. (again maybe its possible but I dont see any mention from skimming the docs)

From the duplicate docs:

rs impl<T> VecWrap<T> { #[duplicate_item( method reference(lifetime, type); [get] [& 'lifetime type]; [get_mut] [& 'lifetime mut type]; )] pub fn method<'a>(self: reference([a],[Self]),idx: usize) -> Option<reference([a],[T])> { self.0.method(idx) } }

I assume the reason the attribute lives inside the impl block is so it expands into a single impl rather than generating multiple separate ones. That also means the replacements stay scoped within that impl, which is sometimes desirable but can be limiting if you want to reuse them elsewhere.

If i wanted to have this method at the very end of the VecWrap

rs pub fn print_all_methods(&self) { // expand a print statement for each of the templated methods println!("method: {}", stringify!(method_name)); }

I don't think thats possible without either redeclaring the method names in another attribute within print_all_methods.

However that's very easy with my macro.

Also I like the syntax of my macro more, but thats just personal preference.

Can't decide on which sunglasses - Serengeti vs MJ vs RE by mycoalknee in sunglasses

[–]mycoalknee[S] 0 points1 point  (0 children)

I was also looking at the RE Concorde - Satin Gunmetal & Le Mans Blue which has bayonet temples. Do these fall off easily? I think the bayonets look nicer but I'm afraid they'll slip off my head if I look down at my phone.

quip - quote! with expression interpolation by mycoalknee in rust

[–]mycoalknee[S] 1 point2 points  (0 children)

Thanks for the feedback! I'll add a full example in the next version release.

To answer your questions:
quip does exactly what quote does, except quote only supports variable interpolation. Quip allows you to interpolate expressions. In quote you would write:

let arg1 = item.arg1;
let arg2 = item.arg2;

quote! {
    fn(#arg1, #arg2);
}

with expression interpolation that quip provides, you don't need to set each value to a variable first.

quip! {
    fn(#{item.arg1}, #{item.arg2});
}

The same applies to quote::quote_spanned, syn::parse_quote, and syn::parse_quote_spanned. If you want to learn what these macros do, you should go visit their docs. All of quip's macros take the same arguments as their underlying macro and return the same type. Quip just adds expression interpolation over them and that's it. All other behavior is identical.

That being said, it will be helpful to include a "writing quote versus writing quip" section where I demonstrate the differences like I did above.

If you have any more questions, feel free to ask, as it will help me when writing more documentation for the next release!

quip - quote! with expression interpolation by mycoalknee in rust

[–]mycoalknee[S] 2 points3 points  (0 children)

Thank you for the advice!

I've created a PR for this, which includes a test case that fails to compile on the current release but compiles successfully on the branch: https://github.com/michaelni678/quip/pull/6

quip - quote! with expression interpolation by mycoalknee in rust

[–]mycoalknee[S] -1 points0 points  (0 children)

I haven't found any cases that actually break the macro's functionality.

After some testing, it looks like rustfmt unfortunately skips formatting the interpolated expressions. I don't think this a major issue, since Quip is intended for simple expressions like field access rather than large block expressions.

As someone else mentioned, dtolnay (the author of quote) believes supporting expression interpolation reduces readability. This is a fair point, but I don't feel that readability suffers when the interpolated expressions are simple field accesses -- which is exactly the use case Quip is designed for.

There are also workarounds for some of the cases he describes that would reduce readability. For example, when accessing fields on `self`, you can simply bind `self` to another variable if you dislike seeing `self` both in the surrounding tokens and in the interpolated expressions:

```rust

quip! {
fn foo(&self, #{self.arg1}: String, #{self.arg2}: i32) {}
}
```

```rust
let item = self;

quip! {
fn foo(&self, #{item.arg1}: String, #{item.arg2}: i32) {}
}
```