Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 7:25 PM, Hans-Peter Diettrich drdiettri...@aol.com wrote: Consider these examples: var x, y, z: Integer; pt: TPoint; ... (x, y) // record a, b: Integer; end; (x, (y))// record a, b: Integer; end; (x, (y, z))// record a, b: Integer; end; (x, TPoint(y, z)) // record a: Integer; b: TPoint; end; (TPoint(x, y), TPoint(y, z)) // record a, b: TPoint; end; (TPoint(x, y), pt) // record a, b: TPoint; end; (TPoint(x, y), Tuple(pt)) // record a: TPoint; b, c: Integer; end; I don't see the correspondence between the left and right sides, sorry. I also dont see whether the left sides are tuple constructors or deconstructors, what's the intended effect... Right side contains examples of records which would be compatible with the tuples on the left -- for both construction and deconstruction. True, functional programming is certainly the largest modern paradigm still lacking from FPC. What's modern? I've learned about functional programming in 1970 - did all the following languages miss something important? Current consensus in the field of programming languages design is that they did -- which is why FP features are added to just eny language you look at, from C++ to PHP :) Why do you expect any difference between A[Tuple(APos1)] := 1.0; and A[APos1] := 1.0; ? The compiler will have to create the same code for both notations, or use the same RTL subroutine for doing the job. The idea is that second case will require a manually-written operator[], while the first one will work automatically. NACK. How comes that the compiler should break a tuple into a list of indices, but not an array? In detail when the tuple contains such an array? Well, that was the idea, auto- breaking a tuple but not an array, so by converting array to tuple programmer can control it. Note again that I did not mean tuple to be a type, so what I suggested is a convention, which might be adopted by some library for real-time, embedded or other low-level usage where exceptions add too much overhead: res, error := SomeFunction(params); where types of result and error will be chosen as appropriate for each function. The advantages over usual res := SomeFunction(params, error) being: 1) Easier to read, once reader knows the convention 2) Ignoring error is more prominent: res, nil := SomeFunction(params); 3) Since the result is actually a record, functions may still be chained, while ignoring errors: SomeFunction1(SomeFinction2(params).res); The latter looks like breaking tuple rules, by acessing a tuple element by name. The record becomes a tuple only by either explicit conversion, or deconstructing assignment. This means more writing, and the typical use of error codes becomes much more complicated IMO: if f(x, res) then ... has to be rewritten as res, error := f(x); //or: (res,error) := f(x);? if error then ... That depends on the type or err That's why I wonder about yet another syntax proposal. Your proposal *requires* that a record/tuple type *is* used for the result, where otherwise the subroutine could return the result in an CPU or FPU register, ready for immediate further use. There is no reason why a record can not be returned in a register. Actually, there is perhaps even greater chance for that compared to out parameter, which is usually implemented as pointer. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, Jan 27, 2013 at 12:35 PM, Hans-Peter Diettrich drdiettri...@aol.com wrote: (a, b) := (b, a); // the compiler needs to ensure the correct usage of temps here! What will happen here? At compile time a tuple type (integer; integer) has to be defined, and an instance must be allocated for it. Initialization and finalization information/code must be added if required. At runtime the arguments are copied into that tuple instance, then copied into the target variables. All copies may be subject to type conversions and reference counting. Consider memory usage and runtime when tuples are nested, or contain large data structures (records, static arrays...). Any time large data structures are used as values (as opposed to references), the incur memory and run-time overhead -- parameter passing, assignment, etc. Tuples are neither better not worse in this aspect. Additionally, standard optimization techniques may be used to significantly reduce or even eliminate the overhead: a, b := b, a = temp1 := b; temp2 := a; a := temp1; b := temp2; = optimizer may notice that temp1 is redundant = temp2 := a; a := b; b := temp2; which is exactly equivalent to manually written code. Also note that in my version of proposal, nested tuples are impossible. a := 42; (a, e) := (a * 2, a); // (a, e) should be (84, 42), not (84, 84) Such code tends to become cryptic with larger tuples. High level (source code) debugging will be impossible :-( Why do you think so? I think adding tuples as watchable item to debugger is rather straight forward, although a bit redundand. Actually, even totally independently from tuples, allowing to enter several comma-separated values in evaluate/modify window to be displayed at once would be a useful feature. * Possible extensions Note: This section is not completely thought through! An possible extension would be to allow the assignment of tuples to records and/or arrays (and vice versa). [...] Without references to distinct tuple elements the coder has to provide local variables for *all* tuple elements, then decompose the *entire* tuple, before access to a single element will be possible. This may be accomplished with less source code when a tuple can be assigned to a record variable, but then it would be simpler to use records *instead* of tuples. This is why I think tuples as a data type are not needed. Instead, I suggest them as a powerful way to manipulate records, arrays, and parameter lists using one relatively simple concept. Also, note nil as lvalue paragraph of my proposal, which allows to deconstruct only part of tuple, ignoring the rest. BTW, I just remembered another tuple usage example: type T3DMatrix = array of array of array of Double; TMatrixPos = array [1..3] of Double; procedure P(A: T3DMatrix; APos1: TMatrixPos); begin A[Tuple(APos1)] := 1.0; // Instead of A[APos[1], APos[2], APos[3]] end; When a record type is modified, during development, all *compatible* tuples and tuple types must be updated accordingly. True. Similarly, when a procedure is modified, all call sites must be updated -- note that there is deliberate analogue between tuples and parameter lists in my proposal. - use for multivalues return values which can make the code more readable (instead of using records or out parameters) This IMO makes sense only when such tuples are passed along many times, before references to their elements occur. Otherwise full tuple decomposition is required when e.g. only a succ/fail indicator in the result tuple has to be examined. Not necessarily. There are, as you know, two basic styles of error handling: exceptions and error codes. Most of Pascal code is based on exceptions, but there are cases, for example embedded programming, server/service programming, where using error codes is advantageous. In that case, using (result, error) tuple as a standard return value is a good convention. There are languages (Go is a most modern example), where this convention is used as a primary method across all standard library. - use as result value for iterators (this way e.g. key and data of containers can be queried) This reminds me of SQL SELECT [fieldlist], where *specified* record fields are copied. That is correct analogy -- in some variants of relational theory, term tuple is used to mean database record. But I wonder how confusion can be eliminated in the order of the tuple elements. Will (k,v) or (v,k) be the right order for key and value? What are the proper types of key and value? If you want to find a substring in a string, do you write Pos(str, substr) or Pos(substr, str) ? To find out, use function signature (in the case of tuples, return value type fields). If all else fails, there is (maybe) documentation :) Note that in my version of tuples proposal tuples are decoupled from records without field names. SSE should be used with array types, where all elements *definitely* have the same type. Then one +
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, 27 Jan 2013, Alexander Klenin wrote: On Sun, Jan 27, 2013 at 4:43 AM, Sven Barth pascaldra...@googlemail.com wrote: Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. Heh, I have started to write similar in form, but different in substance proposal, but needed some sleep, and you have beaten me to it :) I want to quickly summarize the most important points of my proposal before writing it out in length: 1) In a form proposed by Sven (and, IIUC, implemented in Oxygen), tuples are not different enough from records (so perhaps a term like anonymous records is preferable, as well of re-using keyword record). I agree that anonymous records might be good, but I consider them a separate, and weaker, extension. 2) The most important differentiating features of my proposal are: 2.1) Tuples are always temporary and anonymous. You can not store a tuple, define tuple type, of variable of tuple type. So tuples are 100% static, compile-time feature -- no change to RTTI, variants etc. No. I think that tuples should be a full fledged type, not an anonymous one with all the restrictions that come from it. Pascal is declarative. So, you must declare a tuple when you want one. As for notation: Adding the () brackets to indicate a tuple adds to clarity, simply relying on the comma to indicate a tuple is not acceptable. Pascal IS a verbose language. If you want unreadable: go for Javascript. I consider Sven's proposal the one to go for. It is more in line with what Object Pascal stands for. The idea of a tuple is already a concession to avoid the for in index monstrosity. So let's not get carried away too much. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 27.01.2013 02:35, Hans-Peter Diettrich wrote: Sven Barth schrieb: * Description What are tuples? Tuples are an accumulation of values of different or same type where the order matters. Sounds familiar? They are in this regard similar to records, but it's only the order of an element that matters, not its name. So what does make them special? Unlike records you can only query or set all the elements of a tuple at once. They basically behave like multiple assignments. In effect they allow you to return e.g. a multivalued result value without resorting to the naming of record fields (you'll still need to declare a tuple type) or the need for out parameters. This in turn allows you to use them for example in for-in loops. The lack of element names results in bloated code and runtime overhead. See below. I don't see why it should result in bloated code and runtime overhead. * Declaration: [...] The usage of constructors and destructors also allows a realisation of group assignment: === code begin === var a, b, e: Integer; c, d: String; begin a := 42; c := 'Hello World'; (b, d) := (a, c); a := 21; b := 84; (a, b) := (b, a); // the compiler needs to ensure the correct usage of temps here! What will happen here? At compile time a tuple type (integer; integer) has to be defined, and an instance must be allocated for it. Initialization and finalization information/code must be added if required. At runtime the arguments are copied into that tuple instance, then copied into the target variables. All copies may be subject to type conversions and reference counting. And here you are wrong. We have an assignment node with a tuple node on the left and a tuple node on the right. So the compiler can insert direct assignments between the corresponding elements on the left and right maybe with the need to insert a few temp vars to resolve cases like the above. And even then the optimizer can reduce the amount of temps. So the amount of temps is normally less or equal to the count of elements, but often it should be less than the count of elements. If a tuple node is only on one side of the assignment and the other one is a load node for a tuple variable then construction/deconstruction (depending on the side) will take place. Consider memory usage and runtime when tuples are nested, or contain large data structures (records, static arrays...). You'll have similar memory usage and runtime problems when you don't use tuples... a := 42; (a, e) := (a * 2, a); // (a, e) should be (84, 42), not (84, 84) Such code tends to become cryptic with larger tuples. High level (source code) debugging will be impossible :-( You can also write cryptic code without tuples. Also why should debugging become impossible? It's just a matter of adding the correct debug information. [...] * Possible extensions Note: This section is not completely thought through! An possible extension would be to allow the assignment of tuples to records and/or arrays (and vice versa). [...] Without references to distinct tuple elements the coder has to provide local variables for *all* tuple elements, then decompose the *entire* tuple, before access to a single element will be possible. This may be accomplished with less source code when a tuple can be assigned to a record variable, but then it would be simpler to use records *instead* of tuples. There is always Michael's idea of single element access (which can be extended by allowing ranges)... When a record type is modified, during development, all *compatible* tuples and tuple types must be updated accordingly. If you modify code it's likely that you need to modify other parts anyway... * Possible uses - use for group assignments which can make the code more readable ... or unreadable (see above). - use for multivalues return values which can make the code more readable (instead of using records or out parameters) This IMO makes sense only when such tuples are passed along many times, before references to their elements occur. Otherwise full tuple decomposition is required when e.g. only a succ/fail indicator in the result tuple has to be examined. - use as result value for iterators (this way e.g. key and data of containers can be queried) This reminds me of SQL SELECT [fieldlist], where *specified* record fields are copied. But I wonder how confusion can be eliminated in the order of the tuple elements. Will (k,v) or (v,k) be the right order for key and value? What are the proper types of key and value? The order of key and value will depend on the corresponding implementation. You need to look this up like you need to look up other things as well. By implementing builtin enumerators and those of the FCL consistently we might be able to provide a guide for other developers... And the types of key and value depend on what your key and your value is. You have the same problem currently as well
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, Jan 27, 2013 at 10:10 PM, Michael Van Canneyt mich...@freepascal.org wrote: 2.1) Tuples are always temporary and anonymous. You can not store a tuple, define tuple type, of variable of tuple type. So tuples are 100% static, compile-time feature -- no change to RTTI, variants etc. No. I think that tuples should be a full fledged type, not an anonymous one with all the restrictions that come from it. Let me restate: 1) Tuple as a type does nothing new compared to a record, except for possibility to omit field names. 2) While I agree that omitting field names might be a useful shortcut, it is wasteful to introduce a whole new keyword and syntax just for that -- I propose to just extend record syntax, possible variants: type TKeyValue = record (Integer, String) end; type TKeyValue = record of Integer, String end; type TKeyValue = record Integer; String end; type TKeyValue = (Integer; String); 3) The main part of the feature, IMHO, is a new tools for record and array manipulation -- construction and deconstruction of tuples. So in my proposal, tuple is not a type, but a concept underlying a syntax construct -- similar to, for example, a sequence of statements, or a parameter list. Pascal is declarative. No, it is not. http://www.britannica.com/EBchecked/topic/417798/declarative-language http://en.wikipedia.org/wiki/Declarative_programming I think you meant that in Pascal identifiers must be declared before usage -- that is true, and of course tuples proposal agrees with that. So, you must declare a tuple when you want one. Consider the most basic example: a, b := b, a; What do you propose to declare here? As for notation: Adding the () brackets to indicate a tuple adds to clarity, simply relying on the comma to indicate a tuple is not acceptable. Pascal IS a verbose language. If you want unreadable: go for Javascript. Verbosity in Pascal usually comes from using more keywords, not more punctuation. Using comma only would simplify grammar (and possibly parsing, although I am not sure of that -- FPC parser is not easy to understand). Consider, again: for k, v in a do vs for (k, v) in a do a, b := b, a; vs (a, b) := (b, a); DrawLine(Tuple(ARect), AColor); vs DrawLine((Tuple(ARect), AColor)); Why do you think second examples are more clear then first ones? Of course, if the expression becomes complex, programmes may add brackets -- as is already the case with other expressions. OTOH, this is the point I am willing to concede -- the difference is rather small. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, 27 Jan 2013, Alexander Klenin wrote: On Sun, Jan 27, 2013 at 10:10 PM, Michael Van Canneyt mich...@freepascal.org wrote: 2.1) Tuples are always temporary and anonymous. You can not store a tuple, define tuple type, of variable of tuple type. So tuples are 100% static, compile-time feature -- no change to RTTI, variants etc. No. I think that tuples should be a full fledged type, not an anonymous one with all the restrictions that come from it. Let me restate: 1) Tuple as a type does nothing new compared to a record, except for possibility to omit field names. That's all we need. 2) While I agree that omitting field names might be a useful shortcut, it is wasteful to introduce a whole new keyword and syntax just for that -- I propose to just extend record syntax, possible variants: type TKeyValue = record (Integer, String) end; type TKeyValue = record of Integer, String end; type TKeyValue = record Integer; String end; type TKeyValue = (Integer; String); 3) The main part of the feature, IMHO, is a new tools for record and array manipulation -- construction and deconstruction of tuples. So in my proposal, tuple is not a type, but a concept underlying a syntax construct -- similar to, for example, a sequence of statements, or a parameter list. That is exactly what I want to avoid; messing with syntax. I think that Sven (or Oxygen, they apparenly have it too) has more succeeded in preserving the essence of Pascal than your proposal does. Sven's proposal is the least invasive in terms of concepts and whatnot. It is simply a new type, and besides solving your original problem, it has additional advantages: I see Python has it too, so it gives you ammunition in that discussion too. I do not wish to reuse the record keyword, because the record syntax is already messy as it is with the variant parts. The TKeyValue = (Integer; String); is too reminiscent of an enumerated. The only thing that differentiates it is the use of type names. At the level of a parser, you have no way to decide what you are parsing without knowing what the symbols are. Pascal is declarative. No, it is not. http://www.britannica.com/EBchecked/topic/417798/declarative-language http://en.wikipedia.org/wiki/Declarative_programming I think you meant that in Pascal identifiers must be declared before usage -- that is true, and of course tuples proposal agrees with that. My apologies for the mixup in terminology, the latter is what I meant. But the latter is why I think Sven's proposal (or the Oxygen implementation) is more appropriate than yours: - No messing with syntax, just a new type. - Ability to declare a named type (not anonymous). Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, 27 Jan 2013, Paul Ishenin wrote: 27.01.13, 1:43, Sven Barth wrote: Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. I think it is big overkill to implement a new base type for such a small task as returning a key in for-in loop. And (for Michael) I don't see any beauty in this. Imo, initial index extension is much more beauty than suggested here (a,b,c) := d; constructions. Well, there we obviously differ in opinion. To be clear: I am not a proponent of tuples. I can live without it. But the for in index solves exactly 1 problem, and a very very very small one at that, (in fact, I don't even think it is a problem) which can be solved in many different ways as well. A tuple at least has the potential to solve more than one problem. Oxygene and python have tuples. Maybe other languages too; I don't know. So, if this very very very small maybe even non-existent problem must be soleved, I prefer to do it with a tuple. But hey, if you don't like tuples, and I don't like index: We'll do without tuples and index. I'll be perfectly happy. Many others undoubtedly too. Till now I didn't hear you complain about the absence of index, so... Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26 Jan 2013, at 21:45, Alexander Klenin wrote: 2.2.2) Any record or array type may be converted to a tuple of its elements using either assignment or Tuple intrinsic. For example: Tuple(ARectangle) is a tuple of 4 elements; x, y := APoint; // same as x := APoint.x; y := APoint.y; [snip] 2.3.2) When tuple appears inside of a function/procedure argument, it is deconstructed, and its elements are passed as a separate arguments. Tuple elements corresponding to var, out and constref parameters must be lvalues. Note that due to (2.2.2) tuple may represent only part of arguments. Together with (2.2) we note that normal semantics of procedure parameters is left unchanged :) We also gain this: procedure SomeLibrary.DrawLine(X1, Y1, X2, Y2, Color: Integer); // Author did forgot/did not want to declare overload with TRect parameter. ... DrawLine(Tuple(ClientRect), clRed); // No need, tuples help here I don't like these automatic conversions/deconstructions of records at all, nor the ability to have the compiler automatically convert a tuple to its component elements when resolving function calls. It means that you no longer have a tuple type, but rather a deconstruct_into_component_types() type conversion operator along with anonymous records. The fact that the tuple() operator is required when deconstructing a record when calling a function (as in 2.3.2) while it is not when assigning a record to multiple values (as in 2.2.2) shows that such automatic conversions are not a good idea. Implicitly applying it in one case and not in another is not good, and I'm definitely against automatically converting records into its component elements for passing as parameters. A tuple should either be a real type with fixed type conversion semantics that behave the same in every situation (like other types, and like how Pascal usually works: context-insensitive evaluation of expressions), or not exist at all (and this option is certainly fine with me as well). And another option is indeed extending the syntax of the for-statement, although there of course also downsides to do doing that. However, new magic operators that have their own rules are what really complicates a language, both in the compiler implementation and for people that have to use it. Jonas___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 1:26 AM, Paul Ishenin paul.ishe...@gmail.com wrote: 27.01.13, 1:43, Sven Barth wrote: Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. I think it is big overkill to implement a new base type for such a small task as returning a key in for-in loop. Of course. But note that in this thread, many more uses of tuples (which I do NOT want to make a type -- see my previous mail for lengthy explanation why). Some of the uses are: record and array constructors, adaptation of inconvenient signatures, better support for return code style of error handling, etc. And (for Michael) I don't see any beauty in this. Imo, initial index extension is much more beauty than suggested here (a,b,c) := d; constructions. I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do this syntax is forward-compatible with both tuples proposals, is simple to do (basically, already done -- only a small change in parsing is required) and will give immediate benefit regardless of outcome of larger discussion. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 27/01/2013 14:42, Alexander Klenin wrote: On Mon, Jan 28, 2013 at 1:26 AM, Paul Ishenin paul.ishe...@gmail.com wrote: 27.01.13, 1:43, Sven Barth wrote: Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. I think it is big overkill to implement a new base type for such a small task as returning a key in for-in loop. Of course. But note that in this thread, many more uses of tuples (which I do NOT want to make a type -- see my previous mail for lengthy explanation why). Some of the uses are: record and array constructors, adaptation of inconvenient signatures, better support for return code style of error handling, etc. If I understand this correct, the ability to return more than one value from a function (without out parm) is identical to using a record. Except you do not want a type declaration for a record. Therefore in this case tuple becomes an inline (lack of better word) declared record (match like you can declare an array outside a type section) And since it has no named type, it is (other tan records) assignment compatible if it has the same declaration (same as 2 array of integer, only array can not hold different types) So really here you would need an assignment compatible record (I do not say it is a good thing, but if the multi return case is addressed, it may be a better way than toupe) type TFoo1 = compatible record a: integer; b: string end; TFoo2 = compatible record a: integer; b: string end; function Bar: compatible record a: integer; b: string end; and variables/results of any of these are assignment compatible. (compatible record can be restricted to none variant records) And (for Michael) I don't see any beauty in this. Imo, initial index extension is much more beauty than suggested here (a,b,c) := d; constructions. I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do can be solved with records too? The typeof(a) needs to declare the key values anyway (provide an iterator, or something) So together with that, a named record (normal record as exists today) can be defined? Or am I missing something? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 1:38 AM, Jonas Maebe jonas.ma...@elis.ugent.be wrote: you no longer have a tuple type, but rather a deconstruct_into_component_types() type conversion operator along with anonymous records. Yes, this is quite close to what I wanted to propose. I am glad someone has understood me :) Please see arguments for this (as opposed to just a tuple type) in my previous emails. The fact that the tuple() operator is required when deconstructing a record when calling a function (as in 2.3.2) while it is not when assigning a record to multiple values (as in 2.2.2) shows that such automatic conversions are not a good idea. Yes, automatic conversions from records is indeed a weak point in my proposal. It may be dropped, but at a cost of bulkier syntax: handle, error := Tuple(OpenFile('name')); vs handle, error := OpenFile('name'); I am not sure whether to prefer better consistency of better readability. Perhaps Tuple could be made a keyword instead of intrinsic, and thus allowed to omit brackets: handle, error := tuple OpenFile('name'); rectangle := tuple point1, tuple point2; Alternatively, some kind of tuple operator may be introduced (yes, I know, everyone is against punctuation -- consider it just a brainstorming attempt): handle, error := @@OpenFile('name'); // double-@ is currently useless handle, error := ,OpenFile('name'); // crazy :) handle, error := ~OpenFile('name'); // random unused character Implicitly applying it in one case and not in another is not good, and I'm definitely against automatically converting records into its component elements for passing as parameters. Of course, since it would make it impossible to pass records as parameters :) Tuple keyword/intrinsic is definitely unavoidable in this case. However, new magic operators that have their own rules are what really complicates a language, both in the compiler implementation and for people that have to use it. Note that my proposal actually reduces the number of magic operators, since it unifies the meaning of comma-in-parameter-list, comma-in-open-array and comma-in-array-index to be the same comma-in-tuple. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 2:01 AM, Martin laza...@mfriebe.de wrote: Of course. But note that in this thread, many more uses of tuples (which I do NOT want to make a type -- see my previous mail for lengthy explanation why). Some of the uses are: record and array constructors, adaptation of inconvenient signatures, better support for return code style of error handling, etc. If I understand this correct, the ability to return more than one value from a function (without out parm) is identical to using a record. Except you do not want a type declaration for a record. Actually, I have nothing against type declaration of record. What I want to relax is the restriction that the *caller* must use a record to receive the value too -- I want to allow assigning result directly to a list of variables. Therefore in this case tuple becomes an inline (lack of better word) declared record (match like you can declare an array outside a type section) Yes, this is exactly why I am against introducing tuples as a new data type -- inline (I prefer term anonymous) records are good enough. And since it has no named type, it is (other tan records) assignment compatible if it has the same declaration (same as 2 array of integer, only array can not hold different types) So really here you would need an assignment compatible record (I do not say it is a good thing, but if the multi return case is addressed, it may be a better way than toupe) type TFoo1 = compatible record a: integer; b: string end; TFoo2 = compatible record a: integer; b: string end; function Bar: compatible record a: integer; b: string end; and variables/results of any of these are assignment compatible. (compatible record can be restricted to none variant records) I do not think compatible records are good enough, because with named records, the same effect can be achieved simply by type conversion: x := TFoo1(Bar); What I want is: var a: Integer; b: String; c: TIntegerDynArray; x: TFoo1; a, b := Bar; c[0], b := Bar; c[i], c[j] := c[j], c[i]; x := Bar; // This will not work with anonymous record x := TFoo1(a, b); a, b := x; etc. Note that, except for the commented line, it does not matter whether Bar is declared as function Bar: TFoo1; or function Bar: record a: integer; b: string end; I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do can be solved with records too? The typeof(a) needs to declare the key values anyway (provide an iterator, or something) So together with that, a named record (normal record as exists today) can be defined? Or am I missing something? You got it right. More detailed, I suggest to extend Enumerable interface with optional property CurrentWithKey: TValueKey where TValueKey must be a record of two (or perhaps even more) fields. for k, v in a do will call CurrentWithKey for each item, assign first field to k, second -- to v. When/if tuples will be introduced, no change will be needed here. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, 28 Jan 2013, Alexander Klenin wrote: On Mon, Jan 28, 2013 at 1:26 AM, Paul Ishenin paul.ishe...@gmail.com wrote: 27.01.13, 1:43, Sven Barth wrote: Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. I think it is big overkill to implement a new base type for such a small task as returning a key in for-in loop. Of course. But note that in this thread, many more uses of tuples (which I do NOT want to make a type -- see my previous mail for lengthy explanation why). Some of the uses are: record and array constructors, adaptation of inconvenient signatures, better support for return code style of error handling, etc. And (for Michael) I don't see any beauty in this. Imo, initial index extension is much more beauty than suggested here (a,b,c) := d; constructions. I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do this syntax is forward-compatible with both tuples proposals, is simple to do (basically, already done -- only a small change in parsing is required) what concerns syntax, I have no problem with this. What bothers me immensely is the same what bothered me in the totally braindead Delphi implementation of the for in loop : the bunch of requirements you put on the iterator implementation: an interface with special status. You can't get more stupid and ugly than that. I would gladly kill the borland/inprise/embarcadero engineer who thought of this, after torturing him for 3 days, just for unleashing this monstrosity on the world... [Disclaimer: the above is humor. Just trying to show how bad I think it is] Your initial proposal makes it even worse by adding more conditions to the interface, it would not even be an interface any more. So: No, no, no. It is ugly beyond words. That is why I think you need a proper tuple value to solve this. it gives a more fundamental solution: the loop variable type equals the type returned by the iterator/enumerator. No messing with index (bad syntax) and even worse: special 'interfaces' and whatnot. Pascal is a strongly typed language. So, if we absolutely must solve this: introduce a proper type. A tuple fits the job. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 2:59 AM, Michael Van Canneyt mich...@freepascal.org wrote: On Mon, 28 Jan 2013, Alexander Klenin wrote: I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do this syntax is forward-compatible with both tuples proposals, is simple to do (basically, already done -- only a small change in parsing is required) what concerns syntax, I have no problem with this. What bothers me immensely is the same what bothered me in the totally braindead Delphi implementation of the for in loop : the bunch of requirements you put on the iterator implementation: an interface with special status. You can't get more stupid and ugly than that. Out of curiosity -- how would you implement it? (Except the Oberon way -- by telling the programmer that he is better off without this feature :-)) I have no particular like or dislike for the Delphi's enumerable implementation, but it is quite similar to for-in iterators in most other compiled languages. Your initial proposal makes it even worse by adding more conditions to the interface, it would not even be an interface any more. I am not sure what are you talking about. Interface is a list of methods. My for-in proposal would add a new interface (with a single method) which, if supported by enumerator, would allow user to write for-in-index loops. That is why I think you need a proper tuple value to solve this. it gives a more fundamental solution: the loop variable type equals the type returned by the iterator/enumerator. No messing with index (bad syntax) and even worse: special 'interfaces' and whatnot. I agree that index keyword was perhaps not optimal choice. New interface is needed anyway to preserve backwards compatibility (and efficiency for the case when the key is not needed). Do not slow down existing code. Pascal is a strongly typed language. So, if we absolutely must solve this: introduce a proper type. A tuple fits the job. So does the record -- tuple is needed here only to deconstruct that record in separate variables. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, 28 Jan 2013, Alexander Klenin wrote: On Mon, Jan 28, 2013 at 2:59 AM, Michael Van Canneyt mich...@freepascal.org wrote: On Mon, 28 Jan 2013, Alexander Klenin wrote: I have a compromise suggestion: Implement for-index extension with the syntax: for (k, v) in a do this syntax is forward-compatible with both tuples proposals, is simple to do (basically, already done -- only a small change in parsing is required) what concerns syntax, I have no problem with this. What bothers me immensely is the same what bothered me in the totally braindead Delphi implementation of the for in loop : the bunch of requirements you put on the iterator implementation: an interface with special status. You can't get more stupid and ugly than that. Out of curiosity -- how would you implement it? Define an iterator type/operator. - No interface - No 'specially named function' in the class. The iterator should be separate from the class. Now they promoted 1 function with a special name to a special status: 'GetEnumerator' (I know this is how Python and so did it, but I'm not particularly fond of that either). (Except the Oberon way -- by telling the programmer that he is better off without this feature :-)) I am still not convinced that language support for iterators are needed. You may be bothered by the various loop methods in the rtl/fcl. But I am not in the least bothered by it. I have no particular like or dislike for the Delphi's enumerable implementation, but it is quite similar to for-in iterators in most other compiled languages. Well, I do not like to give special status to certain functions or interfaces. All identifiers should be equal for the law :-) I was horribly disappointed when they introduced that. Your initial proposal makes it even worse by adding more conditions to the interface, it would not even be an interface any more. I am not sure what are you talking about. Interface is a list of methods. My for-in proposal would add a new interface (with a single method) which, if supported by enumerator, would allow user to write for-in-index loops. I know. I just do not like the approach. Probably because I don't particularly like interfaces themselves. That is why I think you need a proper tuple value to solve this. it gives a more fundamental solution: the loop variable type equals the type returned by the iterator/enumerator. No messing with index (bad syntax) and even worse: special 'interfaces' and whatnot. I agree that index keyword was perhaps not optimal choice. Quick, we should call the newspaper, we agree on something ;-) New interface is needed anyway to preserve backwards compatibility (and efficiency for the case when the key is not needed). Do not slow down existing code. Yes. Pascal is a strongly typed language. So, if we absolutely must solve this: introduce a proper type. A tuple fits the job. So does the record -- tuple is needed here only to deconstruct that record in separate variables. True. Which begs the question why you didn't use a record to begin with. I still do not see why the enumerator could not simply return a record record key : tkey; value : tactualtype end; for r in myclass do begin Writeln(r.key); With r.value do end. to recapitulate: The construction with interface/index is really very ugly in my opinion, and I would very much regret it if it became part of Object Pascal. I can understand the need to have simpler variables. So a tuple and/or a record deconstructor comes in naturally. I think a tuple as a type construct may have value in itself. and as such would prefer to see it as a 'first class citizen' of Object Pascal, just as it is in e.g. Python, and to a lesser degree, other languages. The exact details are for me less important. A small word: Like most people here I think Pascal is an elegant language, easy to read and whatnot. It was meant/designed as such, and Wirth did a good job. I am very passionate about that, I'm sure you noticed. I may use exuberant language, and probably bad humor, in my efforts to defend it. Despite that, please do not make the mistake of thinking that I would stop features just because I do not like them. That said, I will zealously defend possible alternatives that I think add to the elegance and readability of Pascal. (as witnessed by the discussions this weekend...) Borland did a world of good for (Object) Pascal, up to Delphi 7. After that, it went seriously downhill in my opinion; Adding randomly features without clear direction or regard for the intent and philosophy of the Pascal language - or so it seems to me. Like a ship at the mercy of the waves... I would be very sorry to see that happening to Free Pascal. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Preface: In the following I assume that tuples can be implemented by records. The proposed syntax extensions can be applied to records as well, they are not restricted to a new type. Alexander Klenin schrieb: On Sun, Jan 27, 2013 at 12:35 PM, Hans-Peter Diettrich drdiettri...@aol.com wrote: (a, b) := (b, a); // the compiler needs to ensure the correct usage of temps here! What will happen here? At compile time a tuple type (integer; integer) has to be defined, and an instance must be allocated for it. Initialization and finalization information/code must be added if required. At runtime the arguments are copied into that tuple instance, then copied into the target variables. All copies may be subject to type conversions and reference counting. Consider memory usage and runtime when tuples are nested, or contain large data structures (records, static arrays...). Any time large data structures are used as values (as opposed to references), the incur memory and run-time overhead -- parameter passing, assignment, etc. Tuples are neither better not worse in this aspect. My point is the artificial overhead, introduced in above example. The code may *look* elegant, but in fact is a resource hog. Also note that in my version of proposal, nested tuples are impossible. I consider this an inacceptable restriction. Records can contain other records. a := 42; (a, e) := (a * 2, a); // (a, e) should be (84, 42), not (84, 84) Such code tends to become cryptic with larger tuples. High level (source code) debugging will be impossible :-( Why do you think so? I think adding tuples as watchable item to debugger is rather straight forward, although a bit redundand. Watching tuples (records) is not enough for debugging such complex assignments. Actually, even totally independently from tuples, allowing to enter several comma-separated values in evaluate/modify window to be displayed at once would be a useful feature. Indeed it would be nice to have more specialized watches for e.g. records or classes. When e.g. a class (TWinControl...) contains records or lists, these elements may hide following and more interesting members of derived classes in the output. * Possible extensions Note: This section is not completely thought through! An possible extension would be to allow the assignment of tuples to records and/or arrays (and vice versa). [...] Without references to distinct tuple elements the coder has to provide local variables for *all* tuple elements, then decompose the *entire* tuple, before access to a single element will be possible. This may be accomplished with less source code when a tuple can be assigned to a record variable, but then it would be simpler to use records *instead* of tuples. This is why I think tuples as a data type are not needed. Instead, I suggest them as a powerful way to manipulate records, arrays, and parameter lists using one relatively simple concept. I doubt that a concept alone will help. I see the proposed extensions as an attempt to introduce elements from *functional programming* languages, for which OPL lacks many prerequisites. Also, note nil as lvalue paragraph of my proposal, which allows to deconstruct only part of tuple, ignoring the rest. Just another syntax for accessing record members. BTW, I just remembered another tuple usage example: type T3DMatrix = array of array of array of Double; TMatrixPos = array [1..3] of Double; procedure P(A: T3DMatrix; APos1: TMatrixPos); begin A[Tuple(APos1)] := 1.0; // Instead of A[APos[1], APos[2], APos[3]] end; I'd accept a TMatrixPos as an array of Integer, but not of Double. What result do you expect from an index array of (-5.2, 3.7, 9.5)? Pascal requires explicit rounding (round, trunc, floor...) of real values to integers, for good reason. Tuple deconstructors can use only one of these functions for *every* tuple, so that the choice may be good for one use, but inappropriate in other situations, regardless of the choosen method. Why do you expect any difference between A[Tuple(APos1)] := 1.0; and A[APos1] := 1.0; ? The compiler will have to create the same code for both notations, or use the same RTL subroutine for doing the job. When a record type is modified, during development, all *compatible* tuples and tuple types must be updated accordingly. True. This was my point. Similarly, when a procedure is modified, all call sites must be updated -- note that there is deliberate analogue between tuples and parameter lists in my proposal. That's something very different, IMO. I frequently miss the lack of subroutine argument templates, when e.g. implementing event handlers. Currently it's impossible to declare a method like procedure OnClick(TNotifyEvent); or handler OnClick: TNotifyEvent; with the compiler creating the right method signature (of TNotifyEvent), or of some much more complex event handler type. But subroutine signatures
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Sven Barth schrieb: The lack of element names results in bloated code and runtime overhead. See below. I don't see why it should result in bloated code and runtime overhead. --- See below ;-) (a, b) := (b, a); // the compiler needs to ensure the correct usage of temps here! What will happen here? At compile time a tuple type (integer; integer) has to be defined, and an instance must be allocated for it. Initialization and finalization information/code must be added if required. At runtime the arguments are copied into that tuple instance, then copied into the target variables. All copies may be subject to type conversions and reference counting. And here you are wrong. We have an assignment node with a tuple node on the left and a tuple node on the right. So the compiler can insert direct assignments between the corresponding elements on the left and right maybe with the need to insert a few temp vars to resolve cases like the above. Are you sure that the compiler will detect all (possible) side effects, so that an optimization is always *safe*? Finally somebody (you?) has to implement all the new features, and stand for its correctness. a := 42; (a, e) := (a * 2, a); // (a, e) should be (84, 42), not (84, 84) Such code tends to become cryptic with larger tuples. High level (source code) debugging will be impossible :-( You can also write cryptic code without tuples. Also why should debugging become impossible? It's just a matter of adding the correct debug information. With explicit assignments you can check every single statement, eventually step into embedded functions. A tuple assignment is a single statement, no chance to find out what happens in detail. DoDi ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 4:19 AM, Michael Van Canneyt mich...@freepascal.org wrote: Define an iterator type/operator. - No interface - No 'specially named function' in the class. The iterator should be separate from the class. Now they promoted 1 function with a special name to a special status: 'GetEnumerator' Ah, you mean that FPC's operator Enumerator is better? I agree, but the difference is not too great. All identifiers should be equal for the law :-) I know only two languages with such extreme disdain for reserved words: Forth and, to a lesser extent, Lisp. For example, in Forth, a comment (!) is not a built-in construct, but a word (Forth's analog of procedure) defined in standard library. Which begs the question why you didn't use a record to begin with. I still do not see why the enumerator could not simply return a record record key : tkey; value : tactualtype end; for r in myclass do begin Writeln(r.key); With r.value do end. the point of my tuples proposal is to do exactly that, with only a single change -- allow to *also* write loop as for key, value in myclass do begin Writeln(key); with value do end; while keeping enumerator the same. Borland did a world of good for (Object) Pascal, up to Delphi 7. After that, it went seriously downhill in my opinion; Adding randomly features without clear direction or regard for the intent and philosophy of the Pascal language - or so it seems to me. Like a ship at the mercy of the waves... I would rephrase slightly -- the features they added are, in principle, good ones. However, they hastily (and randomly?) copied them from other languages without a proper adaptation. Take, for example, recently added to FPC array constructors: TIntegerDynArray.Create(1, 2, 3) is much too noisy, and inconsistent with other syntax (it resembles a standard constructor, but takes variable-length argument list, which is impossible for standard constructors). So I would much prefer TIntegerDynArray(1, 2, 3), TIntegerDynArray([1, 2, 3]), or maybe even just [1, 2, 3] if appropriate automatic conversions are defined. -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, 28 Jan 2013, Alexander Klenin wrote: On Mon, Jan 28, 2013 at 4:19 AM, Michael Van Canneyt mich...@freepascal.org wrote: Define an iterator type/operator. - No interface - No 'specially named function' in the class. The iterator should be separate from the class. Now they promoted 1 function with a special name to a special status: 'GetEnumerator' Ah, you mean that FPC's operator Enumerator is better? I agree, but the difference is not too great. It never is. It is all in details. All identifiers should be equal for the law :-) I know only two languages with such extreme disdain for reserved words: Forth and, to a lesser extent, Lisp. For example, in Forth, a comment (!) is not a built-in construct, but a word (Forth's analog of procedure) defined in standard library. Which begs the question why you didn't use a record to begin with. I still do not see why the enumerator could not simply return a record record key : tkey; value : tactualtype end; for r in myclass do begin Writeln(r.key); With r.value do end. the point of my tuples proposal is to do exactly that, with only a single change -- allow to *also* write loop as for key, value in myclass do begin Writeln(key); with value do end; while keeping enumerator the same. regarding syntax, we agree. Borland did a world of good for (Object) Pascal, up to Delphi 7. After that, it went seriously downhill in my opinion; Adding randomly features without clear direction or regard for the intent and philosophy of the Pascal language - or so it seems to me. Like a ship at the mercy of the waves... I would rephrase slightly -- the features they added are, in principle, good ones. However, they hastily (and randomly?) copied them from other languages without a proper adaptation. Yes. That is what I meant. I have no objections to the features themselves. Just the way the were introduced, is, to my taste, totally disregarding Pascal philosophy. And I regret that heavily. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Mon, Jan 28, 2013 at 4:46 AM, Hans-Peter Diettrich drdiettri...@aol.com wrote: Preface: In the following I assume that tuples can be implemented by records. The proposed syntax extensions can be applied to records as well, they are not restricted to a new type. Ok, with a few caveats listed below. Any time large data structures are used as values (as opposed to references), the incur memory and run-time overhead -- parameter passing, assignment, etc. Tuples are neither better not worse in this aspect. My point is the artificial overhead, introduced in above example. The code may *look* elegant, but in fact is a resource hog. The only artificial overhead is using two temporary variables instead of one. As I have demonstrated in previous messages, this overhead can, in principle, be removed by optimizer. Also note that in my version of proposal, nested tuples are impossible. I consider this an inacceptable restriction. Records can contain other records. Yes, but tuples are just a syntax for constructing/deconstructing records, not records themsleves. They can be converted to a specific record type by casting. Consider these examples: var x, y, z: Integer; pt: TPoint; ... (x, y) // record a, b: Integer; end; (x, (y))// record a, b: Integer; end; (x, (y, z))// record a, b: Integer; end; (x, TPoint(y, z)) // record a: Integer; b: TPoint; end; (TPoint(x, y), TPoint(y, z)) // record a, b: TPoint; end; (TPoint(x, y), pt) // record a, b: TPoint; end; (TPoint(x, y), Tuple(pt)) // record a: TPoint; b, c: Integer; end; * Possible extensions This is why I think tuples as a data type are not needed. Instead, I suggest them as a powerful way to manipulate records, arrays, and parameter lists using one relatively simple concept. I doubt that a concept alone will help. I see the proposed extensions as an attempt to introduce elements from *functional programming* languages, for which OPL lacks many prerequisites. True, functional programming is certainly the lergest modern paradigm still lacking from FPC. As for prerequisites, there are mostly closures/anonymous methods, which are discussed in a parallel thread, and perhaps purity annotation, which may be helpful, but is optional. After that, FPC will support FP as well as previous paradigms: OOP, procedural, and structured programming. Also, note nil as lvalue paragraph of my proposal, which allows to deconstruct only part of tuple, ignoring the rest. Just another syntax for accessing record members. Yes, but a useful one in the context of a proposal. Note yet another example of my proposal I have not yet provided: Since procedure arguments are considered tuples, nil could also be used in plase of out paragemets which are not needed by caller, e.g.: instead of var dummy: Integer; ... Val(s, i, dummy); it would be possible to write just Val(s, i, nil); BTW, I just remembered another tuple usage example: type T3DMatrix = array of array of array of Double; TMatrixPos = array [1..3] of Double; procedure P(A: T3DMatrix; APos1: TMatrixPos); begin A[Tuple(APos1)] := 1.0; // Instead of A[APos[1], APos[2], APos[3]] end; I'd accept a TMatrixPos as an array of Integer, That was just my mistake, of course i meant aray of Integer, sorry. Why do you expect any difference between A[Tuple(APos1)] := 1.0; and A[APos1] := 1.0; ? The compiler will have to create the same code for both notations, or use the same RTL subroutine for doing the job. The idea is that second case will require a manually-written operator[], while the first one will work automatically. So, again, just a syntax sugar -- but useful one. Similarly, when a procedure is modified, all call sites must be updated -- note that there is deliberate analogue between tuples and parameter lists in my proposal. That's something very different, IMO. I frequently miss the lack of subroutine argument templates, when e.g. implementing event handlers. Currently it's impossible to declare a method like procedure OnClick(TNotifyEvent); or handler OnClick: TNotifyEvent; with the compiler creating the right method signature (of TNotifyEvent), or of some much more complex event handler type. You may be interested to know that i have just proposed exacty such an extension in a parallel thread discussing anonyomous procedures. Currently proposed syntax is: OnClick := lambda TNotifyEvent begin end; But subroutine signatures are *declarative* elements with their own syntax, different from record or tuple declarations. Would you really extend the tuple declaration syntax, so that it could be used like e.g. type MyTuple: (var Integer; array Of Char; const String default ''); That has certainly crosed my mind, but I decided to go one step at a time. There is certainly much to discuss even with the current proposal. Nevertheless, I did propose to use tuples in position
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 27.01.2013 20:16, Alexander Klenin wrote: Borland did a world of good for (Object) Pascal, up to Delphi 7. After that, it went seriously downhill in my opinion; Adding randomly features without clear direction or regard for the intent and philosophy of the Pascal language - or so it seems to me. Like a ship at the mercy of the waves... I would rephrase slightly -- the features they added are, in principle, good ones. However, they hastily (and randomly?) copied them from other languages without a proper adaptation. Take, for example, recently added to FPC array constructors: TIntegerDynArray.Create(1, 2, 3) is much too noisy, and inconsistent with other syntax (it resembles a standard constructor, but takes variable-length argument list, which is impossible for standard constructors). So I would much prefer TIntegerDynArray(1, 2, 3), TIntegerDynArray([1, 2, 3]), or maybe even just [1, 2, 3] if appropriate automatic conversions are defined. Here we - again - agree. I would have also preferred the latter one (as this could be used for non named array types as well...). I already thought about simply implementing it... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] RFC: Support for new type tuple v0.1
Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. Regards, Sven The draft: * Description What are tuples? Tuples are an accumulation of values of different or same type where the order matters. Sounds familiar? They are in this regard similar to records, but it's only the order of an element that matters, not its name. So what does make them special? Unlike records you can only query or set all the elements of a tuple at once. They basically behave like multiple assignments. In effect they allow you to return e.g. a multivalued result value without resorting to the naming of record fields (you'll still need to declare a tuple type) or the need for out parameters. This in turn allows you to use them for example in for-in loops. * Declaration: The declaration of a tuple type is build up as follows (pseudo grammar): TUPLETYPE ::= [packed] tuple of (TUPLEELEMENTS) TUPLEELEMENTS ::= TYPENAME, TYPENAME [, TYPENAME]* This shows that a tuple must at least consist of two elements. While in theory a one element tuple would be possible the question is on the one hand why you'd use a tuple type at all and on the other hand this avoids potential problems for the compiler especially if the tuple type is used as the left side of an assignment (the compiler currently allows e.g. (Writeln('Foobar')) as a statement). Note: If single element tuples are desired they need to be made assignment compatible with corresponding scalar values. The memory layout of tuples is also similar to records in that the elements are aligned according to the current alignment settings. This alignment is not used if the packed modifier is used. Like sets tuples can be declared anonymously: === code begin === var t: tuple of (Integer, String); === code end === Tuples can not be declared as generic, but they can be declared inside generics with generic parameters as one or more element types. * Assignment compatibility: Two different tuples A and B are considered assignment compatible if and only if they contain the same number of elements and each element Ai is assignment compatible to Bi (please note that this might contain precision/data loss). E.g.: === code begin === var t1, t2: tuple of (Integer, Single, TObject, String); t3: tuple of (Byte, Double, TStrings, ShortString); t4: tuple of (Integer, Single); t5: tuple of (Single, Double, TObject, String); t6: tuple of (TObject, Integer, String, Single); begin t1 := t2; // ok t1 := t3; // ok (with precision loss in second element) t3 := t1; // not ok, because TObject is not a subclass of TStrings t1 := t4; // not ok, because the count of elements is not equal t5 := t1; // ok, element 1 will be converted to a Single t6 := t1; // not ok, order of elements is not equal end; === code end === * Usage: Tuples can be used by assigning either another compatible tuple (see above) to it or by constructing or deconstructing a tuple value. A constructor looks as follows: TUPLECONSTRUCTOR ::= (RVALUE, RVALUE [,RVALUE]*) While a deconstructor looks as follows: TUPLEDECONSTRUCTOR ::= (LVALUE, LVALUE, [,LVALUE]*) In both cases the amount of elements must be equal to the amount of elements the tuple is assigned to/from (and also the types must be compatible). Examples: === code begin === var t1: tuple of (Integer, String, Single); t2: tuple of (TObject, Integer); s: String; i: LongInt; d: Double; o: TObject; sl: TStringList; begin // constructors t1 := (42, 'Hello World', 3.14); t1 := (i, s, d); // with precision loss in third element upon assignment t2 := (TObject.Create, 42); t2 := (Nil, 0); t2 := (TStringList.Create, Random(42)); //t2 := (0, False); // not ok, because elements are not compatible //t2 := (Nil, 0, ''); // not ok, because the count is different // deconstrucors (i, s, d) := t1; //(42, s, d) := t1; // not valid, because 42 can not be assigned to! //(i, s) := t1; // not valid, because the count of elements differs (o, i) := t2; (o, sl.Capacity) := t2; // properties can be assigned to as well end; === code end === The usage of constructors and destructors also allows a realisation of group assignment: === code begin === var a, b, e: Integer; c, d: String; begin a := 42; c := 'Hello World'; (b, d) := (a, c); a := 21; b := 84; (a, b) := (b, a); // the compiler needs to ensure the correct
Re: [fpc-devel] RFC: Support for new type tuple v0.1
In our previous episode, Sven Barth said: up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. In a quick read, I cannot see any limitations to the type used for a tuple-element except that it behaves like file of... So that would mean a record type (or other non variant compatible type) would qualify? ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26.01.2013 18:52, Marco van de Voort wrote: In our previous episode, Sven Barth said: up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. In a quick read, I cannot see any limitations to the type used for a tuple-element except that it behaves like file of... So that would mean a record type (or other non variant compatible type) would qualify? Whether there should be restrictions of types could be added to the open issues as I'd want to have at least equality operators working for tuples and thus we need to think about something for records... (as a solution one could require that a = operator for records must be in scope) But without that problem in mind I had wanted to allow every type for tuple elements (even tuples). Out of curiosity: Do you see this positive or negative? Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
In our previous episode, Sven Barth said: In a quick read, I cannot see any limitations to the type used for a tuple-element except that it behaves like file of... So that would mean a record type (or other non variant compatible type) would qualify? Whether there should be restrictions of types could be added to the open issues as I'd want to have at least equality operators working for tuples and thus we need to think about something for records... (as a solution one could require that a = operator for records must be in scope) But without that problem in mind I had wanted to allow every type for tuple elements (even tuples). Out of curiosity: Do you see this positive or negative? To be frank, I'm not interested in the whole shebang. It reeks too much like first wanting an extension, and then thinking of one. But, like you, when it is being done, it should be done decent, and IMHO using array of variant (or tvarrec) as implementation vehicle is limiting the feature too much. Either good, or not. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26.01.2013 19:20, Marco van de Voort wrote: In our previous episode, Sven Barth said: In a quick read, I cannot see any limitations to the type used for a tuple-element except that it behaves like file of... So that would mean a record type (or other non variant compatible type) would qualify? Whether there should be restrictions of types could be added to the open issues as I'd want to have at least equality operators working for tuples and thus we need to think about something for records... (as a solution one could require that a = operator for records must be in scope) But without that problem in mind I had wanted to allow every type for tuple elements (even tuples). Out of curiosity: Do you see this positive or negative? To be frank, I'm not interested in the whole shebang. It reeks too much like first wanting an extension, and then thinking of one. But, like you, when it is being done, it should be done decent, and IMHO using array of variant (or tvarrec) as implementation vehicle is limiting the feature too much. Either good, or not. Ah, this is how you meant it. As I've written in the beginning of the draft I think of tuples more like a simplified record type (in terms of compiler implementation, etc). Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sat, 26 Jan 2013, Sven Barth wrote: Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. After a first read, looks OK. You seem to have thought of everything that needs to be described, except maybe extraction of a single element: b : tuple of (integer, integer); a : integer; begin b:=(1,2); a:=b[0]; // a = 1 after this. end; In this sense, it seems more like an array of const than as a record. I would not do the extensions. The tuple is simply a logical, immutable grouping of values. I would also not allow operators other than := and =, because in expressions, when encountering a (, it is not clear what is meant. Stick to what can be considered well-defined. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Sven Barth wrote: Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Nice, but I've got reservations about making tuples compatible with dynamic arrays (or at least, any more compatible than a dynamic array is with a normal array). I also note Alexander's earlier ZEROES: array [1..10] of Integer = (0, 0, ..., 0); ... (x, y, z) := Tuple(ZEROES); which I'm afraid I really don't like since that sort of thing is too easily misinterpreted as making the language indeterminate. I'd vote for having implicit compatibility between a single element and a tuple i.e. something like (x, y, z) := Tuple(0); provided that x, y and z are all the same type. Granted that the same effect can be had by overlaying the assignment operator but this would save having to use per-element assignment or an intermediate array. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26.01.2013 20:13, Mark Morgan Lloyd wrote: Sven Barth wrote: Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Nice, but I've got reservations about making tuples compatible with dynamic arrays (or at least, any more compatible than a dynamic array is with a normal array). Which is why I added it under extensions. I also note Alexander's earlier ZEROES: array [1..10] of Integer = (0, 0, ..., 0); ... (x, y, z) := Tuple(ZEROES); which I'm afraid I really don't like since that sort of thing is too easily misinterpreted as making the language indeterminate. Which is in turn why I required that the count of elements is the same... I'd vote for having implicit compatibility between a single element and a tuple i.e. something like (x, y, z) := Tuple(0); provided that x, y and z are all the same type. Granted that the same effect can be had by overlaying the assignment operator but this would save having to use per-element assignment or an intermediate array. I don't know... this is again the the right side is evaluated without knowing the left side problem. Thus it is not known what types Tuple(0) should return. (Note: this problem does not apply to group assignments as proposed, because if necessary every value could just be copied to the stack and then retrieved (of course the compiler will optimize here...) Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26.01.2013 20:14, Michael Van Canneyt wrote: On Sat, 26 Jan 2013, Sven Barth wrote: Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. After a first read, looks OK. You seem to have thought of everything that needs to be described, except maybe extraction of a single element: b : tuple of (integer, integer); a : integer; begin b:=(1,2); a:=b[0]; // a = 1 after this. end; In this sense, it seems more like an array of const than as a record. The question is whether we really need it. But if you think it's worthwhile then one can add it. But then we might also need support for Length and maybe also (just for the sake of completeness) Low and High. And then there's also the question whether to start at 0 or 1... I would not do the extensions. The tuple is simply a logical, immutable grouping of values. That's why I proposed them as extensions. I'm myself not very sure in allowing them or not, but I added them for Alexander's sake ;) I would also not allow operators other than := and =, because in expressions, when encountering a (, it is not clear what is meant. Here are two possiblities: * allow operator overloads only for named tuples, which would mean that only t3 := t1 + t2 would be supported * allow operator overloads also for anonymous tuples, which would mean that (like I wrote in open issues) (d1, d2, d3, d4) := (d1, d2, d3, d4) + (1.0, 2.0, 3.0, 4.0) would be supported The former is also the case for other types (e.g. sets, though there only a few operators (like **) can be overloaded), so this would be consistent... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On 26.01.2013 20:36, Sven Barth wrote: After a first read, looks OK. You seem to have thought of everything that needs to be described, except maybe extraction of a single element: b : tuple of (integer, integer); a : integer; begin b:=(1,2); a:=b[0]; // a = 1 after this. end; In this sense, it seems more like an array of const than as a record. And I just got the following idea: === example begin === var t1: tuple of (Integer, Integer, Integer, Integer); t2: tuple of (Integer, Integer); begin t1 := (4, 3, 2, 1); t2 := tl[2..3]; // with 1 based access t2 will be (3, 2); t1[3..4] := (5, 6); // t1 will now be (4, 3, 5, 6) end; === example end === Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Sven Barth wrote: I'd vote for having implicit compatibility between a single element and a tuple i.e. something like (x, y, z) := Tuple(0); provided that x, y and z are all the same type. Granted that the same effect can be had by overlaying the assignment operator but this would save having to use per-element assignment or an intermediate array. I don't know... this is again the the right side is evaluated without knowing the left side problem. Thus it is not known what types Tuple(0) should return. (Note: this problem does not apply to group assignments as proposed, because if necessary every value could just be copied to the stack and then retrieved (of course the compiler will optimize here...) In that case how about type TInteger2Tuple= tuple of (integer, integer); var i2: TInteger2Tuple; begin i2 := TIntegerTuple(0); for the very specific case where the tuple on the LHS is only allowed elements of a single type (or at the very least must be assignment-compatible with each other) and there is only a single element on the RHS. Since under normal circumstances a tuple contains more than one element, this couldn't be confused with a cast. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Michael Van Canneyt wrote: On Sat, 26 Jan 2013, Sven Barth wrote: Hello together! Based on the results of the for-in-index thread I've decided to come up with a draft for the Tuple type which is thought by many people to be a better alternative to for-in-index. Please note the following points: * This is not the final specification for Tuples and thus open to discussion (there are still some issues with this draft that need to be solved) * I won't implement this feature myself (at least not in the near future) as I have other topics on my list (most importantly generics once type helpers are commited), so Alexander is free to give the task for implementation to his student. After a first read, looks OK. You seem to have thought of everything that needs to be described, except maybe extraction of a single element: b : tuple of (integer, integer); a : integer; begin b:=(1,2); a:=b[0]; // a = 1 after this. end; Iff a tuple contains elements of the same type and if tuples with this restriction are compatible with arrays, wouldn't this behaviour be implicit? -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Alexander Klenin wrote: 2) The most important differentiating features of my proposal are: 2.1) Tuples are always temporary and anonymous. You can not store a tuple, define tuple type, of variable of tuple type. So tuples are 100% static, compile-time feature -- no change to RTTI, variants etc. If you can't define a tuple type then you can't check that it's assignment-compatible with e.g. an array. 2.2) Tuples construction: after some thinking, I propose to define a plain comma as an operator creating a tuple. I must say that I prefer the idea of any collection being in some form of brackets. I'm tempted to say any language extension being in bracket-like entities, even if that's paired keywords. This way, any comma-separated list is considered a tuple, and parenthesis may be used simply to control priority, since priority of comma is lower than all other operators. I will demonstrate below how the compatibility with existing features is still preserved. 2.2.1) Tuples are *flattening*, so (1, 2, (3, 4)) is a tuple of 4 elements, not of 3 elements, last being tuple. I've got a bad feeling about that. Apart from anything else I think it implies that (pseudocode) (TPoint, TColor) := (TColor, TPoint); would be valid. Single-value tuples are useless, so Tuple(1) is either a no-op or error. Except that a variant of that could be used to expand an element to a tuple. Or provided that tuples *did* *not* flatten it could expand a tuple to a tuple-of-tuples. type TPoint= tuple of Double; TRect= tuple of TPoint; var rect: TRect; begin rect := TRect(TPoint(100.0)); OK, so that's a zero-size rectangle but I'm trying to demonstrate potential syntax rather than do anything useful. -- Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues] ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, Jan 27, 2013 at 8:40 AM, Mark Morgan Lloyd markmll.fpc-de...@telemetry.co.uk wrote: If you can't define a tuple type then you can't check that it's assignment-compatible with e.g. an array. I do not see a link here. 2.2) Tuples construction: after some thinking, I propose to define a plain comma as an operator creating a tuple. I must say that I prefer the idea of any collection being in some form of brackets. I'm tempted to say any language extension being in bracket-like entities, even if that's paired keywords. Nothing stops you from adding extra brackets, if you like them. However, I think that in all cases: a, b := b, a; for v, k in a do DrawLine(Tuple(r), clRed); Nothin useful is gained by abbing extra pair of brackets. Also, comma is always a tuple removes grammar ambiguity -- there is no need to look ahead after the opening bracket. 2.2.1) Tuples are *flattening*, so (1, 2, (3, 4)) is a tuple of 4 elements, not of 3 elements, last being tuple. I've got a bad feeling about that. Apart from anything else I think it implies that (pseudocode) (TPoint, TColor) := (TColor, TPoint); would be valid. No, you'll have to write Tuple(APoint), AColor := AColor, Tuple(APoint); Single-value tuples are useless, so Tuple(1) is either a no-op or error. Except that a variant of that could be used to expand an element to a tuple. As Sven pointed out, the main problem with that is that expression type now suddenly depends on context, which is quite a rare feature in programming languages, and is probably much bugger change to Pascal than this whole tuple business. OTOH, define Tuple(x, 5) to mean (x, x, x, x, x) is quite possible, although less convenient: x, y, z := Tuple(0, 3); arr := Tuple(x, Length(arr)); -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
On Sun, Jan 27, 2013 at 12:11 PM, Alexander Klenin kle...@gmail.com wrote: Nothin useful is gained by abbing extra pair of brackets. Sorry, I mean Nothing useful is gained by adding ... -- Alexander S. Klenin ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] RFC: Support for new type tuple v0.1
Sven Barth schrieb: * Description What are tuples? Tuples are an accumulation of values of different or same type where the order matters. Sounds familiar? They are in this regard similar to records, but it's only the order of an element that matters, not its name. So what does make them special? Unlike records you can only query or set all the elements of a tuple at once. They basically behave like multiple assignments. In effect they allow you to return e.g. a multivalued result value without resorting to the naming of record fields (you'll still need to declare a tuple type) or the need for out parameters. This in turn allows you to use them for example in for-in loops. The lack of element names results in bloated code and runtime overhead. See below. * Declaration: [...] The usage of constructors and destructors also allows a realisation of group assignment: === code begin === var a, b, e: Integer; c, d: String; begin a := 42; c := 'Hello World'; (b, d) := (a, c); a := 21; b := 84; (a, b) := (b, a); // the compiler needs to ensure the correct usage of temps here! What will happen here? At compile time a tuple type (integer; integer) has to be defined, and an instance must be allocated for it. Initialization and finalization information/code must be added if required. At runtime the arguments are copied into that tuple instance, then copied into the target variables. All copies may be subject to type conversions and reference counting. Consider memory usage and runtime when tuples are nested, or contain large data structures (records, static arrays...). a := 42; (a, e) := (a * 2, a); // (a, e) should be (84, 42), not (84, 84) Such code tends to become cryptic with larger tuples. High level (source code) debugging will be impossible :-( [...] * Possible extensions Note: This section is not completely thought through! An possible extension would be to allow the assignment of tuples to records and/or arrays (and vice versa). [...] Without references to distinct tuple elements the coder has to provide local variables for *all* tuple elements, then decompose the *entire* tuple, before access to a single element will be possible. This may be accomplished with less source code when a tuple can be assigned to a record variable, but then it would be simpler to use records *instead* of tuples. When a record type is modified, during development, all *compatible* tuples and tuple types must be updated accordingly. * Possible uses - use for group assignments which can make the code more readable ... or unreadable (see above). - use for multivalues return values which can make the code more readable (instead of using records or out parameters) This IMO makes sense only when such tuples are passed along many times, before references to their elements occur. Otherwise full tuple decomposition is required when e.g. only a succ/fail indicator in the result tuple has to be examined. - use as result value for iterators (this way e.g. key and data of containers can be queried) This reminds me of SQL SELECT [fieldlist], where *specified* record fields are copied. But I wonder how confusion can be eliminated in the order of the tuple elements. Will (k,v) or (v,k) be the right order for key and value? What are the proper types of key and value? * Implementation notes Tuples need to pay attention to managed types (strings, interfaces, etc.). Thus an Init RTTI will be required (which needs to be handled by fpc_initalize/fpc_finalize accordingly). It might be worthwhile to add a new node type for tuple constructors/deconstructors (one node type should be sufficient) and handle them in assignment nodes accordingly. I'd reuse the record type node for that purpose. * Open issues Should anonymous tuples (together with tuple constructors) be allowed to participate in operator search as well? This would on the one hand allow the following code, but on the other hand make operator lookup rules less clear (because of assignment compatibility rules): === code begin === type TDoubleVector = tuple of (Double, Double, Double, Double); operator + (aLeft, aRight: TDoubleVector): TDoubleVector; // implement by e.g. using SSE instructions // somewhere else begin (d1, d2, d3, d4) := (d1, d2, d3, d4) + (1.0, 2.0, 3.0, 4.0); end; === code end === SSE should be used with array types, where all elements *definitely* have the same type. Then one + operator can be implemented for open arrays of any size, what looks quite impossible for tuples. Conclusion: IMO tuples are *abstract* templates (mathematical notation) for *concrete* (record...) implementations. I see no need or purpose in the introduction of such an abstract type into any concrete language, except when that languages lacks an already existing record (or equivalent) type. Nonetheless the discussion revealed some possible improvements of record