Change:
Rust now supports in macro invocations, with a driving use case being able to write as analogy to the fixed sized vector syntax . However, there is no analogy to the repeat syntax for it: does not work.
I don't think rust-lang/rfcs is relevant here; that's relevant to because it provides a good way to initialize the with the correct capacity for the number of arguments. But with your there's no use for counting arguments. The array syntax requires the element to be . Does your proposed syntax have the same requirement? Or does it require instead? Offhand it looks like it's just shorthand for , which uses the bound. I'm also not convinced that we need any shorthand for . It's already reasonably short. itself is useful because there's no one-line equivalent that can be written as a function (because it needs to move each value, so it can't take a slice, and we don't have integral generics, so it can't take a fixed-size array). FWIW, extending to support syntax does not actually require a procedural macro, as long as it's being translated into . It just needs a new matcher to the top of the macro (not the bottom, that doesn't work), making the whole macro look like
Oh right, I totally got the dependency on backwards. I still think it would make sense to mirror the syntax of , it could just dispatch to as you said. This should either involve a bound and an arbitrary value on the premise that can only be constructed at runtime, or a bound and a requirement for the to be a constexpr, to be semantically and syntactically identical to Whether or not to extend at all depends on how idiomatic its use is considered. Personally I always use instead of , for example.
Personally, I think supporting is a reasonable idea. And I think it should be literally equivalent to , i.e. no constexpr, and instead of . IIRC we want to eventually be able to provide an implementation of for all types that are (if they don't otherwise provide it), but in the meantime we tend to assume that any type that needs some sort of copying like that needs to implement . There are many good reasons why array construction uses instead of , but those reasons don't apply to . Given that, I would support a PR that modifies the definition of as I listed above.
What about expanding to i.e. don't require or .
That's inconsistent with array literals. I submitted a PR a while back as (closed due to inactivity) that an procedural macro that did have that behavior (of duplicating the expression instead of copying the resulting value), although it was not clear if this was behavior that anyone besides me actually wanted. But that was very explicitly trying to diverge from array initialization semantics; the request here for would be to try to match the semantics as reasonably as possible except using a instead of an array. Note that with your version the following code: would print "wat" 5 times, but the equivalent array expression only prints "wat" once.
FWIW, if you want that expression-duplicating behavior with , we already have that will do it (using a closure).
Yeah, if we want to emulate the syntax, then it should only evaluate the first expression once, or else you get weird and very rare bugs.
After introduced and changed the definition of , the desired syntax is pretty close to just work. Today, you'd expect to expand to: Except that it doesn't because the macro definition expects (expressions separated by commas) as arguments, but is not an expression (because is parsed as a token). To make this work, we'll have to change from being a MBE to a "procedural macro", where it retains pretty much the same expansion it has today, but it doesn't parse the arguments as a list, instead it just passes the full token tree to . (I'm skimming the details of this last part, but I think is doable) Anyhow, such change probably merits an RFC?
I don't think it needs an RFC. The syntax is defined as part of the core language for fixed-size arrays and should just be passing through to those.
I correct myself, this can be done using macros by example. This appears to work: Prints: (I would send a PR, but I'm on my way out)
It would be nicer if it could just pass through all of the tokens opaquely. I don't know how to do that or if it's actually possible.
Is there any advantage of doing it that way? I think the macro definition above covers all the initialization patterns we currently have. (modulo trailing comma, but that's easy to add) I'll be working with syntax extensions later today, I'll check whether this is feasible or not, and report it here.
It's certainly doable, here's an . I'll reproduce the important part of the README here for posteriority: expands into: Both and work as expected, and things like and fail to parse, and the error message points to the right span. The implementation is way longer (100 lines) than the current macro by example though. Do let me know if I should send a PR with the syntax extension version or with the macro by example version.
It seems to me that this can be done via the following (the hack is a work around for ).
If it can be done with just , we should use that.
+1 to the syntax addition

Discussion:
<del> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT </del> <ins> // Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT </ins> // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. //

#[macro_export] #[stable] macro_rules! vec { <ins> ($x:expr; $y:expr) => ({ let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$x; $y]); $crate::slice::SliceExt::into_vec(xs) }); </ins> ($($x:expr),*) => ({ let xs: $crate::boxed::Box<[_]> = $crate::boxed::Box::new([$($x),*]); $crate::slice::SliceExt::into_vec(xs)

<ins> // Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. pub fn main() { assert_eq!(vec![1; 3], vec![1, 1, 1]); assert_eq!(vec![1; 2], vec![1, 1]); assert_eq!(vec![1; 1], vec![1]); assert_eq!(vec![1; 0], vec![]); } </ins>