Proposal: Object/?? Destruction

Timon Gehr timon.gehr at gmx.ch
Thu Oct 5 19:42:38 UTC 2017


On 05.10.2017 17:40, Steven Schveighoffer wrote:
> On 10/5/17 2:42 AM, Timon Gehr wrote:
> 
>> The only unresolved question is (as using the result of the comma 
>> operator has been deprecated already): How to write a unary tuple. My 
>> favourite is what python does: "(3,)". This is however already 
>> accepted as a function argument list. I think it is worth breaking 
>> though. Maybe we should deprecate it.
> 
> I know you have an answer for this, but pardon my ignorance.

I indeed have strong opinions on how to do this correctly, as I have 
given some thought to it when designing the (still quite basic) type 
system of PSI: https://github.com/eth-srl/psi

The idea is to follow type theory/mathematics where the type of 
functions is a binary type constructor taking domain and codomain to the 
type of functions mapping values from the domain to values from the 
codomain. Multiple function arguments are just the function applied to a 
tuple of values.

> Why isn't (a) good enough?
> 
> -Steve

typeof((a)) should be typeof(a). This is just a parenthesized 
expression, as in (a+b)*c.

typeof((a,)) should be (typeof(a),).

(I'm not super keen on conflating the type of a tuple with a tuple of 
types, but this has precedent in alias sequences, and I think it will be 
intuitive to most D users. FWIW, Haskell also does this.)

My intention is to disentangle the concepts "function argument" and 
"multiple values" as much as possible.

For example:

---
(int,string,double) foo(int a,string b,double c){
     return (a,b,c);
}

(int,string) bar(int a,string b,double c){
     return (a,b);
}

void main(){
     auto x = foo(1,"2",3.0); // ok, typeof(x) is (int,string double)
     //          ^^^^^^^^^^^
     // syntax of function argument is the same as the
     // syntax for a free-standing tuple:
     auto y = (1,"2",3.0);

     // all functions take a single argument, so you can construct
     // the tuple either at the call site, or before that:
     (int a,string b,double c) = foo(y); // ok
     auto (x,y,z) = foo(a,b,c); // ok

     // This allows natural composition of functions.
     // It is like DIP 35 except better:
     writeln([(1,"2",3.0), (4,"5",6.0)].map!foo.map!bar);
}
---

---
(int,) foo(int a){ return (a,); } // turn value into singleton tuple
int bar(int a,){ return a[0]; }   // turn singleton tuple into value

void main(){
     foo(2,); // error: cannot convert (int,) to int
     bar(2); // error: cannot convert int to (int,)
     auto (x,) = foo(2); // ok, x has type int
     auto y = bar(2,); // ok y has type int
     auto z = foo(2); // ok, z has type (int,)
}
---

---
// The following two function signatures are equivalent (identical name 
mangling):
(int,string) foo(int a,string b){
     return (a,b);
}

(int,string) foo((int,string) x){
     return x;
}
---

---
auto id(T)(T x){ return x; }

void main(){
     auto a = id(2); // ok, a is 2.
     auto b = id(1,2); // ok, b is (1,2)
     auto c = id(1,); // ok, c is (1,)
}
---



More information about the Digitalmars-d mailing list