Mike Torrettinni 198 Posted November 29, 2020 I use IfThen a lot. Delphi already has some of it's own IfThen defined: in System.Math are defined for numbers, in System.StrUtils there is one defined for string parameters: System.Math: function IfThen(AValue: Boolean; const ATrue: Integer; const AFalse: Integer = 0): Integer; overload; inline; //... and other number types of parameters System.StrUtils: function IfThen(AValue: Boolean; const ATrue: string; AFalse: string = ''): string; overload; inline; I have a few of my own, with XML types, TVirtualStringTree parameters... all overloaded of course, in my Utils.pas unit. I would like to have them all defined in my Utils, so I only need to put Utils in uses. The problem is when if I still need to use System.StrUtils or System.Math for other functions, I get error: E2251 Ambiguous overloaded call to 'IfThen' System.StrUtils.pas(499)... It makes sense, because same Ifthen signatures are not in System.StrUtils and my Utils. Is there anyway to avoid this error and force it to use IfThen from my Utils and not get this error? Share this post Link to post
Guest Posted November 29, 2020 You can and should point the compiler to the right unit file specially if you are reusing functions names, System.Math.IfThen(.... instead of just IfThen or just StrUtils.Ifthen for your library Utils.IfThen(... One more thing: did you named a file in your library "Utils.pas" ? I suggest to pick some naming pattern for your own library, also stick to a pattern for each project you are writing, this on the long run will simplify your life. example mtUtils.pas instead of just Utils.pas, this will prevent rare and time wasting situation, when you there is a file has the same popular name in either a 3rdparty library or a project. Share this post Link to post
David Heffernan 2347 Posted November 29, 2020 What types are the parameters for the functions that are ambiguous? Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 1 hour ago, David Heffernan said: What types are the parameters for the functions that are ambiguous? Integer and String, copied from Math and StrUtils. Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 1 hour ago, Kas Ob. said: You can and should point the compiler to the right unit file specially if you are reusing functions names, System.Math.IfThen(.... instead of just IfThen or just StrUtils.Ifthen for your library Utils.IfThen(... One more thing: did you named a file in your library "Utils.pas" ? I suggest to pick some naming pattern for your own library, also stick to a pattern for each project you are writing, this on the long run will simplify your life. example mtUtils.pas instead of just Utils.pas, this will prevent rare and time wasting situation, when you there is a file has the same popular name in either a 3rdparty library or a project. Oh, I didn't think about this... I'm not used to using unit identifiers, except in some cases. Before I started using namespaces for unit names, it would be easier, but now it's getting annoying to have to name the full unit name. Like: ProjectName.Utilities.IfThen() instead of just IfThen() If there is no other way, then I can start using unit prefix. But it will take time to adjust. No, Utils.pas name is just for this example purpose. Share this post Link to post
David Heffernan 2347 Posted November 29, 2020 1 hour ago, Mike Torrettinni said: Integer and String, copied from Math and StrUtils. This seems odd. Why would you need another implementation of IfThen for Integer and string? Why would you need more than one? Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 Just now, David Heffernan said: This seems odd. Why would you need another implementation of IfThen for Integer and string? Why would you need more than one? I have many units where I need access to integer, string and one of custom IfThen implementations. So, I want to just use my Utils.pas, without StrUtils and Math in these units. Share this post Link to post
David Heffernan 2347 Posted November 29, 2020 That's a poor idea in my view. Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 1 hour ago, David Heffernan said: That's a poor idea in my view. Just trying to clean up the uses clause. And these are simple functions, nothing I need to worry about Delphi changing in the future. Share this post Link to post
David Heffernan 2347 Posted November 29, 2020 Well, now you've got to fully qualify function calls left right and centre, so it's hard to see this as a clean up. Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 5 minutes ago, David Heffernan said: Well, now you've got to fully qualify function calls left right and centre, so it's hard to see this as a clean up. You are right, it doesn't seem like there is a perfect solution. A trade off in all cases. Will see how it goes with this, perhaps I will realize it was not a good decision, or it will be really neat solution to my problem. Share this post Link to post
Attila Kovacs 629 Posted November 29, 2020 (edited) isn't this "IfThen" is the one that nobody uses because it evaluates both branches? Edited November 29, 2020 by Attila Kovacs 2 Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 13 minutes ago, Attila Kovacs said: isn't this "IfThen" is the one that nobody uses because it evaluates both branches? It works very good on simple types, I use it a lot. For example: IntegerValue := IfThen(condition, IntVal1, IntVal2); StringValue := IfThen(Condition, String1, String2); For expressions, you need to be aware they will be evaluated, so it can cause problems if not used correctly, like: vStr1 := '1'; vStr2 := ''; vInt := IfThen(condition, vStr1.ToInteger, vStr2.ToInteger); // will fail at runtime The runtime error will occur here: EConvertError with message ''' is not a valid integer value for Integer type' It's like with everything else in Delphi: if you don't use it is expected, you get unexpected behavior. Use it as is it designed, you get correct behavior. Share this post Link to post
David Heffernan 2347 Posted November 29, 2020 32 minutes ago, Mike Torrettinni said: if you don't use it is expected, you get unexpected behavior. Use it as is it designed, you get correct behavior The point is not that it doesn't behave as designed. It's that the design is poor. What is needed is a conditional operator built into the language, like in almost all other languages. Share this post Link to post
Mike Torrettinni 198 Posted November 29, 2020 2 minutes ago, David Heffernan said: The point is not that it doesn't behave as designed. It's that the design is poor. What is needed is a conditional operator built into the language, like in almost all other languages. I assume you are right - I'm the last one to judge the core of Delphi functionality... was just explaining what he was asking about with example. That is how I remember IfThen issues, but my experience is limited to simple type examples. Share this post Link to post
Lars Fosdal 1792 Posted November 30, 2020 I also use IfThen a lot - but only for string constants. A ternary operator - or lambdas without the verbosity would have been so nice. Share this post Link to post
Attila Kovacs 629 Posted November 30, 2020 15 minutes ago, Lars Fosdal said: so nice for sure H := (C = 0 ? 0 : V = r ? (g - b) / C : V = g ? (b - r) / C + 2 : (r - g) / C + 4 ); 4 Share this post Link to post
Lars Fosdal 1792 Posted November 30, 2020 If it exists, it can be abused. 2 Share this post Link to post
Clément 148 Posted November 30, 2020 (edited) Hi, I'm using another construction for simple types: iif<T>( aCond : boolean; aTrue : T; aFalse : T ) : T; function iif<T>( aCond : boolean; aTrue : T; aFalse : T ) : T; begin if aCond then Result := aTrue else Result := aFalse; end; No overloads, very easy to ready.... procedure SomeProcedure; begin a := iif<string>( aCond, 'Hello', 'World'); b := iif<integer>( aCond, 12, 0 ); end; As for ternary operators, it would be a nice addition. Couldn't it be written in ASM? Edited November 30, 2020 by Clément Share this post Link to post
Rollo62 538 Posted November 30, 2020 20 hours ago, Kas Ob. said: You can and should point the compiler to the right unit file specially if you are reusing functions names, System.Math.IfThen(.... instead of just IfThen or just StrUtils.Ifthen for your library Utils.IfThen(... .. I suggest to pick some naming pattern for your own library, This "naming pattern" is not limited to the uses alone. I know, most people dislike that decorating of function names, but I do that in some similar cases too, like that: MtIfThen(... Share this post Link to post
Lars Fosdal 1792 Posted November 30, 2020 3 minutes ago, Clément said: function iif<T>( aCond : boolean; aTrue : T; aFalse : T ) : T; begin if aCond then Result := aTrue else Result := aFalse; end; Not in Delphi, for sure. Share this post Link to post
Anders Melander 1795 Posted November 30, 2020 22 minutes ago, Clément said: Couldn't it be written in ASM? What's the point? The arguments would still be evaluated up front. You need the cooperation of the compiler to avoid that. 1 Share this post Link to post
Clément 148 Posted November 30, 2020 26 minutes ago, Lars Fosdal said: Not in Delphi, for sure. In a delphi class, record, or form I mean. Share this post Link to post
Clément 148 Posted November 30, 2020 4 minutes ago, Anders Melander said: What's the point? The arguments would still be evaluated up front. You need the cooperation of the compiler to avoid that. One can always hope. Share this post Link to post
Anders Melander 1795 Posted November 30, 2020 6 minutes ago, Clément said: hope. I think I'll put that on a t-shirt: "Hope - Helping Delphi survive since 1996" 1 5 Share this post Link to post