#dup, the Duplication Macro, part 3

I want to see if moving to Discourse will improve the reception.

Since I’d probably need a code champion to add #dup to Swift, I want to know if what I proposed is even feasible first. If not, either by its entire design, or by little details, I want to update it before re-pitching.

Of course, it doesn’t work via (Objective-)C(++) text dumps. But it isn’t like Rust either. It think Rust works with tokens. My idea just adds a production for every type of comma-separated list, where that production is a call to #dup, then adds sub-productions for each list where a #dup call is an option. (There’s around 20 types of comma-separated lists. So that’s 20 new productions for the #dup calls, and around 20 modifications to existing productions to add #dup calls as options.)

I didn’t really understand what Rust does, based on my quick glance 7 months ago. So I don’t know if their system would ultimately be better. I feel that Rust’s system could produce token sequences that don’t actually form valid syntax, while my simpler syntax hopefully avoids that.

I don’t think introducing macros would be a good decision - Macros are one of the worst parts of c/c++ and it’s really refreshing beeing free from that stuff in Swift.


Macros aren’t bad, C & C++ just have the worst possible implementation of them. Lisp, Forth, and various other languages have much better metaprogramming support than simple text-substitution.


Certainly not all macros are bad, but macros are still clearly out of scope for Swift’s current stage of evolution.

So, no one wants to comment if this idea is feasible? Or if it’s underspecified? And if either, what’s wrong?

1 Like

It’s pretty hard for me to understand or evaluate. It looks like the primary motivation is generics features that don’t exist yet, is that correct?

Most likely true... but we already had a bunch of proposals (even some that are already implemented) which might interfere with metaprogramming features yet to come, so imho it would help a lot to know what might happen in this area.
(I personally hope very much that Swift won't ever have macros)

It can be the dual of (variadic) generics. Those take arbitrarily long comma-separated lists, while #dup generates them. However, we already have comma-separated lists, so #dup is currently useful.

We don’t have constexpr, so the duplication count is either a hard-coded integer literal or a duplication counter (which is an integer literal at resolution time).

Well, #dup isn’t a dumb text dump. It’s limited so we can find possible problems. It’s not even a macro technically; it’s implemented as a bunch of similar extensions to current productions. I’m not sure that’s better than something closer to Rust’s macros; that’s part of the reason I’m asking for comments.

And what for do I need generated lists?

And on a general point - We shouldn’t strive to become Rust or another “cool” language. Let Swift remain Swift. We don’t need another functional monster.

I don't know. For whatever you want.

I guess you can use (0..<MyCount).map { /*Whatever*/ }, but that only works for expressions. There are many comma-separated lists in Swift that are not expressions, like type lists. My main example was replacing:

(T, T, T, T, T, T)


( #dup(6; T) )

Even if you think six is too small for this, imagine having to do a list of 43 elements. Then you have to change it to 47 (or any other amount you'd dread having to count individually to confirm).

What do you mean by "functional" here?

The idea isn't to be "cool" like Rust. I just need to programmatically set the number of elements in a tuple by compile-time. Yes, it's not as useful without a constexpr story, but we have to start somewhere. And #dup works at the syntax-tree level, nothing past the SIL stage sees it. (Easier to implement than my strong type-alias and array ideas, which need ABI changes.) But I need it in the language proper, so in case the SIL stage finds a problem after a #dup expansion the compiler can return the term within the #dup and the iteration of the #dup.

My proposal mentioned Rust, but what about that other "cool" C-ish language, Go? I forgot why I didn't mention it the first time. I just did a quick web-search, and it seems that Go "doesn't have" macros, but added text replacement to secretly get some things done. The first major page I read ends with:

Meta programming has come to stay. If you have been conditioned to think macros are bad because you have been spoon fed plenty of C/C++ horror stories, you should think again. More and more languages implement macros. But do yourself a favour and use a language which provides the more saner syntactic macros. Unfortunately that means leaving Go, at least until they reach 2.0 (or later) and improve their meta programming capabilities.

It might be easier for people to understand if you use examples that aren’t tied to complex generics features that may never be implemented. Are there places in current Swift code where this would be useful? I guess this could be used to paper over some of the current issues with fixed-size C arrays being imported as e.g. 256 element tuples. Though a lot of issues would still remain in that exact case, including how to access elements, and it would probably be better addressed by an implementation of the oft-discussed “fixed-size arrays in Swift” feature.


I mean 2 thing with functional. Swift is drifting to much in the functional programming direction for me and I don’t want a all feature in language like c++. Both should be avoided imo.