Skip to content

extend PR #11846 to add symbol support for AliasAssign#12029

Merged
dlang-bot merged 1 commit intodlang:masterfrom
WalterBright:AliasAssign2
Jan 15, 2021
Merged

extend PR #11846 to add symbol support for AliasAssign#12029
dlang-bot merged 1 commit intodlang:masterfrom
WalterBright:AliasAssign2

Conversation

@WalterBright
Copy link
Member

#11846 only does alias assigns for types. As promised, this extends it for symbols, too, just like AliasDeclaration.

@WalterBright WalterBright added the Review:WIP Work In Progress - not ready for review or pulling label Dec 16, 2020
@dlang-bot
Copy link
Contributor

Thanks for your pull request, @WalterBright!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#12029"

@WalterBright
Copy link
Member Author

@atilaneves this now passes the std.meta unittests

@WalterBright
Copy link
Member Author

Spec pull: dlang/dlang.org#2919

@WalterBright
Copy link
Member Author

Still missing: a RHS that consists of a function literal. Will add that in next PR.

@WalterBright
Copy link
Member Author

I also discovered there's already an AliasAssign in the grammar. I'll be doing a refactor at some point to change this to AliasReassign, which makes more sense anyway.

@Geod24
Copy link
Member

Geod24 commented Dec 17, 2020

Can we put this feature behind a -preview switch ?

@WalterBright WalterBright removed the Review:WIP Work In Progress - not ready for review or pulling label Dec 17, 2020
@WalterBright
Copy link
Member Author

Can we put this feature behind a -preview switch ?

This feature is purely additive. It does not remove or modify any existing behavior. There's no purpose to putting it behind a switch.

Besides, I want to get it used in std.meta fairly soon, as the performance boost should be substantial.

@Geod24
Copy link
Member

Geod24 commented Dec 18, 2020

As mentioned in the previous PR:

Having it straight into the language means that code might not break when the feature is first added, but will break when the design evolves to incorporate feedback.

If you're experimenting with the language, fine, but signal it properly. I found a SEGV with this feature within 5 minutes.

@WalterBright
Copy link
Member Author

If you're experimenting with the language, fine, but signal it properly.

No more than other PRs. Still no need to hide it behind a switch.

I found a SEGV with this feature within 5 minutes.

Test case, please.

@12345swordy
Copy link
Contributor

This is what @Geod24 is referring to.

import std.meta;

template Swap (alias A, alias B)
{
    alias C = A;
    B = A;
    A = B;
    enum Swap = true;
}

alias A = int;
alias B = string;

static assert(Swap!(A, B));

pragma(msg, A);

@WalterBright WalterBright force-pushed the AliasAssign2 branch 4 times, most recently from 09eafc3 to f37f028 Compare January 3, 2021 07:41
@WalterBright
Copy link
Member Author

ping @Geod24

@atilaneves
Copy link
Contributor

While it's additive, I'd hate for someone to go and write code that depends on this behaviour in case we have to revert these changes. I think a preview switch is a better way forward. Well, something that prevents what I just described, anyway.

@WalterBright
Copy link
Member Author

We put in other additive enhancements all the time without -preview. I do not understand the trepidation about this feature - it's what people have been asking for for several years. There's no posted rationale against it. It's small and simple. If it fails, it just gets put in the deprecation cycle.

The problem with -preview is we cannot then use it to speed up Phobos, which is its primary purpose.

@WalterBright
Copy link
Member Author

I suppose "cannot" is a bit strong. It would be just ugly.

@Geod24
Copy link
Member

Geod24 commented Jan 5, 2021

We put in other additive enhancements all the time without -preview. I do not understand the trepidation about this feature - it's what people have been asking for for several years.

When is the last time we put in such a language change without -preview ?

There's no posted rationale against it.

The burden of proof should be on the proposer, not the reviewer.
Also the premise here is "let's put it in and see what happens" (which, as mentioned, is common - with -preview).

It's small and simple. If it fails, it just gets put in the deprecation cycle.

Except that it will "almost work" and there will be "just a few fixes needed" that will break code. The idea behind -preview is exactly to avoid this.

template staticMap(alias F, T...)
{
alias A = AliasSeq!();
static foreach (t; T)
Copy link
Contributor

@nordlow nordlow Jan 5, 2021

Choose a reason for hiding this comment

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

This is still gonna create T.length - 1 number of intermediate instances of AliasSeq. Despite AliasSeq being special cased in the compiler, it would be interesting to see how the compilation performance of this compares to an implementation using alias functions, @UplinkCoder.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is still gonna create T.length - 1 number of intermediate instances of AliasSeq.

Yup. A lot less than T.length-1 number of template instantiations of staticMap, which are far more expensive.

@WalterBright
Copy link
Member Author

WalterBright commented Jan 5, 2021

Except that it will "almost work" and there will be "just a few fixes needed" that will break code.

There's no evidence that it will break code. It's additive. It's no more risk than any of many other PRs sailing through. Sticking it behind -preview means it will be years before the performance improvements to things like staticMap will be available.

When is the last time we put in such a language change without -preview ?

Last week? Heck, one went through in less than ONE DAY with no Spec pull, no Bugzilla issue, and no changelog. #11833

The burden of proof should be on the proposer, not the reviewer.

I can't prove a negative. We do know that nothing broke in the test suite, druntime, phobos, buildkite, etc.

The idea behind -preview is exactly to avoid this.

The idea is we use it for features we know will break code. Otherwise, every single PR would have to be behind -preview.

@ibuclaw
Copy link
Member

ibuclaw commented Jan 5, 2021

Except that it will "almost work" and there will be "just a few fixes needed" that will break code.

There's no evidence that it will break code. It's additive. It's no more risk than any of many other PRs sailing through. Sticking it behind -preview means it will be years before the performance improvements to things like staticMap will be available.

Consider it an incubator for new features. As this feature is clearly still incomplete, it shouldn't be on by default until it's ready to be presented to the world.

When is the last time we put in such a language change without -preview ?

Last week? Heck, one went through in less than ONE DAY with no Spec pull, no Bugzilla issue, and no changelog. #11833

There is a bugzilla issue, it's referenced in the PR - and the language change is hidden behind a -preview, so that isn't answering the question at all.

The idea behind -preview is exactly to avoid this.

The idea is we use it for features we know will break code. Otherwise, every single PR would have to be behind -preview.

It's also there for experiments that may prove volatile and allows removal without ever bothering with any deprecation cycle (though apparently some things like -preview=rvaluerefparam appear to be more tricky than initially thought).

Having a -preview= would have prevented @[UDA] being introduced as both a new feature and deprecated syntax in the same release.

@WalterBright
Copy link
Member Author

As this feature is clearly still incomplete

How so?

Having a -preview= would have prevented @[UDA] being introduced as both a new feature and deprecated syntax in the same release.

On the other hand, hiding it behind a switch would have meant it would have taken several years to adopt it, whereas it was immediately successful. The immediacy and eagerness of its adoption justified it.

The point of this PR is to speed up staticMap and some other Phobos templates, where people have been begging for solutions for years. It's a topic of every DConf and every quarterly meeting. This is not going to happen for staticMap for years more if it is behind a preview switch. Nobody has identified any problems with this addition. It passes all the tests.

This feature gives D a significant competitive advantage. It's immediately useful to anyone who uses std.meta.

Copy link
Member

@Geod24 Geod24 left a comment

Choose a reason for hiding this comment

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

So identity assignment doesn't work anymore ?

template Identity (alias T)
{
    T = T;
    alias Identity = T;
}
pragma(msg, Identity!int);

Results in:

aliasassign.d(5): Error: `T` must have same parent `Identity!int` as alias `T`

Comment on lines +3 to +4
fail_compilation/aliasassign.d(13): Error: `B` must have same parent `Swap!(int, string)` as alias `B`
fail_compilation/aliasassign.d(14): Error: `A` must have same parent `Swap!(int, string)` as alias `A`
Copy link
Member

Choose a reason for hiding this comment

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

This error message doesn't make much sense. "B must have same parent as B"... Well it does, doesn't it ?
And changing the outter B (L19) doesn't help.

Copy link
Member Author

Choose a reason for hiding this comment

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

If you name all your symbols the same, no, it isn't going to make that much sense. If you have a better idea, let me know.

Copy link
Member Author

Choose a reason for hiding this comment

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

Note that in your example the parameter T is a different declaration than the target T of the aliasassign, and they have different parents. They have to have the same parent to be accepted.

Copy link
Member

Choose a reason for hiding this comment

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

If you name all your symbols the same, no, it isn't going to make that much sense. If you have a better idea, let me know.

That's why I mentioned changing the outer B:

template Swap (alias A, alias B)
{
    alias C = A;
    B = A;
    A = B;
    enum Swap = true;
}

alias OuterA = int;
alias OuterB = string;

static assert(Swap!(OuterA, OuterB));

This produces the same error message.

Note that in your example the parameter T is a different declaration than the target T of the aliasassign, and they have different parents. They have to have the same parent to be accepted.

How can they be different, there is no other alias declaration with the same name ?
Looking at the code again, did you mean something like:

fail_compilation/aliasassign.d(14): Error: alias `A` must be declared inside `Swap!(int, string)`

Likewise, the following would be more user-friendly:

fail_compilation/aliasassign.d(14): Error: alias parameter `A` cannot be re-assigned
(errorSupplemental) Only aliases declared inside a template can be re-assigned

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@RazvanN7
Copy link
Contributor

RazvanN7 commented Jan 8, 2021

We put in other additive enhancements all the time without -preview. I do not understand the trepidation about this feature

The fact that this happens is not a reason to continue to do so. Besides the technical shortcomings that have been pointed out by other reviewers, one fundamental issue with this approach is that it is unfair to other contributors. We have rules that are clearly stated and the fact that those rules were not respected in this case brings a lot of damage to the community.

For example, @UplinkCoder 's type functions: while I do agree that a DIP is necessary in that situation, it is hard to impose that rule when we get examples such as this PR.

From my perspective, both AliasAssign and type functions should be behind a preview switch and both should be presenting a DIP so that everyone gets to analyze them.

@atilaneves
Copy link
Contributor

I talked to @WalterBright about this today.

The idea is to not put it behind -preview but instead:

  1. Move forward with enough changes in the compiler to enable us to write a different version of staticMap that we can then use to benchmark compile time for large codebases that use it.
  2. Iff we see compile-time improvements we keep it. Otherwise we revert the changes.

The idea is to use the beta period for this and if necessary revert before the release. In any case we wouldn't update the changelog until we're sure this is the direction we're going in. How does that sound?

@UplinkCoder
Copy link
Member

@atilaneves in that case we would do the same with typefunctions?

@atilaneves
Copy link
Contributor

@atilaneves in that case we would do the same with typefunctions?

This is a false equivalency.

@RazvanN7
Copy link
Contributor

@atilaneves I still don't understand what is wrong with putting it behind a preview switch. If we decide to go on with this we can just eliminate the preview, if not then we can revert it in a clean way. It is not clear why we should flout the rules in this case and implement the feature directly in the language without a DIP.

@Geod24
Copy link
Member

Geod24 commented Jan 12, 2021

The idea is to use the beta period for this and if necessary revert before the release. In any case we wouldn't update the changelog until we're sure this is the direction we're going in. How does that sound?

Well the previous PR already made it into a release. And as @RazvanN7 noted, if the idea is to test between releases, a -preview switch is not a problem.

@atilaneves
Copy link
Contributor

Because the whole point of this is to test changing the implementation of staticMap and we'd have to use the preview flag when building Phobos itself.

Either way, I don't think it's a big deal. Reasonable people may of course disagree.

@12345swordy
Copy link
Contributor

@WalterBright is using a preview switch a huge deal breaker here?

@WalterBright
Copy link
Member Author

@12345swordy yes. Atila explained it, so have I.

@Geod24
Copy link
Member

Geod24 commented Jan 15, 2021

Either way, I don't think it's a big deal. Reasonable people may of course disagree.

Seems like everyone but the two of you not only disagree, but agree on an alternate course.

@dlang-bot dlang-bot merged commit a85d0d6 into dlang:master Jan 15, 2021
@nordlow
Copy link
Contributor

nordlow commented Jan 15, 2021

What's the plan on updating druntime and phobos, such as staticMap to make use of this?

@atilaneves
Copy link
Contributor

What's the plan on updating druntime and phobos, such as staticMap to make use of this?

The plan is to try it out, benchmark it, and revert it if it's not faster to compile. If it is, we make a PR for Phobos.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

Comments