Discussion:
generalized 'using' statement
(too old to reply)
Viacheslav Usov
2015-12-17 12:52:09 UTC
Permalink
Consider the following:

namespace foo
{
struct bar {};
void baz() {}
int qux;
}

namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;

The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?

Is there any fundamental reason why using X = Y cannot (or should not) be
valid for all kinds of names?

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-17 14:17:42 UTC
Permalink
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Because they're not the same thing. However much you may want to think of
`C` and `D` as "aliases", they are not. They are *references to objects*.

Doing `B b{};` is legal. Doing `C c{};` is not. It makes perfect sense that
creating a typename alias and creating an object reference would require
different syntax. Just as creating a namespace alias uses different syntax
from a typename alias.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-17 15:06:37 UTC
Permalink
Post by Nicol Bolas
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Because they're not the same thing. However much you may want to think of
`C` and `D` as "aliases", they are not. They are *references to objects*.
I did not mean to ask why different syntaxes had to be used per the current
standard. My question was a proposal, which I thought would be self-evident
in this forum; let me re-formulate it more explicitly.

Proposal: make syntax using X = Y a valid alternative to namespace X = Y
(when Y is a namespace name); or auto &X = Y (when Y is a function or an
object); this is similar to how using X = Y is a valid alternative to
typedef Y X (when Y is a type).

Motivation: the current means of creating alternative names for language
entities create leaky abstractions and have corresponding maintenance
costs. Consider this:

// unit 1
struct A {};

// unit 2
using X = A;
auto a = X();

At some later time, the code in unit 1 changes to:

B A();

The code in unit 2 is no longer valid.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-17 17:48:52 UTC
Permalink
Post by Viacheslav Usov
Post by Nicol Bolas
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Because they're not the same thing. However much you may want to think of
`C` and `D` as "aliases", they are not. They are *references to objects*.
I did not mean to ask why different syntaxes had to be used per the
current standard. My question was a proposal, which I thought would be
self-evident in this forum; let me re-formulate it more explicitly.
Proposal: make syntax using X = Y a valid alternative to namespace X = Y
(when Y is a namespace name); or auto &X = Y (when Y is a function or an
object); this is similar to how using X = Y is a valid alternative to
typedef Y X (when Y is a type).
And the reason not to allow such a proposal is exactly what I said: it
confuses the language. These three circumstances are *not the same thing*,
so the syntax should *not* make them look like they are.
Post by Viacheslav Usov
Motivation: the current means of creating alternative names for language
entities create leaky abstractions and have corresponding maintenance
// unit 1
struct A {};
// unit 2
using X = A;
auto a = X();
B A();
The code in unit 2 is no longer valid.
You have proven my point. With that change, your code *should be invalid*.

You cannot exchange a struct for a *function*. That is not a valid thing
you can do and expect to get sane code. After all, `unit 2` could easily
have been written as:

using X = A;
auto a = X{};

Now it doesn't work, even if the using declaration works as you wanted. Nor
do any of the following *perfectly valid uses*:

sizeof(X); //Cannot take the size of a reference.
vector<X>; //Can't pass a reference as a typename template parameter.

Indeed, the specific case you described is probably the *only* case where
you could use a reference and a type in the same way. In every other way,
it would not work.

So I find your motivation to be exceedingly weak.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 11:52:53 UTC
Permalink
Post by Nicol Bolas
And the reason not to allow such a proposal is exactly what I said: it
confuses the language. These three circumstances are *not the same thing*,
so the syntax should *not* make them look like they are.

Oh yes. And we should never have allowed the use of 'auto' for type
deduction, because different types are never the same thing, so the syntax
should *not* make them look like they are.
Post by Nicol Bolas
You cannot exchange a struct for a *function*.
Except when we can. And we can do so very often.

The premises of your argument are invalid.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-18 14:16:30 UTC
Permalink
Post by Nicol Bolas
Post by Nicol Bolas
And the reason not to allow such a proposal is exactly what I said: it
confuses the language. These three circumstances are *not the same thing*,
so the syntax should *not* make them look like they are.
Oh yes. And we should never have allowed the use of 'auto' for type
deduction, because different types are never the same thing, so the syntax
should *not* make them look like they are.
... what are you even talking about?

There's a huge difference between "deduce a different type" and "turn a
typename into a function."
Post by Nicol Bolas
Post by Nicol Bolas
You cannot exchange a struct for a *function*.
Except when we can. And we can do so very often.
The premises of your argument are invalid.
Declaring something to be invalid does not make it invalid.

If you want to argue that *transparently* exchanging a struct for a
function is something you can do, prove it. Show me under what
circumstances this is acceptable. And then show that the other
circumstances which would prevent it are not usable.

Because right now, the only way you can transparently exchange a struct for
a function is if the *only uses* of that struct's typename were of the
exact form:

auto x = Struct(...);

If you did any of these other *perfectly valid* and very common forms of
initialization, your idea doesn't work:

auto x = Struct{...};
Struct x(...);
Struct x{...};
Struct x = Struct(...); //Not everyone uses auto everywhere
auto x = make_unique<Struct>(...); //Oh right, heap allocation
auto x = new Struct(...); //Even old-school heap allocation fails

Plus, if you used that typename in any other way, your code is broken. In
particular, you cannot:

- Use it as a template argument.
- Get a member pointer to one of the members of the struct, perhaps for
a callback.
- Make a non-static data member of that class type.
- Call the destructor directly.
- Use it as a (non-deduced) return type of a function.

So I'm not buying that this is a particularly useful case.

If you want to argue that transparently exchanging a struct for a function
happens "very often", again prove it. Show me a codebase where this has
happened a lot. Show me libraries that has gone though API revisions that
transparently turn a struct into a function. And show me that users have
not been broken by these changes.

You're the one making the argument for this idea, so the burden of proof is
on you. You claim that this is a common thing, so prove it.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 14:43:55 UTC
Permalink
Post by Nicol Bolas
There's a huge difference between "deduce a different type" and "turn a
typename into a function."

This is a straw man; nothing in my proposal suggests the latter.
Post by Nicol Bolas
If you want to argue that *transparently* exchanging a struct for a
function is something you can do, prove it

You want to argue about that. I have no interest in that.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-18 14:48:26 UTC
Permalink
Post by Nicol Bolas
Post by Nicol Bolas
There's a huge difference between "deduce a different type" and "turn a
typename into a function."
This is a straw man; nothing in my proposal suggests the latter.
Post by Nicol Bolas
If you want to argue that *transparently* exchanging a struct for a
function is something you can do, prove it
You want to argue about that. I have no interest in that.
Then *why did you bring it up?* Here is your post that started this path of
discussion:

Motivation: the current means of creating alternative names for language
Post by Nicol Bolas
entities create leaky abstractions and have corresponding maintenance
// unit 1
struct A {};
// unit 2
using X = A;
auto a = X();
B A();
The code in unit 2 is no longer valid.
You claimed that this, the ability to transform a typename into a function,
was a motivating example for your proposal.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 15:42:59 UTC
Permalink
Post by Nicol Bolas
Then *why did you bring it up?*
Motivation: the current means of creating alternative names for language
entities create leaky abstractions and have corresponding maintenance costs.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2015-12-18 18:23:37 UTC
Permalink
Post by Viacheslav Usov
Post by Nicol Bolas
Then *why did you bring it up?*
Motivation: the current means of creating alternative names for language
entities create leaky abstractions and have corresponding maintenance costs.
That's because it was never intended to be an abstraction in the first place.

You're the one proposing creating an abstraction layer.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Woehlke
2015-12-18 15:54:05 UTC
Permalink
Post by Viacheslav Usov
Post by Nicol Bolas
If you want to argue that *transparently* exchanging a struct for a
function is something you can do, prove it
You want to argue about that. I have no interest in that.
Post by Nicol Bolas
You cannot exchange a struct for a *function*.
Except when we can. And we can do so very often.
If that's not "interest", then I have no idea what you are trying to say.

Also, the basis of your proposal is to blur the line between types,
functions, and variables. Which has been pointed out repeatedly seems
like a bad idea.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 16:14:38 UTC
Permalink
Post by Matthew Woehlke
If that's not "interest", then I have no idea what you are trying to say.
I said that "You cannot exchange a struct for a *function*" was invalid.
But that is not something that I really want to talk about; my proposal is
orthogonal to that.
Post by Matthew Woehlke
Also, the basis of your proposal is to blur the line between types,
functions, and variables.

Then explain why the use of auto is not to blur the line between different
types; or why that is not a bad idea.

Before we had the revamped auto, one would have to say to the compiler:
"create a variable of type X and initialize it from the expression" (whose
type must be convertible to Y; this and further parenthetical remarks are
not to be spelled out). Now we just say "please create and initialize a
variable from the expression" (choosing an appropriate type).

With the current means of aliasing, we have to say: "we both know that Y is
a namespace (or a type; or a var). Let X be another name for that." What I
am proposing is a way of saying "Let X be another name for Y" (whatever Y
is, provided it can be validly aliased).

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2015-12-18 16:18:28 UTC
Permalink
Post by Viacheslav Usov
With the current means of aliasing, we have to say: "we both know that Y is
a namespace (or a type; or a var). Let X be another name for that." What I
am proposing is a way of saying "Let X be another name for Y" (whatever Y
is, provided it can be validly aliased).
While that may be reasonable, it shouldn't be done so that people who use
the current way of saying "let X be another name for type Y, and if Y
isn't a type,
the code must be ill-formed" have their code broken. In other words, you should
strive for a different syntax for such "universal aliases", whatever
that syntax might be.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 16:31:09 UTC
Permalink
On Fri, Dec 18, 2015 at 5:18 PM, Ville Voutilainen <
Post by Ville Voutilainen
While that may be reasonable, it shouldn't be done so that people who use
the current way of saying "let X be another name for type Y, and if Y isn't
a type, the code must be ill-formed" have their code broken.

That is a good point. However, as far as I can tell, and I can easily be
mistaken here, using X = Y when Y is not a type is undefined behaviour
currently.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2015-12-18 16:33:37 UTC
Permalink
Post by Viacheslav Usov
That is a good point. However, as far as I can tell, and I can easily be
mistaken here, using X = Y when Y is not a type is undefined behaviour
currently.
I don't know how you come to such a conclusion; it's not undefined behaviour,
it's ill-formed.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 16:54:48 UTC
Permalink
On Fri, Dec 18, 2015 at 5:33 PM, Ville Voutilainen <
Post by Ville Voutilainen
I don't know how you come to such a conclusion; it's not undefined
behaviour, it's ill-formed.

As I said, I could easily have been mistaken :)

I accept your point as a valid consideration against the proposed syntax.
Yet, as far as I can tell, making ill-formed code well-formed has not
always been enough to dismiss a proposal.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2015-12-18 17:01:42 UTC
Permalink
Post by Viacheslav Usov
Post by Ville Voutilainen
I don't know how you come to such a conclusion; it's not undefined
behaviour, it's ill-formed.
As I said, I could easily have been mistaken :)
I accept your point as a valid consideration against the proposed syntax.
Yet, as far as I can tell, making ill-formed code well-formed has not always
been enough to dismiss a proposal.
In this case I daresay it would be.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Richard Smith
2015-12-18 19:07:53 UTC
Permalink
On Fri, Dec 18, 2015 at 8:18 AM, Ville Voutilainen <
Post by Ville Voutilainen
Post by Viacheslav Usov
With the current means of aliasing, we have to say: "we both know that Y
is
Post by Viacheslav Usov
a namespace (or a type; or a var). Let X be another name for that." What
I
Post by Viacheslav Usov
am proposing is a way of saying "Let X be another name for Y" (whatever Y
is, provided it can be validly aliased).
While that may be reasonable, it shouldn't be done so that people who use
the current way of saying "let X be another name for type Y, and if Y
isn't a type,
the code must be ill-formed" have their code broken. In other words, you should
strive for a different syntax for such "universal aliases", whatever
that syntax might be.
If you're saying that we can't use "using X = Y;" for anything other than
types because we already use it for types, then I think we made a major
mistake using such a general syntax for such a specific thing.

I think the feature being proposed is useful, but I don't think the
discussion thus far has really captured a good motivation for it. So here's
why I want it:

Refactoring.

This feature allows an entity to be incrementally renamed, in a uniform way
that does not depend on what kind of entity you started with. (You first
add "using NewName = OldName;", then update all the users, then remove the
alias declaration.) To do this today involves using a different syntax,
possibly with subtly-different semantics, for each different kind of entity
(for examples where this is hard today, try renaming a template or an
overload set of functions).

This is exactly analogous to using-declarations, which allow an entity to
be incrementally moved from one namespace to another, independent of the
kind of entity.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2015-12-18 19:40:43 UTC
Permalink
Post by Richard Smith
Post by Ville Voutilainen
While that may be reasonable, it shouldn't be done so that people who use
the current way of saying "let X be another name for type Y, and if Y
isn't a type,
the code must be ill-formed" have their code broken. In other words, you should
strive for a different syntax for such "universal aliases", whatever
that syntax might be.
If you're saying that we can't use "using X = Y;" for anything other than
types because we already use it for types, then I think we made a major
mistake using such a general syntax for such a specific thing.
Perhaps so, but that mistake was made before C++11 was published, and
changing it is a silent breaking change that potentially turns
compile-time errors
into run-time errors.
Post by Richard Smith
I think the feature being proposed is useful, but I don't think the
discussion thus far has really captured a good motivation for it. So here's
Refactoring.
This feature allows an entity to be incrementally renamed, in a uniform way
that does not depend on what kind of entity you started with. (You first add
"using NewName = OldName;", then update all the users, then remove the alias
declaration.) To do this today involves using a different syntax, possibly
with subtly-different semantics, for each different kind of entity (for
examples where this is hard today, try renaming a template or an overload
set of functions).
N.B. I have no doubt a facility like this would be useful, nor do I have trouble
imagining practical uses for it.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Richard Smith
2015-12-19 03:00:07 UTC
Permalink
On Fri, Dec 18, 2015 at 11:40 AM, Ville Voutilainen <
Post by Ville Voutilainen
Post by Richard Smith
Post by Ville Voutilainen
While that may be reasonable, it shouldn't be done so that people who
use
Post by Richard Smith
Post by Ville Voutilainen
the current way of saying "let X be another name for type Y, and if Y
isn't a type,
the code must be ill-formed" have their code broken. In other words, you should
strive for a different syntax for such "universal aliases", whatever
that syntax might be.
If you're saying that we can't use "using X = Y;" for anything other than
types because we already use it for types, then I think we made a major
mistake using such a general syntax for such a specific thing.
Perhaps so, but that mistake was made before C++11 was published, and
changing it is a silent breaking change that potentially turns
compile-time errors
into run-time errors.
Do you have a specific example in mind? I can imagine contrived cases, but
so far I've failed at inventing one that is plausible.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2015-12-19 12:15:36 UTC
Permalink
Post by Richard Smith
Post by Ville Voutilainen
Perhaps so, but that mistake was made before C++11 was published, and
changing it is a silent breaking change that potentially turns
compile-time errors
into run-time errors.
Do you have a specific example in mind? I can imagine contrived cases, but
so far I've failed at inventing one that is plausible.
I have nothing too specific, no. I suppose such breakage would need changing
an object to a type so that parentheses-initialization of an object of
said type would have
compatible syntax to invoking a function call on the object. Or vice
versa. Any examples
I can come up with are indeed also somewhat contrived, but I tend to
become categorically
cautious when compile-time errors turn into run-time behavior change,
if not outright
breakage. And again, sometimes that's very useful and exactly what's
intended; my concern
is for cases where it might not be. :)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-29 15:20:40 UTC
Permalink
Post by Richard Smith
Post by Viacheslav Usov
Post by Viacheslav Usov
With the current means of aliasing, we have to say: "we both know that
Y is
Post by Viacheslav Usov
a namespace (or a type; or a var). Let X be another name for that."
What I
Post by Viacheslav Usov
am proposing is a way of saying "Let X be another name for Y" (whatever
Y
Post by Viacheslav Usov
is, provided it can be validly aliased).
While that may be reasonable, it shouldn't be done so that people who use
the current way of saying "let X be another name for type Y, and if Y
isn't a type,
the code must be ill-formed" have their code broken. In other words, you should
strive for a different syntax for such "universal aliases", whatever
that syntax might be.
If you're saying that we can't use "using X = Y;" for anything other than
types because we already use it for types, then I think we made a major
mistake using such a general syntax for such a specific thing.
I think the feature being proposed is useful, but I don't think the
discussion thus far has really captured a good motivation for it. So here's
Refactoring.
This feature allows an entity to be incrementally renamed, in a uniform
way that does not depend on what kind of entity you started with. (You
first add "using NewName = OldName;", then update all the users, then
remove the alias declaration.) To do this today involves using a different
syntax, possibly with subtly-different semantics, for each different kind
of entity (for examples where this is hard today, try renaming a template
or an overload set of functions).
OK, there are two issues here:

1) Cases that other alias methods already cover.

2) Cases that other alias methods don't cover.

There's an argument for having coverage for #2. Indeed, part of P0109
(strong type aliases) includes a section specifically about adding function
aliases, as a means of specifying "trampolines", but also as a generalized
mechanism. It can even alias a function with an object, which is rather...
odd, and it's not really clear what that means for doing things like
getting function pointers and the like.

My issue is primarily with #1: cases which we have perfectly valid
mechanisms for. Unless you are explicitly trying to change the *meaning* of
such aliases, then I don't see the point. So long as these two declarations
would do the same thing:

namespace alias = original;
using alias = original;

I don't know why we should blur the line between a namespace alias
declaration and a using declaration.

That brings up another point you raised: "possibly with subtly-different
semantics". Well, possibly different semantics with what, exactly?

Variable aliases are a big issue here. That's because the language doesn't
define "variable aliases"; it defines *references*. The OP wanted `using`
to declare a *reference*, not an alias. And as much as the OP would like to
believe it, they aren't the same thing.

So if `using` were to be able to create "variable aliases", would you want
them to behave like aliases (different name, same object) or references
(different *variable*, same object)?
Post by Richard Smith
This is exactly analogous to using-declarations, which allow an entity to
be incrementally moved from one namespace to another, independent of the
kind of entity.
Except that it doesn't. Not really. It simply makes the name visible in
that new namespace. It doesn't change, for example, ADL lookup rules
<http://ideone.com/W75Hhm>. The "moved" entity is not really in that
namespace.

That's why we invented inline namespaces <http://ideone.com/7MemB6>.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-29 15:32:22 UTC
Permalink
The OP wanted `using` to declare a *reference*, not an alias. And as much
as the OP would like to believe it, they aren't the same thing.
And by the way, in my proposal I identified using X = Y with auto &X = Y
when Y is a variable or a function; this is, however, not essential for the
proposal. The desired semantics is "X is another name for Y", not really "X
is a reference to Y" even though the latter means very nearly the former.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-29 15:52:04 UTC
Permalink
The OP wanted `using` to declare a *reference*, not an alias. And as
much as the OP would like to believe it, they aren't the same thing.
And by the way, in my proposal I identified using X = Y with auto &X =
Y when Y is a variable or a function; this is, however, not essential for
the proposal. The desired semantics is "X is another name for Y", not
really "X is a reference to Y" even though the latter means very nearly the
former.
Maybe you need to re-read your own posts:

Proposal: make syntax using X = Y a valid alternative to namespace X = Y
(when Y is a namespace name); or auto &X = Y (when Y is a function or an
object); this is similar to how using X = Y is a valid alternative to
typedef Y X (when Y is a type).
That was what you said.
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/4PR7LUngZFw/NmEiDCGNDQAJ>
I cannot read your mind; if you ask for `using X = Y` to become `auto &X =
Y`, then I must assume that's what you want.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-29 16:01:10 UTC
Permalink
Post by Nicol Bolas
That was what you said.
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/4PR7LUngZFw/NmEiDCGNDQAJ>


And, of course, subsequent clarifications are to be ignored.
Post by Nicol Bolas
I cannot read your mind
You do not have to. You just need to learn to read your email.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-29 16:32:42 UTC
Permalink
Post by Nicol Bolas
Post by Nicol Bolas
That was what you said.
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/4PR7LUngZFw/NmEiDCGNDQAJ>
And, of course, subsequent clarifications are to be ignored.
OK, I admit that I missed that line. That doesn't change one important fact:

That wasn't a "clarification". That was a *change to your idea*.

That's not something that should be buried in the middle of a random post.
It should be something that you should make abundantly clear to everyone
that a change has occurred. Not everyone is going to remember every minor
detail of every sentence from a post you wrote weeks ago.

If you're going to add new aspects to a proposal (and this is new), that
needs to be made clear. You should have created a new post that said,
"Earlier, I said that I wanted `using X = Y` to be `auto &X = Y` for
objects. I realize now that I want it to mean something new instead."
Followed of course by an explanation of how this "something new" should
behave (C++ doesn't have "variable aliases", so you have to explain what
the rules for them are).

That's something that people would notice and be aware of (and comment on.
Note that nobody actually responded to the post including your change).
Changes to your proposal due to issues brought up in debate are good. But
you need to make it more visible when such changes happen.

Now that we have that out of the way, you still need to explain what a
"variable alias" does.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-29 16:59:24 UTC
Permalink
Post by Nicol Bolas
That wasn't a "clarification". That was a *change to your idea*.
I never said I wanted to introduce a new concept such as a "variable
alias". I am not entirely sure whether there *is* or *should be *a true
difference between a reference and variable alias. I *think* a reference
could be sufficient, but if there are valid arguments against that or a
better way to define a variable alias, let's see them, but let's not
dismiss the proposal just because of that. That was the whole point of my
clarification.
Post by Nicol Bolas
That's not something that should be buried in the middle of a random post.
A clarification is made when it becomes clear that something is unclear. It
is made when it is felt it needs to be made. Labelling the message with the
clarification as a "random post" is baseless.
Post by Nicol Bolas
It should be something that you should make abundantly clear to everyone
that a change has occurred. Not everyone is going to remember every minor
detail of every sentence from a post you wrote weeks ago.

Everyone? The clarification was made in response to your message. And it
was you who missed it. If you cannot be bothered to read responses to your
own messages, then I am not even sure why you post here.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Richard Smith
2015-12-29 20:06:30 UTC
Permalink
Post by Nicol Bolas
Post by Nicol Bolas
Post by Nicol Bolas
That was what you said.
<https://groups.google.com/a/isocpp.org/d/msg/std-proposals/4PR7LUngZFw/NmEiDCGNDQAJ>
And, of course, subsequent clarifications are to be ignored.
That wasn't a "clarification". That was a *change to your idea*.
That's not something that should be buried in the middle of a random post.
It should be something that you should make abundantly clear to everyone
that a change has occurred. Not everyone is going to remember every minor
detail of every sentence from a post you wrote weeks ago.
If you're going to add new aspects to a proposal (and this is new), that
needs to be made clear. You should have created a new post that said,
"Earlier, I said that I wanted `using X = Y` to be `auto &X = Y` for
objects. I realize now that I want it to mean something new instead."
Forking the discussion thread every time the idea is slightly adjusted will
make it near-impossible to follow the discussion as a whole, people will
inevitably respond to the wrong thread, and so on.

I think the best thing to do would be to write a short paper, update it
based on feedback, and post new versions to the discussion thread whenever
the paper is materially updated, with a brief description of the changes
made. Writing a paper is also a good way to ensure that your thoughts on
the subject are organized, coherent, consistent, and well-motivated.

Followed of course by an explanation of how this "something new" should
Post by Nicol Bolas
behave (C++ doesn't have "variable aliases", so you have to explain what
the rules for them are).
That's something that people would notice and be aware of (and comment on.
Note that nobody actually responded to the post including your change).
Changes to your proposal due to issues brought up in debate are good. But
you need to make it more visible when such changes happen.
To my reading, mapping "using X = Y" to a reference declaration was not
proposed by Viacheslav (the reference declaration was part of the
description of the problem, not part of the proposed solution). What was
proposed was to make "using X = Y be valid for all kinds of names", without
a precise specification for what that means. But I can see how you'd read
the introductory email in a different way.

Now that we have that out of the way, you still need to explain what a
Post by Nicol Bolas
"variable alias" does.
(This is what I'd like to see, not necessarily what Viacheslav was
proposing.) Consider this in today's C++:

namespace X {
int n;
}
using X::n; // creates an alias ::n

There's no fundamental reason that the alias must have the same
unqualified-id as the original, and being able to rename the declaration is
every bit as useful as being able to make it appear within a different
namespace. So, suppose we allow:

using m = X::n;

as an exact analogue of the existing using-declaration, but one that gives
the alias a different name.

When an alias-declaration is viewed as a renaming analogue of a
using-declaration, it's really odd that an alias-declaration can be used
only for types, whereas a using-declaration can be used for any kind of
entity (except namespaces and scoped enumerators -- more warts!).
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-30 16:13:54 UTC
Permalink
Post by Richard Smith
I think the best thing to do would be to write a short paper
This is my conclusion as well. I will do so early next year.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Woehlke
2015-12-18 16:28:30 UTC
Permalink
Post by Viacheslav Usov
Post by Matthew Woehlke
Also, the basis of your proposal is to blur the line between types,
functions, and variables.
Then explain why the use of auto is not to blur the line between different
types; or why that is not a bad idea.
That's like saying "because it's okay to blur the lines between a
Rottweiler and a Pug, it must also be okay to blur the line between a
dog and a cucumber... or a socket wrench".

Uh... yeah. I think that sums it up nicely.

(Also, what Ville said.)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 16:36:20 UTC
Permalink
Post by Matthew Woehlke
That's like saying "because it's okay to blur the lines between a
Rottweiler and a Pug, it must also be okay to blur the line between a dog
and a cucumber... or a socket wrench".

It might be. Or may not. Unless you explain why doing it is OK in one case
and not OK in the other, I do not think we can argue about that rationally.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-21 08:51:05 UTC
Permalink
Post by Matthew Woehlke
Also, the basis of your proposal is to blur the line between types,
functions, and variables.

I'd like to dispute this point once more.

Consider this code:

A::B();

Without seeing how A and B were defined or declared, one can only say that
A can be a namespace or a class type, and B can be a function, a type, or
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.

Now, if we say (using proposed syntax)

using X = A;
using Y = B;
X::Y();

Has that blurred the line between types, functions and variables *any
more* than
it was blurred in the first excerpt? In my opinion, it has not. Your
objection, in my opinion, is in that the current semantics of using X = Y
is partly to *disambiguate* the nature of Y, making it clear it is a type
and nothing else, and we lose this feature in my proposal So it is entirely
equivalent to the objection by Ville Voutilaine.

But the question is, was using X = Y ever supposed to be such a
disambiguator? I doubt it was the case and I concur with Richard Smith that
we would be making a major mistake if we lock this syntax into this
unintended role.

I could trivially modify my proposal to satisfy Ville
Voutilaine's constraint, say into 'using X for Y'; but then we would have
yet another syntax for aliasing, despite the fact 'using X = Y' was clearly
earmarked for more general use in the original proposal.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Magnus Fromreide
2015-12-21 09:07:00 UTC
Permalink
Post by Matthew Woehlke
Post by Matthew Woehlke
Also, the basis of your proposal is to blur the line between types,
functions, and variables.
I'd like to dispute this point once more.
A::B();
Without seeing how A and B were defined or declared, one can only say that
A can be a namespace or a class type, and B can be a function, a type, or
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.
Now, if we say (using proposed syntax)
using X = A;
using Y = B;
X::Y();
Is this really what you mean to propose?

Would, at this point,

C::Y();

call C::B()?, i.e. is your using some kind of macro facility?

Also, what happens with A::Y(), would that be inaccessible after the
using declarations?

/MF
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-21 09:18:49 UTC
Permalink
Post by Magnus Fromreide
Is this really what you mean to propose?
Oops, I really meant to say this:

using X = A;
using Y = X::B;
Y();

It is a not macro-kind-of thing.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2015-12-21 13:12:50 UTC
Permalink
Post by Viacheslav Usov
A::B();
Without seeing how A and B were defined or declared, one can only say that
A can be a namespace or a class type, and B can be a function, a type, or
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.
No one writes code like that. This is not a valid example.

First of all, if any of your co-workers is writing namespaces, function names
or class names with single letters, they require retraining. There may be
exceptions, but those exceptions can only be accepted if the entire
development team knows about it, in which case you know what A::B() is.

Second, even if it weren't the case, most projects have coding conventions.
For example, since B starts with a capital letter, I conclude it's the name of
a type, so the statement above creates a temporary and destroys it. Whether A
is a namespace or whether it's a class name and B is a typedef to A inside of
A, it's not relevant.

If you're trying to solve the case of a third-party code that is so bad that
you can't tell what it is doing, then you *need* to know what A and B are. So
you'll look them up, then apply code refactoring to rename them so you'll know
later (we've done that recently in an old C project without comments and with
functions named with one letter, each).
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Larry Evans
2015-12-21 13:43:06 UTC
Permalink
Post by Thiago Macieira
Post by Viacheslav Usov
A::B();
Without seeing how A and B were defined or declared, one can only say that
A can be a namespace or a class type, and B can be a function, a type, or
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.
No one writes code like that. This is not a valid example.
First of all, if any of your co-workers is writing namespaces, function names
or class names with single letters, they require retraining. There may be
exceptions, but those exceptions can only be accepted if the entire
development team knows about it, in which case you know what A::B() is.
Second, even if it weren't the case, most projects have coding conventions.
For example, since B starts with a capital letter, I conclude it's the name of
a type, so the statement above creates a temporary and destroys it. Whether A
is a namespace or whether it's a class name and B is a typedef to A inside of
A, it's not relevant.
If you're trying to solve the case of a third-party code that is so bad that
you can't tell what it is doing, then you *need* to know what A and B are. So
you'll look them up, then apply code refactoring to rename them so you'll know
later (we've done that recently in an old C project without comments and with
functions named with one letter, each).
I'm pretty sure Mr. Usov was using single letter names solely to
make the example easier to read. After all, the only purpose of
using longer names is to make the names more meaningful, but
the only "meaning" of A,B,X,Y in Usov's example is to represent
some name, which, in the real world, would be the more meaningful
names which a "properly trained co-worker" would supply.

-regards,
Larry
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2015-12-23 11:33:14 UTC
Permalink
Post by Larry Evans
I'm pretty sure Mr. Usov was using single letter names solely to
make the example easier to read. After all, the only purpose of
using longer names is to make the names more meaningful, but
the only "meaning" of A,B,X,Y in Usov's example is to represent
some name, which, in the real world, would be the more meaningful
names which a "properly trained co-worker" would supply.
I understand that, but that made the example invalid.

Let's try hearing the argument again when A, B, X, and Y are replaced with
names that unambiguously explain whether they're namespaces, type names, or
function names.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-23 14:26:09 UTC
Permalink
Post by Thiago Macieira
Post by Larry Evans
I'm pretty sure Mr. Usov was using single letter names solely to
make the example easier to read. After all, the only purpose of
using longer names is to make the names more meaningful, but
the only "meaning" of A,B,X,Y in Usov's example is to represent
some name, which, in the real world, would be the more meaningful
names which a "properly trained co-worker" would supply.
I understand that, but that made the example invalid.
Let's try hearing the argument again when A, B, X, and Y are replaced with
names that unambiguously explain whether they're namespaces, type names, or
function names.
I'm not sure that's possible. I have seen very few cases where the name of
a construct automatically tells you whether it's a typename or a namespace.
Variables and types tend to have more distinguishing names., but not
typenames and namespaces.

But let's look at some of the namespace names we have in C++, just in the
standard library:

* std
* filesystem
* literals

`std` is so nebulous that who knows what it even means; you learn that one
by convention. However, there are *many* libraries that have "filesystem"
objects, so `filesystem` could easily be a typename. Or even a variable,
representing a global filesystem.

`literals`... if you know that refers to user-defined literals, then you
can probably assume it's a namespace. But otherwise... who knows.

Yes, there are some namespace names that are named differently from types.
But these tend to be the root namespace for a library. Once you start
subdividing namespaces more finely, you'll find some overlap between
namespace naming and typenames.

Of course, that only torpedoes his argument even more. Being able to see a
difference at the time when a declaration is made as to whether or not it's
a namespace or a type is very important, and this is one reason why. If you
can't see a difference between `namespace X = Y` and `using W = Z`, then
you would have to track down the declaration of `Y` and `Z` to figure out
what's actually going on.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-23 15:13:02 UTC
Permalink
Post by Nicol Bolas
Of course, that only torpedoes his argument even more.
Yup; not referencing "his argument" makes for a firing solution that always
works.

My argument in this particular branch of the discussion:

If one can grasp from the name Y whether it is a namespace or a type or
whatever, then using X = Y does not blur anything.

And being unable to grasp that was ruled out by Thiago Macieira [1].

Cheers,
V.

[1] "No one writes code like that. This is not a valid example."
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2015-12-23 21:26:46 UTC
Permalink
Post by Viacheslav Usov
If one can grasp from the name Y whether it is a namespace or a type or
whatever, then using X = Y does not blur anything.
Indeed. But then what's the value of having a unified syntax?
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-29 10:36:13 UTC
Permalink
Post by Thiago Macieira
Indeed. But then what's the value of having a unified syntax?
That was addressed earlier, by me and Richard Smith, so I won't repeat that
again.

But perhaps there is another argument. What is the value of 'using' over
'typedef', except in dealing with templates? I would say it is marginal in
the slightly less weird type specification in complicated cases. Yet I find
(looking at my and my colleagues' code) that we do not need 'typedef' at
all, even in the simplest cases. The generality of 'using' *alone* makes it
preferable to other means in *every *case.

Yet another argument is given in n1449:

The original draft of this proposal was well received by the Evolution
Working Group at the Oxford meeting. After the initial presentation of this
paper we worked on carrying these ideas further. First we considered
extending the proposal to include the notion of function template aliases:

template using F = f >(int, char); // does this require a signature?

We also briefly considered non-template aliasing:

using F = f(int);
using Cos = cos; // whole overload set?

Two straw polls were taken regarding syntax. A strong majority voted to
avoid the typedef template syntax, in favor of the “=” syntax. A second
vote indicated strong preference for the “using” keyword as opposed to a
word like “alias” or the absence of any keyword as in the draft version of
this proposal. *The motivation for using any keyword at all stemmed partly
from the desire to use a syntax that might be compatible with the
non-template aliasing direction briefly outlined above.*

(end quote)

The current 'using' syntax was introduced at least partly because EWG saw a
value in its suitability for other kinds of aliasing. That was re-affirmed
in n2258, which made it into the standard.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-29 14:53:45 UTC
Permalink
Post by Viacheslav Usov
Post by Thiago Macieira
Indeed. But then what's the value of having a unified syntax?
That was addressed earlier, by me and Richard Smith, so I won't repeat
that again.
But perhaps there is another argument. What is the value of 'using' over
Post by Viacheslav Usov
'typedef', except in dealing with templates?
It fits normal C++ convention. Non-variable declarations of names tend to
be of the form:

Keyword(s) IntroducedName <Other Stuff Describing Name>;

C++11 even allowed function declarations to fit that model:

auto FunctionName(parameters) -> Return;

While this was added for an entirely different purpose, it does make the
syntax for declarations more regular as well.

Typedefs have been the odd man out in this regard. The typename comes
*last* instead of first. Or in the case of function pointers, in the middle
somewhere.

I would say it is marginal in the slightly less weird type specification in
Post by Viacheslav Usov
complicated cases. Yet I find (looking at my and my colleagues' code) that
we do not need 'typedef' at all, even in the simplest cases. The generality
of 'using' *alone* makes it preferable to other means in *every *case.
No, it does not.

`using` is better than `typedef` because it makes more sense. It fits C++
syntax better, as shown above. That's why it was adapted to subsume all
uses of `typedefs`, rather than just the template case.

Typedefs for function pointers are a particular pain point:

typedef Return (*IntroducedName)(Parameters);

It's hard to figure out where the new name is supposed to be in that.
Especially if `Return` is something big and complex. By contrast:

using IntroducedName = Return(*)(Parameters);

This is much more legible. The important information, the new name, is
easily visible.

Yet another argument is given in n1449:
No, that is an argument for applying `using` in the cases of all *type*
aliases. It is *not* an argument for applying `using` in the case of all
aliases period.

An argument for expanding `using` to subsume one syntax is *not* an
argument for subsuming another syntax.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-29 15:28:10 UTC
Permalink
The generality of 'using' *alone* makes it preferable to other means in *every
*case.
No, it does not.
And then you expand verbosely how 'using' is much better than 'typedef' for
reasons *other than generality*, while failing to show that generality
alone does *not* make it preferable.
The current 'using' syntax was introduced at least partly because EWG saw
a value in its suitability for other kinds of aliasing.
No, that is an argument for applying `using` in the cases of all *type*
aliases. It is *not* an argument for applying `using` in the case of all
aliases period.

Which, again, falls short of being a true negation of what I wrote.

I could say that your use of 'no' is merely illogical; but given how
carefully you redacted my reference to n2258, what I see is really just
splitting hairs.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2015-12-23 21:27:44 UTC
Permalink
Post by Nicol Bolas
I'm not sure that's possible. I have seen very few cases where the name of
a construct automatically tells you whether it's a typename or a namespace.
Variables and types tend to have more distinguishing names., but not
typenames and namespaces.
Maybe you should seek frameworks that have better coding conventions instead.
Post by Nicol Bolas
But let's look at some of the namespace names we have in C++, just in the
* std
* filesystem
* literals
<purely subjective>
And that would be an example of a framework with a bad coding convention,
where everything is lowercase, some things are separated by space and some
things not (type_info in <typeinfo>), methods are not consistently named after
verbs in a particular tense reflecting their purpose, and the list goes on.
Your are more evidence of this.
</purely subjective>

Note that "no one writes code like that" does not apply here. That was to
entities named after one letters.
Post by Nicol Bolas
`std` is so nebulous that who knows what it even means; you learn that one
by convention. However, there are *many* libraries that have "filesystem"
objects, so `filesystem` could easily be a typename. Or even a variable,
representing a global filesystem.
"std" is a name apart because everyone knows what it is. How it came to be
named is irrelevant and never should be in any argument. That includes reasons
for naming other namespaces.

[snip the rest]
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-21 13:43:35 UTC
Permalink
Post by Thiago Macieira
Post by Viacheslav Usov
A::B();
Without seeing how A and B were defined or declared, one can only say
that
Post by Viacheslav Usov
A can be a namespace or a class type, and B can be a function, a type, or
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.
No one writes code like that. This is not a valid example.
First of all, if any of your co-workers is writing namespaces, function names
or class names with single letters, they require retraining. There may be
exceptions, but those exceptions can only be accepted if the entire
development team knows about it, in which case you know what A::B() is.
Second, even if it weren't the case, most projects have coding conventions.
For example, since B starts with a capital letter, I conclude it's the name of
a type, so the statement above creates a temporary and destroys it. Whether A
is a namespace or whether it's a class name and B is a typedef to A inside of
A, it's not relevant.
The point that was I disputing was that the extended syntax 'using X = Y'
blurs the line between types, namespaces, functions and variables.

If we stipulate that Y makes that unambiguous, then the whole point is moot.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
i***@gmail.com
2015-12-22 01:12:44 UTC
Permalink
Post by Viacheslav Usov
Post by Thiago Macieira
Post by Viacheslav Usov
A::B();
Without seeing how A and B were defined or declared, one can only say
that
Post by Viacheslav Usov
A can be a namespace or a class type, and B can be a function, a type,
or
Post by Viacheslav Usov
an object, and I hope I have not missed some other possibility. It is
probably going to far if we say say that A and B can be pretty much
everything that C++ has to offer, but it is not much less than that.
No one writes code like that. This is not a valid example.
First of all, if any of your co-workers is writing namespaces, function names
or class names with single letters, they require retraining. There may be
exceptions, but those exceptions can only be accepted if the entire
development team knows about it, in which case you know what A::B() is.
Second, even if it weren't the case, most projects have coding conventions.
For example, since B starts with a capital letter, I conclude it's the name of
a type, so the statement above creates a temporary and destroys it. Whether A
is a namespace or whether it's a class name and B is a typedef to A inside of
A, it's not relevant.
The point that was I disputing was that the extended syntax 'using X = Y'
blurs the line between types, namespaces, functions and variables.
If we stipulate that Y makes that unambiguous, then the whole point is moot.
Cheers,
V.
Only place for me where this could be used is templates parameters where
you could accept values and types as one parameter:
template<template<using... > typename F, using First, using Second>
struct X
{
using F = First; //can by type or constexpr value, can't be used
directly otherwise
using type = F<First, Second>; //indirect use
};

typename X<std::array, int, 3>::type a;
typename X<std::vector, int, my_alloc>::type b;
This isn't exactly same proposal, but share one common thing: treating
`using` as catch all case.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Woehlke
2015-12-18 15:56:06 UTC
Permalink
Post by Nicol Bolas
Post by Viacheslav Usov
Post by Nicol Bolas
You cannot exchange a struct for a *function*.
Except when we can. And we can do so very often.
The premises of your argument are invalid.
Declaring something to be invalid does not make it invalid.
If you want to argue that *transparently* exchanging a struct for a
function is something you can do, prove it. Show me under what
circumstances this is acceptable. And then show that the other
circumstances which would prevent it are not usable.
class Foo { /* details unimportant */ };
auto ct = Foo; // note; no construction
auto x = ct{}; // construction
assert(std::is_same_type<decltype(x), Foo>::value);

...of course that doesn't work in C++. Making it work in a strongly
typed language would be... difficult. In particular, I don't see how
runtime method dispatch could be made to work (not, anyway, without
twisting the language into a bowl of spaghetti).

It works in Python ;-). But I don't see it happening in C++.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
FrankHB1989
2015-12-21 07:52:54 UTC
Permalink
圚 2015幎12月17日星期四 UTC+8䞋午10:17:43Nicol Bolas写道
Post by Nicol Bolas
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Because they're not the same thing. However much you may want to think of
`C` and `D` as "aliases", they are not. They are *references to objects*.
"Thing" is not a term in C++. So it is depend on the meaning of "thing".
They can be same things because `B`, `C`, `D` are "names", which denotes
"entities".

Variable of reference type may be used as aliases. They are similar in
usage.

One more example is namespace alias. Why they should have different syntax
at first? Though "auto& alias = ns;" is horrible without type system
support, but what about "using"?

Doing `B b{};` is legal. Doing `C c{};` is not. It makes perfect sense that
Post by Nicol Bolas
creating a typename alias and creating an object reference would require
different syntax. Just as creating a namespace alias uses different syntax
from a typename alias.
This is not required by "alias".
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Richard Smith
2015-12-17 19:24:02 UTC
Permalink
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Is there any fundamental reason why using X = Y cannot (or should not) be
valid for all kinds of names?
For prior work in this area, see section 2 of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf -- this
was considered when the "using X = Y;" syntax was first proposed as a
possible eventual extension.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-17 23:37:47 UTC
Permalink
Post by Richard Smith
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Is there any fundamental reason why using X = Y cannot (or should not) be
valid for all kinds of names?
For prior work in this area, see section 2 of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf -- this
was considered when the "using X = Y;" syntax was first proposed as a
possible eventual extension.
Actually, that made me remember something. P0109
<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0109r0.pdf>
actually came up with a good reason to allow function aliasing. It's
primarily used as a way of implementing certain aspects of strong typedefs
though.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 12:11:40 UTC
Permalink
Post by Richard Smith
For prior work in this area, see section 2 of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf -- this
was considered when the "using X = Y;" syntax was first proposed as a
possible eventual extension.

Thanks for the pointer. What I see there, though, is that the syntax was
*not* proposed, they merely admitted it was possible for things other than
types. It seems they were quite certain that the extension covering
namespaces would be a good thing: "The alias-declaration syntax appears to
be more general and more uniform. It also contains the traditional
using-declaration as a special case." I am not sure why the same could not
be said verbatim in section 2.3.

It is definitely true that a general mechanism that can select and define
an alias for an entity is a good thing. The need to lift some elaborately
decorated entities into current scope and use them via aliases is real, it
is understood and addressed in the current language, except this is done
via three different syntaxes (or four, if we count pointers). If nothing
else, the uniform syntax addressing the need would be easy to learn, and
add a bit more of DRY to the language. This is similar to how much more
clarity we have now with auto.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Nicol Bolas
2015-12-18 14:42:45 UTC
Permalink
Post by Richard Smith
Post by Richard Smith
For prior work in this area, see section 2 of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf -- this
was considered when the "using X = Y;" syntax was first proposed as a
possible eventual extension.
Thanks for the pointer. What I see there, though, is that the syntax was
*not* proposed, they merely admitted it was possible for things other
than types. It seems they were quite certain that the extension covering
namespaces would be a good thing: "The alias-declaration syntax appears to
be more general and more uniform. It also contains the traditional
using-declaration as a special case." I am not sure why the same could not
be said verbatim in section 2.3.
It is definitely true that a general mechanism that can select and define
Post by Richard Smith
an alias for an entity is a good thing.
No, it is not "definitely true"; that's what you're trying to prove. You
cannot prove something by assuming it.
Post by Richard Smith
The need to lift some elaborately decorated entities into current scope
and use them via aliases is real, it is understood and addressed in the
current language, except this is done via three different syntaxes (or
four, if we count pointers).
And all of these create different constructs.

Namespaces are different from typenames. Typenames are different from
variables. Variables are different from functions. Having a single syntax
that treats these "aliases" of different things as though they were the
same is *lying* to the coder by making them think that they are
interchangeable.

Also, a pointer is not an alias. It's not even a reference; it's an *object*
.

If nothing else, the uniform syntax addressing the need would be easy to
Post by Richard Smith
learn, and add a bit more of DRY to the language. This is similar to how
much more clarity we have now with auto.
You've made three claims here: ease of learning, removing repetition, and
improving clarity. I'll take them one at a time.

The ease of learning issue. Well, your syntax only covers the case of
creating non-const l-value references from an actual variable. That is, it
only covers this:

auto & var = other_var;
using var = other_var;

Well, what if the user needs to create a const reference? Are you going to
allow:

const using var = other_var;

But we're talking about learning here. And learning is exactly the problem.
See, the user still needs to know how to create references, because they're
going to be using them in other ways. For example:

for(auto &var: some_vector)
{...}

Is the user going to be able to use `using` syntax to create references
from that? If not, then the user *still* has to know how the old syntax
works. And that's not the only place where they'll have to declare
references. The user still has to know how to declare reference variables
as function parameters too. There'd be no reasonable way to stick `using`
in there.

So the *only* place where learning would allegedly be eased is when you are
declaring a naked stack variable declared as `auto &`. But the user already
needs to know how `auto` works as well as how references work. So... how
have you improved learning, when they still need to know the old way too?

All you've done is given users *more* to learn, not less; that's not
helping them learn. So long as the user still needs to use references
directly, I see no benefit to learning this `using` syntax.

As for repetition and clarity... what are you talking about? Where is the
repetition you're trying to avoid? Where is the lack of clarity that you
want to impvoe? Your suggestion is to exchange this:

namespace Name = OtherNamespace;
using Type = OtherType;
auto &Var = OtherVariable;

For this:

using Name = OtherNamespace;
using Type = OtherType;
using Var = OtherVariable;

The current case has no repetition. Indeed, the two cases have almost the
exact same number of tokens (the reference case requiring the `&` token),
and the difference in keystrokes between them is minimal.

The current case is no less clear than what you want. It's readily apparent
what's going on in both cases. So you aren't improving clarity at all.

So again, I find your motivation for this proposal lacking.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Viacheslav Usov
2015-12-18 15:39:28 UTC
Permalink
Post by Nicol Bolas
No, it is not "definitely true"; that's what you're trying to prove. You
cannot prove something by assuming it.

We are not proving a theorem here, Nicol. If you find that "a general
mechanism that can select and define an alias for an entity is a good
thing" needs to be substantiated further, then I can only suggest that you
should practice programming for a few more years.
Post by Nicol Bolas
Having a single syntax that treats these "aliases" of different things as
though they were the same is *lying* to the coder by making them think that
they are interchangeable.

Nonsense. The proposed syntax does not treat aliases as though they were
the same; it merely creates them uniformly.
Post by Nicol Bolas
Also, a pointer is not an alias. It's not even a reference; it's an
*object*.

Are you arguing just for the sake of arguing?
Post by Nicol Bolas
Well, what if the user needs to create a const reference? Are you going
to allow:

In what clause of my proposal have you found that? Is this another straw
man?

And by the way, in my proposal I identified using X = Y with auto &X = Y
when Y is a variable or a function; this is, however, not essential for the
proposal. The desired semantics is "X is another name for Y", not really "X
is a reference to Y" even though the latter means very nearly the former.
Post by Nicol Bolas
All you've done is given users *more* to learn, not less; that's not
helping them learn.

No. using X = Y is already something that must be learnt. It is easier to
learn that everything aliasable can be aliased with this one mechanism.
Post by Nicol Bolas
The current case has no repetition.
Repetition here is not in keystrokes. It is in having to express, again,
that OtherNamespace is a namespace, OtherType is a type, and OtherVariable
is a variable.

Cheers,
V.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
FrankHB1989
2015-12-21 08:30:10 UTC
Permalink
圚 2015幎12月18日星期五 UTC+8䞋午10:42:46Nicol Bolas写道
Post by Viacheslav Usov
Post by Richard Smith
Post by Richard Smith
For prior work in this area, see section 2 of
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1489.pdf --
this was considered when the "using X = Y;" syntax was first proposed as a
possible eventual extension.
Thanks for the pointer. What I see there, though, is that the syntax was
*not* proposed, they merely admitted it was possible for things other
than types. It seems they were quite certain that the extension covering
namespaces would be a good thing: "The alias-declaration syntax appears to
be more general and more uniform. It also contains the traditional
using-declaration as a special case." I am not sure why the same could not
be said verbatim in section 2.3.
It is definitely true that a general mechanism that can select and define
Post by Richard Smith
an alias for an entity is a good thing.
No, it is not "definitely true"; that's what you're trying to prove. You
cannot prove something by assuming it.
It is easy to illustrate the negative proposition: it's true that lack of
such abilities in the language is not a good thing, for some general tasks.
(Why we bother reflection if the language has already be homoiconic?)
Post by Viacheslav Usov
Post by Richard Smith
The need to lift some elaborately decorated entities into current scope
and use them via aliases is real, it is understood and addressed in the
current language, except this is done via three different syntaxes (or
four, if we count pointers).
And all of these create different constructs.
Namespaces are different from typenames. Typenames are different from
variables. Variables are different from functions. Having a single syntax
that treats these "aliases" of different things as though they were the
same is *lying* to the coder by making them think that they are
interchangeable.
Also, a pointer is not an alias. It's not even a reference; it's an
*object*.
The difference is by design. The design may be not good at first. It is
not immutable. At least, it should be open to be extended.

For example, there are no references in C. C++ copied most of the type
system, and added references (with other modifications). References are
definitely not object types. However, declared objects, functions and (non
data member) references can be all treated as "variables". When only
"variables" are needed (e.g. in lambda capture), you should not care
whether it is a reference or not. Note that C has no "variable" in this
means. It is nonsense to talk about the latter in C rules. The design of C
here is disabled.

For another example, there are no lambdas in C++98. C++11 added lambda
expressions. They are definitely not functions. However, they can be
treated as same thing in some rewriting systems, notably, lambda calculi.
C++ has no support to such systems. So if there are need to put them
together, current C++ rules are not enough. The design of current C++ here
is disabled.

Note that I don't support such proposals just for these reasons. The amount
of work to adding lambda expressions are reasonable and the work is
actually done, but change the whole type system or even typing discipline
is certainly not. Change rules out of the type system is even more
dangerous. But the underlying principle should be clear: prevent
modification of the language by the current design, not by intention.
Distinction on current features serve for different goals, but they do not
make the ability to ignore the differences invalid. (Oh, why some C guys
prefer manual single method dispatch over C++ virtual functions?)
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
FrankHB1989
2015-12-21 08:55:10 UTC
Permalink
圚 2015幎12月17日星期四 UTC+8䞋午8:52:11Viacheslav Usov写道
Post by Viacheslav Usov
namespace foo
{
struct bar {};
void baz() {}
int qux;
}
namespace A = foo;
using B = foo::bar;
auto &C = foo::baz;
auto &D = foo::qux;
The question is, why do we have to use at least three different ways in
order to say use X as an alias of Y?
Is there any fundamental reason why using X = Y cannot (or should not) be
valid for all kinds of names?
Cheers,
V.
There is no reason to prevent this feature in the language rules
generally, but not for C++. C++ is not designed with such use cases in
mind (it is based on C; and C does not, either). And it is not easy to
patch current C++ rules to adopt this feature. There are some subtle
issues, e.g. as N1489 mentioned. So it is likely not worth doing, for C++.

If you strongly want to use this feature, you can invent a language with
it, and implement it by translating it to C++, like the ancient "C with
classes" did.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
Loading...