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 when EXPR has operators with higher precedence.
():TYPE, it calls the default constructor
(args...):TYPE
- Regular Function Calls:
FUNCTION(), it calls a function without arguments
FUNCTION(args...)
obj.FUNCTION()
obj.FUNCTION(args...)
- 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.
- 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.
- 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:
Thanks.
This is an alternative solution to this issue. If you don't like
...TYPEnotation for object construction because of its UDL syntax, this is an alternative solution. In this suggestion, objection construction would use familiar notationEXPR:TYPE(aka Typed Expression) which is similar to how Cpp2 programmers use it within declarations.Consider
EXPR:TYPEas syntactic sugar to(: TYPE = EXPR). For example:Literally if
x:intis at the start of a statement or function parameter, it would be a declaration, otherwise it would be a Typed Expression.EXPR:TYPEis similar to...TYPEsuggestion, except with the following advantages:...TYPEwould complicate the grammar especially for working within function chaining.a++:Abc). It depends on operator precedence, and it's left to right.And this notation has the following disadvantages:
:. BTW it's opinion based.I have to explain
:withinSOMETHING:TYPEis for object construction (as an expression) or declaration (as a statement), but::withinSOMETHING::TYPEis scope resulotion operator for qualified names. They can be combined like10++ : my::Type. Also after the object is constructored, we can use operator dot oroperator()oroperator[]or ... to access members from it, e.g.10:Type.call()or10: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.
EXPR:TYPE, parentheses are not necessary whenEXPRhas operators with higher precedence.():TYPE, it calls the default constructor(args...):TYPEFUNCTION(), it calls a function without argumentsFUNCTION(args...)obj.FUNCTION()obj.FUNCTION(args...)usingstatement before they can be applied to literals._, thus they will be distinguished from UDLs which are declared in the Cpp1 standard library.TYPE(args)it doesn't work with UFCS intentionally. UFCS should not work on constructors as described in this comment. Compare:Describe alternatives you've considered.
These are alternative solutions:
Thanks.