-
Content Count
285 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Rudy Velthuis
-
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
Not for me. Yes, it is what makes using this a problem, but that is not my objection against open array parameters. I would be against them if they had a different, unambiguous syntax too. And yes, I think the syntax choices made in the past were somewhat unfortunate and I would have preferred less ambiguous solutions, but that is not why I am against open array parameters on operators. I think the notion of open array parameters, especially open array constructors should be resticted to proper parameter lists of a function, and should not be used in any way on operators. And yes, I think that is nonsensical from the programmer's perspective. I don't care about the language designers or how they could solve their compiler problems, but I do care about the design of the language itself, from the perspective of a user of the language. Open array parameters should never have been allowed for operator overloads, IMO. I think I have already said why. They are just as silly as varargs in an operator overload in C++ (and you can't specify varargs in such an operator overload in C++). Actually, open array parameters are quite a lot like varargs in C++ (not technically, but semantically). For the same reasons, I don't think they should be allowed in Delphi, even if technically, it is possible. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
I know what a vector is, in several meanings of the word, thanks, and I know how to use them, or calculate with them or what kind of operations on them make sense. Not sure what that has to do with the fact that I think it is silly and stupid to declare open array parameters on overloaded operators. If you want to pass open array parameters to something, make that something a function, not an operator. And note that I think there is nothing wrong with declaring static array types (including Euclidian vectors or transformation matrices) or dynamic array types as parameters for operators. It makes sense to add two vectors (Euclidian kind) or concatenate the C++ kind of vectors using a + operator. It also makes sense to multiply a vector (any kind, actually) with a scalar using a * operator. But operators and open array parameters are a bad match. Again: this is fine: class operator Multiply(Left: Double; const Right: TVector3): TVector3; // scales a plain static 3D vector // or: class operator Multiply(Left: Double; const Right: TArray<Double>): TArray<Double> // numpy-style "broadcast": each element of Right is multiplied by Left. But this doesn't make any sense IMO: class operator Multiply(const Left, Right: array of Double): TArray<Double>; // Convolution: Left[i] is multiplied with Right[i] If you want that, then code it as: class function Multiply(const Left, Right: array of Double): TArray<Double>; static; And then you can call it like Result := Multiply([1.0, 2.0, 3.0], [4.0, 5.0, 6.0]); But this is (syntactical) nonsense, IMO: Result := [1.0, 2.0, 3.0] * [4.0, 5.0, 6.0]; Because you can't or at least shouldn't be able to use open array constructors like that, outside a parameter list. And they could be confused with dynamic array constants and perhaps even with sets anyway. Pure nonsense to try that, IMO. So if it compiles but doesn't work as expected, I am not surprised. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
Sure, arrays/vectors/matrices/lists/tuples/etc. can be thought of as single entities and I fully agree that one can use operators to combine them too, or to map single operations to such structures (e.g. like numpy's "broadcasts": myNewArray := myArray + 3;). But not open array parameters. They are parameters. Parameters belong in a parameter list, and operators do not have parameter lists. Well yes, they can have formal parameter lists when you declare their overloads, but not when they are used in infix or prefix notation. And that use is their sole raison d'être. After all, everything an operator does can be done with a plain function call too, like they do in Java; it just doesn't look so "natural". So if I had designed operator overloading, I would not have allowed open array parameters or arrays of const for them, for (to me) obvious reasons. I would of course have allowed predefined array types, dynamic and static, and TArray<x>, and what not. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
Well yes, the syntax overlap is unfortunate and very confusing. But sets exist much longer than dynarray constants or even much longer than open array constructors, so sets should always win, IMO. They could have used ([ and ]) or similar for open array parameters or even some kind of (alternative) function-like syntax. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
Duuude, an open array parameter is not one single thing, IMO. And the operators defined in Delphi only have one or two operands. Anything else makes no sense for those operators. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
Nothing wrong with arrays and operator, but everything with open array parameters on operators. Operators should have one or two parameters, depending on the type of operator, and not ranges of operands. -
operator overloding Equal vs Multiply
Rudy Velthuis replied to Eugine Savin's topic in RTL and Delphi Object Pascal
They are not normal static class methods either. There are restrictions and IMO, open array parameters should be among those restrictions. Otherwise, they are different too: e.g. certain operators can be overloaded by return type. The way they are called is especially different. They are not called with parameter lists, and to have open array constructors, you need parameter lists. But even if open array parameters are allowed for operators, they are simply a stupid idea. -
Any reservations on using const array[type] of?
Rudy Velthuis replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Incorrect. It is the same as: cInfoTypeNodeNames: array[itProject..itWorkers] of string = ('project', 'contacts_info', 'WRK', 'WRKS'); -
Delphi pitfalls: Enumerated types and for loops
Rudy Velthuis replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
What do you mean with "open arrays"? The only open arrays I know are open array parameters and I have no idea how you would implement sets with them. Did you perhaps mean dynamic arrays? If so, then please don't use confusing terminology. And it really gets confusing and troublesome if you confuse such "open arrays" with open array parameters. FWIW, there is already a TBits class, implementing an indexed bitset.- 39 replies
-
- pitfall
- enumerated type
-
(and 1 more)
Tagged with:
-
Befre you make more mistakes like the ones above, please ready my article about the Pitfalls of converting. It explains everything discussed here and a lot more.
-
User settings - split logic and UI
Rudy Velthuis replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
Yes. In my case, the settings are objects, one for each form, and together colllected in a special class. Each Settings class has public fields that are the settings and can be read globally They can be read and written by the control logic, and each can have an associated property of a control on the associated form, indicated using an attribute called AssociatedAttribute. Example: type TAppearanceOptions = class(TSettings) public [Associated('FileNameFontEdit.TextSettings.Font.Size')] FileFontSize: Single; [Associated('FileNameFontEdit.TextSettings.Font.Family')] FileFontFamily: string; [Associated('FileNameFontEdit.TextSettings.Font.Style')] FileFontStyle: TFontStyles; [Associated('TextLineFontEdit.TextSettings.Font.Size')] TextFontSize: Single; [Associated('TextLineFontEdit.TextSettings.Font.Family')] TextFontFamily: string; [Associated('TextLineFontEdit.TextSettings.Font.Style')] TextFontStyle: TFontStyles; [Associated('BackgroundColorCombo.Color')] BackColor: TColor; Each settings class can save itself to a given Storage class file (and re-load itself too). Storage classes can write to or read from ini files, or JSON files, or XML files, or the registry. Each settings class can set or read the properties associated by the attribute on a form given as parameter. If the appearance options form is opened, I call GlobalSettings.AppearanceOptions.SetProperties(AppearanceForm); and when it is closed with OK, I do: GlobalSettings.AppearanceOptions.GetProperties(ApperanceForm);. Uses quite a bit of RTTI, so it wouldn't work in old versions. -
How can I get the list of registered interfaces and their GUIDs in a Delphi 2007 application?
Rudy Velthuis replied to dummzeuch's topic in RTL and Delphi Object Pascal
Off-topic, but actually, that is multi-posting. Cross-posting is posting to several newgroups on the same server, with one single post (i.e. the single post has multiple targets and a reply in one group will usually appear in the other groups too, unless the reply was specifically set up not to do that).- 8 replies
-
- delphi-2007
- rtti
-
(and 2 more)
Tagged with:
-
Fast way to find points near a given point?
Rudy Velthuis replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Hypot takes the square root of sum of the squares, I guess (the length of the hypothenuse). But that is not necessary. It is enough to use Sqr(checkx - point.x) + Sqr(checky - point.y); Note that I use Sqr(), not Sqrt(). That will compare the squares of the distances, but that's fine too, as long as you know the square of the maximum distance. It is quite likely a lot faster, especially since you now only deal with integers again and don't need to take the square root. -
E2158 System unit out of date or corrupted: missing '@Clr' - how to cure?
Rudy Velthuis replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
Probably because of the error in the code, the compiler got into an inconsistent state. In such cases, the only way to get rid of the problem is to restart the IDE. -
Ad 1: The warning is correct. Both #$A and #$D are WideChar values reduced to AnsiChars. Ad 2: No, that doesn't mean it is resolved (I don't see any signs that we will get built-in Pascal sets 16-bit wide elements). Note that not C is reduced, only #$000A and #$000D. In such comparisons, if that is simpler, you will often see a set being reduced to a range. FWIW, instead of if A in ['A'..'Z'] then ... ; you can do: case A of 'A'..'Z': ... ; end; That is a little less convenient, but the range syntax lets you use all WideChar values, even the ones > #255. Ad 3: That is indeed weird. Even with optimizations on, you'll see the same. But this seems to be related to how LLVM handles DEBUG and RELEASE modes. It is well possible that the actual code in RELEASE mode (no-debug settings) is really optimized. But you can't see this in the CPU view. I say this because this kind of extremely ugly and uselessly complicated output can be seen from the Clang compilers too, in DEBUG mode. But as soon as DEBUG is off, you get extremely fast generated code. I just can't prove this yet. I managed to show this in the CPU view for a Clang-compiled program a few times, but sometimes that worked, sometimes it didn't. I can see that the code is shorter in RELEASE mode (48 instead of 64 bytes).
-
How to pass an unknown record to a function as argument
Rudy Velthuis replied to John Kouraklis's topic in RTL and Delphi Object Pascal
Yes, indeed you did. I must have missed that, sorry. -
Array compression in InternalGetUnicodeCategory() (System.Character)
Rudy Velthuis replied to mael's topic in RTL and Delphi Object Pascal
I assume that the structure of these $110000 values is thus, that there are many repeating structure, blocks and ranges, so I guess that for certain ranges, you only have to know parts of the values to know which types they are. I didn't look into the detail but I bet this is even described somewhere, in the Unicode documentation. Embarcadero didn't probably devise these lookups on their own. -
How to pass an unknown record to a function as argument
Rudy Velthuis replied to John Kouraklis's topic in RTL and Delphi Object Pascal
TRTTIContext doesn't have to be freed. To quote the help: -
How to pass an unknown record to a function as argument
Rudy Velthuis replied to John Kouraklis's topic in RTL and Delphi Object Pascal
Not much, as this is only one function. And it is more elegant than passing a pointer and type info. I would then make this function call a private function with the pointer obtained from the parameter and the typeinfo obtained from T. That way, there will hardly be any bloat. And if this function is not critical, you will never notice a difference. -
Complete Boolean Evaluation
Rudy Velthuis replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Not necessarily mediocre, but short-circuit might sound like something went wrong. <g> -
Complete Boolean Evaluation
Rudy Velthuis replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
Wow, that was important for you, I guess. Yes, I am happy to use it. I just use it, and if it doesn't work, I find out soon enough. Just like I always forget the order of directives like virtual, stdcall, static, inline, overload, etc., so I just try out an order and find out if it is wrong. <g> -
Complete Boolean Evaluation
Rudy Velthuis replied to dummzeuch's topic in Algorithms, Data Structures and Class Design
I am not so sure. If I remember correctly, in the very olden days, it was the only option (TP3 or some such -- memories about those days have become a little vague). Short-circuit boolean evaluation came later. Also: https://www.gnu-pascal.de/gpc/and.html: For such cases, GNU Pascal even knows the and then construct, to force short-circuit evaluation. -
Pitfalls of Anonymous methods and capture
Rudy Velthuis replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
FWIW, this is similar to the call-by-name problem (Jensen's device) in Algol 60. And similar problems can happen if people do: for I := 1 to 10 do begin MyRecord.Int := I; MyPlainTList.Add(@MyRecord); end; The entire plain TList is now filled with pointers to the same record, and that contains the value 10. <g> -
Pitfalls of Anonymous methods and capture
Rudy Velthuis replied to Lars Fosdal's topic in RTL and Delphi Object Pascal
Hmmm... I knew I had read something like it before, but couldn't find it anywhere (in a meaning that made sense). The missing S did it. -
How to switch condition position?
Rudy Velthuis replied to Mike Torrettinni's topic in Algorithms, Data Structures and Class Design
I wrote"I think" but was not 100% sure anymore and hadn't looked it up. Your link confirms this: That is indeed what I thought to remember. It was pretty late though...