3 ms·
Sorry, but your response seems to be about consistency, or "purity" at some level. While what Go has may be inconsistent, what functional impact does that have
by dfawcus 2y ago
Sorry, but your response seems to be about consistency, or "purity" at some level.
While what Go has may be inconsistent, what functional impact does that have?
I can't see a need for 'de-structuring' as such, absent tuples. Even if it had real first class tuple types, like Alef did, what would one do with them? As I indicated, I'd not want to store them (other than holding in locals), prior to use.
As I recall, Alef did support de-structuring with tuples, as well as re-structuring. One could assign either way between an unnamed tuple, and an 'aggr' (it's name for a struct).
So at most I'd want to break them apart, which the return value thing gives.
Hence if I was creating Go 2.0, I can't see why I'd want to add first class tuples, but could see a use for adding tagged unions.
- rollcat 2y ago> Sorry, but your response seems to be about consistency, or "purity" at some level. > While what Go has may be inconsistent, what functional impact does that have? Same reasons why Go fixed C's: inside-out type declarations, function pointer syntax, ERRNO, headers, macros, signal handling, UB, all the things that technically had no "functional" impact but still directly contributed to consistency, ergonomics, clarity, ease of comprehension, and (either by proxy or directly) correctness. > I can't see a need for 'de-structuring' as such, absent tuples. Your playground example of a, b = b, a is not destructuring a tuple in action? It's basically the same syntax / mechanism as Python's destructuring assignment, which existed since before Go (except Python's was always more powerful). It's almost like you can do everything you want with a tuple in Go, except for actually holding it in your hand. > Even if it had real first class tuple types, like Alef did, what would one do with them? Similar things you'd do with a function without a name - work directly with the data at hand, without having to do the extra round trip to the attic to declare its name or shape. > Hence if I was creating Go 2.0, I can't see why I'd want to add first class tuples, but could see a use for adding tagged unions. That would probably break Go. I liked Chris Siebenmann's take on the subject: https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnionTypesComplexities https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnion... https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnionTypesAndZeroValues https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnion... https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnionTypesStartWithGoals https://utcc.utoronto.ca/~cks/space/blog/programming/GoUnion... Meanwhile tagged unions bring you virtually all the way to ADTs, where pattern matching (generalised destructuring) is basically a must. (By the way, Python stumbled really badly when it added pattern matching without even having proper structs. It's almost comical, given def __init__(self, ...), that should've been gone as a part of the 3.0 break-the-world.)
- dfawcus 2y ago> Similar things you'd do with a function without a name - work directly with the data at hand, without having to do the extra round trip to the attic to declare its name or shape. Note that in Alef, tuples are essentially a dual for an aggr, but with unnamed fields. So one always has to (explicitly, or implicitly via inference) declare its 'shape', in terms of number of members, and type of members. So one could declare: tuple (int, byte *, int) t; Then manipulate 't', one could also have a function return a tuple as in: tuple (int, byte *, int) something(int x) { /* ... */ } Then handle its return value either as: t = something(2); or byte *str; int value; (nil, str, value) = something(7); However the tuple 'shape' is always statically determined. Is that in your view satisfactory, or not? Or do you desires something where the tuple is an entirely dynamic type, sort of akin to syntax sugar on top of '[]interface{}'? More akin to the sort of dynamic thing which Python offers? Such that one can potentially have a program run, and each call to a given function returning a tuple may have different numbers of elements, potentially of different types within it. So that for said program, if the function return value depended upon input data, one could not determine the full set of tuples which may be returned?
- rollcat 2y agoSince func() (A, B) is different from func() (A, B, C), I'd expect first-class tuples to do the same. At which point there would be a lot of similarity between (A, B) and struct{A, B}. Perhaps they should be equivalent? From which "struct{a A, b B} = f()", or even "switch x.(type) { case struct{a A, b B}: ...}", or "case (a A, b B): ..." could follow. It might be too much Rust influence, but it might be a good influence, given there's already a lot of interest in unions/enums/ADTs (but see "start with goals"). The counter-arguments are that "type A struct{}" and "type B struct{}" are different types, and that anonymous structs are seldom found in the wild (likely due to their verbosity), but perhaps this is a chicken-and-egg problem? Go already does local type inference, because "var mypackage.VeryLongThing = mypackage.NewVeryLongThing()" is stupidly repetitive. But there's always a fine balance between code being terse and readable (I will never wrap my head around APL).