I think it’s important to identify cases where you absolutely need to use compile-time macros, versus simply having the compiler precompute the results of regular Swift functions.
In the original post the linked article shows a macro calculating a factorial, but it’s a poor example IMO as it’s not something that definitely needs to be a macro, and indeed it’s something that would be more useful as a Swift function since you would also gain the ability to perform the same calculations dynamically at runtime. You get the same benefit to performance by having the compiler recognise which cases can be computed in advance and just let it do that. In fact in the fibonacci case it’s a clear one for the compiler to optimise away since storing the result as a constant should use less memory than storing the instructions required to trigger the function at run time, so it’s better for both performance and memory (there’s no downside to doing it).
The compiler probably already does this as part of its optimisations in cases where this can be done without any cost, so all that may be needed is a mechanism for forcing the compiler to do it in less obvious cases; e.g- where a function may generate a large set of results. Point being that in these cases it’s better to not use macros to do this, since you end up with two languages to maintain instead of just one, rather than just using a general purpose optimisation that works automatically across the whole, single, language.
I think a more clear benefit would be cases that could for example replace the .gyb files that are currently in the Swift stdlib code-base; I’m not 100% sure on what these actually do (besides make it harder for me to look up the implementation details of things ;), but if they could be replaced with some kind of macro constructs within a regular Swift file it may make them easier to work with, though you’re still talking about something that’s essentially a language within a language.
The other kinds of cases are things like platform-specific optimisations, but that’s something you should only ever do if you have to do it, and we already have conditionals that should support this I think.
Unless I’ve totally misunderstood the problem, but my experience with other languages has usually been that compile-time macros are most often used in place of good support for generics, which isn’t obviously a problem for Swift, either that or they’re used in cases that are actually redundant cases that a good compiler can optimise away for you (i.e- preemptive optimisation, which isn’t always a good thing). I can’t think of many good cases where I’ve thought “oh yeah that makes sense”, doesn’t mean there aren’t any of course, it might be helpful to have some good examples of where this kind of feature is necessary in Swift, versus some alternative feature in the language itself.
On 12 Jun 2016, at 09:47, L Mihalkovic via swift-evolution <email@example.com> wrote:
On Jun 12, 2016, at 6:05 AM, Alexander Momchilov <firstname.lastname@example.org <mailto:email@example.com>> wrote:
Aren't macros totally different?
Anyways, weren't macros rejected? I thought Swift was trying to avoid having the hefty reliance of preprocessor macros that C did.
Sorry I was not referring to C-style macros (i.e. preproc). I was referring to a macro language in the sense of the scala compiler macros or other languages that let you insert compile time code inside your source (like D). I was of the opinion that it would be a short step to support something like embedded SIL inside string literals. But Chirs ruled out compile time code execution stressing that it should not be a replacement for designing a great language. Maybe around 4 or 5, when the language is mature, then compile time code execution (macros) can be added