-
Notifications
You must be signed in to change notification settings - Fork 264
Description
This is an alternative solution to this issue. If you don't like ...TYPE
notation for object construction because of its UDL syntax, this is an alternative solution. In this suggestion, objection construction would use familiar notation EXPR:TYPE
(aka Typed Expression) which is similar to how Cpp2 programmers use it within declarations.
Consider EXPR:TYPE
as syntactic sugar to (: TYPE = EXPR)
. For example:
Abc: type;
Xyz: type;
func: (u: int) -> Abc;
a: int = 2;
b: = 2:int; // (: int = 2)
c: = a:Abc; // (: Abc = a)
d: = ():Abc; // Default Constructor
e: = (a + b):Abc; // (: Abc = a + b)
r: = func(a):Abc; // (: Abc = func(a))
s: = func(2):Abc.start():Xyz.value; // Function Chaining
t: = a++:Abc; // (: Abc = a++)
u: = a:Abc++; // (: Abc = a)++
x: = 2:int:Abc; // (: Abc =: int = 2) Constructor Chaining
y: = (2:int + 4:int):Abc; // (: Abc = (: int = 2) + (: int = 4))
z: = ("text", 2:int):Abc; // (: Abc = ("text", (: int = 2)))
Literally if x:int
is at the start of a statement or function parameter, it would be a declaration, otherwise it would be a Typed Expression.
Abc: type;
// `x: Abc` is a parameter declaration.
func: (x: Abc) = {}
// `a: int` is a declaration.
a: int = 2;
// `a:Abc` is a Typed Expression, it calls the constructor of `Abc`.
m: = a:Abc;
EXPR:TYPE
is similar to ...TYPE
suggestion, except with the following advantages:
- It's familiar and similar to declaration syntax in which types are specified in the language.
- It's easier to parse, but
...TYPE
would complicate the grammar especially for working within function chaining. - It doesn't need parentheses for simple expressions with unary postfix operators (e.g.
a++:Abc
). It depends on operator precedence, and it's left to right.
And this notation has the following disadvantages:
- It requires an extra
:
. BTW it's opinion based.
I have to explain :
within SOMETHING:TYPE
is for object construction (as an expression) or declaration (as a statement), but ::
within SOMETHING::TYPE
is scope resulotion operator for qualified names. They can be combined like 10++ : my::Type
. Also after the object is constructored, we can use operator dot or operator()
or operator[]
or ... to access members from it, e.g. 10:Type.call()
or 10:Type[0]
.
Will your feature suggestion eliminate X% of security vulnerabilities of a given kind in current C++ code?
No.
Will your feature suggestion automate or eliminate X% of current C++ guidance literature?
Yes.
- It unifies constructors with UDLs. They are semantically the same. Both of them create a new object.
- It's useful in generic programming.
- It reduces concept count.
- Novice programmers don't need to learn a distinct concept about UDLs.
- All types benefit from UDL like syntax. It's not needed to declare UDL for them.
- It eliminates the need of understanding and learning built-in prefixes and suffixes for literals.
- The syntax of calling constructors will be expressive and readable.
- It distincts constructors from regular function calls. They are semantically different.
- Constructors:
EXPR:TYPE
, parentheses are not necessary whenEXPR
has operators with higher precedence.():TYPE
, it calls the default constructor(args...):TYPE
- Regular Function Calls:
FUNCTION()
, it calls a function without argumentsFUNCTION(args...)
obj.FUNCTION()
obj.FUNCTION(args...)
- Constructors:
- They can be chained together, whereas it's not possible with UDLs in Cpp1.
- Only one UDL can be applied to a literal in Cpp1.
- Constructors already can be templated, but UDLs cannot be templated.
- UDL templates are not supported in Cpp1.
- It removes built-in literal prefixes and suffixes. They are inconsistent and redundant.
- They are visually inconsistent.
- Some of them are prefix.
- Some of them are suffix.
- Their behaviours are inconsistent when the constant of literal exceeds the type as described in this comment.
- They are visually inconsistent.
- The name to construct a literal and to declare a variable will be consistently the same.
- It's not needed to declare a new name for literal suffixes.
- The name of types are like a suffix that will construct an object.
- They can be applied to literals with qualified name (if they are within namespaces) unlike UDLs which need
using
statement before they can be applied to literals.- That's why UDLs in Cpp1 have to be prefixed with
_
, thus they will be distinguished from UDLs which are declared in the Cpp1 standard library.
- That's why UDLs in Cpp1 have to be prefixed with
- Unlike
TYPE(args)
it doesn't work with UFCS intentionally. UFCS should not work on constructors as described in this comment. Compare:// `TYPE(args)` with UFCS on it. x: = 10.Type(10, 20); // `(args):TYPE` y: = (10, 10, 20):Type;
Describe alternatives you've considered.
These are alternative solutions:
- [SUGGESTION] Literal suffixes are constructors. #455
- [SUGGESTION] Literal Templates #316 (INACTIVE)
- [SUGGESTION] Multiple suffixes for literals, a revisit of Uniform Function Call Syntax #284 (INACTIVE)
Thanks.