| |
| Posted by Timon Gehr in reply to Walter Bright | PermalinkReply |
|
Timon Gehr
Posted in reply to Walter Bright
| On 5/7/23 02:16, Walter Bright wrote:
> On 5/6/2023 8:55 AM, Quirin Schroll wrote:
>> For the record: I’ve objected to parentheses for tuples from the beginning. Parentheses are for grouping, not for constructing. My take on the tuples front was to look at static arrays as the special case of tuples that are homogeneous (the same type iterated), and generalize them for heterogeneous components: `int[2]` is a shorthand for `[int, int]`; and `[int, string]` is a heterogeneous tuple. You build such a tuple like you build an array: `[1, "abc"]`. Indexing with a run-time index is supported by Design by Introspection: A `[int, immutable int]` can give you `ref const(int)` access, a `[int, long]` can give you `long` access by value, but no `ref` access.
>
> I'd like Timon Gehr to weigh in on this!
There is no conflict between the two features in the first place.
I am in favor of allowing types in arbitrary expressions, as well as parentheses within types. My own D frontend already had a proof of concept implementation of that. [1]
It also does not affect anything in my fork of DMD that already has some tuple support [2]: in particular a single-element tuple is indicated with a trailing comma, like `(int,) x = (1,);`. Having `(int) x = (1);` mean `int x = 1` would be fully consistent and unsurprising.
[1] https://github.com/tgehr/d-compiler/
[2] https://github.com/tgehr/dmd/tree/tuple-syntax
About the attack on standard tuple syntax with parentheses: Having `T[2]` be a tuple type `[T,T]` is one of those things that initially sound good enough on paper until you actually examine the existing array semantics that D already has and try to square them with tuple semantics. It does not work at all. D would need to break arrays. It's a pipe dream.
It's not that I don't get that fixed-length arrays and tuples (and variable-length-arrays and argument lists etc) can be fully unified in principle (I have done it in some of my own languages [3]), it's just that it cannot really be done well as an afterthought.
[3] https://github.com/eth-sri/silq
def rev[τ:*,n:!ℕ](xs:τ^n){
for i in 0..n div 2{
(xs[i],xs[n-1-i]):=(xs[n-1-i],xs[i])
}
return xs;
}
def main(){
t:=(1,(2,3)): !ℕ×!ℕ^2;
a:=(1,2,4,3): !ℕ^4;
assert(rev(a)=(3,4,2,1));
assert(rev(a,)=(a,));
assert(rev(1,2,3)=(3,2,1));
n:=2+measure(H(0:𝔹)); // (n is 2 or 3 with equal probability)
b:=vector(n,0:!ℕ);
for i in 0..n{ b[i]=i; }
assert(rev(rev(b))=b);
}
|