New feature: IfThen() intrinsic

classic Classic list List threaded Threaded
186 messages Options
1234 ... 10
Reply | Threaded
Open this post in threaded view
|

New feature: IfThen() intrinsic

Sven Barth-2
Hello together!

I've finally come around to add a feature that many people have asked
for throughout the years: an inline if that works like the if-statement
in that it only evaluates that expression that is indeed returned.

After the discussion last year about the inline-if I've decided to add
it as an intrinsic function instead of an extension of the language.
Like all intrinsics it's part of the System unit and "declared" like this:

=== code begin ===

function IfThen(Condition: Boolean; ThenExpr, ElseExpr: type): type;

=== code end ===

Since it's declared in the System unit it won't interfere with the
IfThen()s that are declared in the Math unit or other units, so they'll
continue to work as before to avoid any surprises.

An important point to note is that in general the result type is
determined by the ThenExpr (there are a few usability exceptions
regarding strings and chars).

Examples:

=== code begin ===

function A: LongInt;
begin
  A := 42;
end;

function B: LongInt;
  B := 21;
end;

var
  i, j: LongInt;
  s: String;
begin
  i := 42;
  j ;= IfThen(i < 32, 48, 21);

  j := IfThen(True, 23, 49); // compiler will warn of unreachable code
  j := IfThen(False, 23, 49); // compiler will warn of unreachable code

  j := IfThen(i < 32, A, B); // in this case only B will be executed

  //j := IfThen(i < 32, 32, '123'); // this will fail if there's no
suitable conversion operator available

  //s := IfThen(j < 32, #42, 'Foo'); // this will fail as a char is expected
  s := IfThen(j < 32, #42, #3294); // this will work however and will
result in a WideChar
  s := IfThen(j < 32, 'Hello World', 'Hello'#3294'World'); // this will
also work and will result in a WideString (and a warning as s is a
Short-/AnsiString)
end;

=== code end ===

If there are any combinations of types that should work, but do not,
please don't hesistate to report them at http://bugs.freepascal.org/

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Mark Morgan Lloyd-5
Sven Barth wrote:
> Hello together!
>
> I've finally come around to add a feature that many people have asked
> for throughout the years: an inline if that works like the if-statement
> in that it only evaluates that expression that is indeed returned.
>
> After the discussion last year about the inline-if I've decided to add
> it as an intrinsic function instead of an extension of the language.

Thanks for that, it will make maintaining some Pascal transcribed from
Javascript much easier.

--
Mark Morgan Lloyd
markMLl .AT. telemetry.co .DOT. uk

[Opinions above are the author's, not those of his employers or colleagues]
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

silvioprog
In reply to this post by Sven Barth-2
On Sun, Jan 31, 2016 at 11:43 AM, Sven Barth <[hidden email]> wrote:
Hello together!

I've finally come around to add a feature that many people have asked
for throughout the years: an inline if that works like the if-statement
in that it only evaluates that expression that is indeed returned.

After the discussion last year about the inline-if I've decided to add
it as an intrinsic function instead of an extension of the language.
Like all intrinsics it's part of the System unit and "declared" like this:

=== code begin ===

function IfThen(Condition: Boolean; ThenExpr, ElseExpr: type): type;

=== code end ===

Since it's declared in the System unit it won't interfere with the
IfThen()s that are declared in the Math unit or other units, so they'll
continue to work as before to avoid any surprises.

An important point to note is that in general the result type is
determined by the ThenExpr (there are a few usability exceptions
regarding strings and chars).

Examples:

=== code begin ===

function A: LongInt;
begin
  A := 42;
end;

function B: LongInt;
  B := 21;
end;

var
  i, j: LongInt;
  s: String;
begin
  i := 42;
  j ;= IfThen(i < 32, 48, 21);

  j := IfThen(True, 23, 49); // compiler will warn of unreachable code
  j := IfThen(False, 23, 49); // compiler will warn of unreachable code

  j := IfThen(i < 32, A, B); // in this case only B will be executed

  //j := IfThen(i < 32, 32, '123'); // this will fail if there's no
suitable conversion operator available

  //s := IfThen(j < 32, #42, 'Foo'); // this will fail as a char is expected
  s := IfThen(j < 32, #42, #3294); // this will work however and will
result in a WideChar
  s := IfThen(j < 32, 'Hello World', 'Hello'#3294'World'); // this will
also work and will result in a WideString (and a warning as s is a
Short-/AnsiString)
end;

=== code end ===

If there are any combinations of types that should work, but do not,
please don't hesistate to report them at http://bugs.freepascal.org/

Wooow! I did a request about it many years ago, however it was rejected because the limitation in the generic feature at that time.

So, I posted a bug related to it yesterday:


Can I use it after this new feature? (I'm upgrading my FPC sources now :-) )

Buddy, thanks a lot for that feature, it is very useful! o/

--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

vojtech.cihak
In reply to this post by Sven Barth-2

Hi,

 

what is difference in produced assembler between ifthen(); and classic if - then - else?


Thanks, V.

______________________________________________________________
> Od: Sven Barth <[hidden email]>
> Komu: "FPC-Pascal users discussions" <[hidden email]>
> Datum: 31.01.2016 15:43
> Předmět: [fpc-pascal] New feature: IfThen() intrinsic
>

Hello together!

I've finally come around to add a feature that many people have asked
for throughout the years: an inline if that works like the if-statement
in that it only evaluates that expression that is indeed returned.

After the discussion last year about the inline-if I've decided to add
it as an intrinsic function instead of an extension of the language.
Like all intrinsics it's part of the System unit and "declared" like this:

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Sven Barth-2
On 31.01.2016 16:14, Vojtěch Čihák wrote:
> what is difference in produced assembler between ifthen(); and classic
> if - then - else?

=== code begin ===

i := IfThen(x < 42, 32, 49);

=== code end ===

is equivalent to

=== code begin ===

if x < 42 then
  i := 32
else
  i := 49;

=== code end ===

That's in fact how the compiler handles this internally (with the added
benefit of nesting IfThen()s).

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Sven Barth-2
In reply to this post by silvioprog
On 31.01.2016 16:09, silvioprog wrote:
> Wooow! I did a request about it many years ago, however it was rejected
> because the limitation in the generic feature at that time.

This implementation has nothing to do with generics. It's a compiler
magic function, just like Writeln() and thus it can bend the usual rules ;)

> So, I posted a bug related to it yesterday:
>
> http://bugs.freepascal.org/view.php?id=29546

I've seen your bug this night and that was the cause for finally
implementing this.

> Can I use it after this new feature? (I'm upgrading my FPC sources now :-) )

I've not yet looked at what the problem regarding your code is. However
you can simply remove your TUtils.Iif() and use IfThen() instead.

> Buddy, thanks a lot for that feature, it is very useful! o/

That's what I have hoped for. :)

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

silvioprog
On Sun, Jan 31, 2016 at 12:20 PM, Sven Barth <[hidden email]> wrote:
On 31.01.2016 16:09, silvioprog wrote:
> Wooow! I did a request about it many years ago, however it was rejected
> because the limitation in the generic feature at that time.

This implementation has nothing to do with generics. It's a compiler
magic function, just like Writeln() and thus it can bend the usual rules ;)

Awesome.

> So, I posted a bug related to it yesterday:
>
> http://bugs.freepascal.org/view.php?id=29546

I have a test-case in a draft project that worked fine some days ago, so I think that this bug was introduced recently. o_O

I've seen your bug this night and that was the cause for finally
implementing this.

2^64 thanks! :-)

> Can I use it after this new feature? (I'm upgrading my FPC sources now :-) )

I've not yet looked at what the problem regarding your code is. However
you can simply remove your TUtils.Iif() and use IfThen() instead.

YES! o/ .. \o .. \o/

I'm going to do it now ... :-D

> Buddy, thanks a lot for that feature, it is very useful! o/

That's what I have hoped for. :)

^^

--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

silvioprog
In reply to this post by Sven Barth-2
On Sun, Jan 31, 2016 at 11:43 AM, Sven Barth <[hidden email]> wrote:
Hello together!

I've finally come around to add a feature that many people have asked
for throughout the years: an inline if that works like the if-statement
in that it only evaluates that expression that is indeed returned.

After the discussion last year about the inline-if I've decided to add
it as an intrinsic function instead of an extension of the language.
Like all intrinsics it's part of the System unit and "declared" like this:

=== code begin ===

function IfThen(Condition: Boolean; ThenExpr, ElseExpr: type): type;

=== code end ===
[...] 
If there are any combinations of types that should work, but do not,
please don't hesistate to report them at http://bugs.freepascal.org/


--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

silvioprog
On Sun, Jan 31, 2016 at 1:03 PM, silvioprog <[hidden email]> wrote:
[...] 
If there are any combinations of types that should work, but do not,
please don't hesistate to report them at http://bugs.freepascal.org/



Sorry for fast reporting! ^^'

--
Silvio Clécio

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Ralf Quint
In reply to this post by vojtech.cihak
On 1/31/2016 7:14 AM, Vojtěch Čihák wrote:
>
> Hi,
>
> what is difference in produced assembler between ifthen(); and classic
> if - then - else?
>
>
+1

I don't really see how this is different from properly writing  if ...
then ... else... either... :-\

Ralf

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Stephen Chrzanowski
Mostly code readability, but, I've been writing my own functions to do that kind of thing for years.  Same with the BETWEEN function.

On Mon, Feb 1, 2016 at 1:03 AM, Ralf Quint <[hidden email]> wrote:
On 1/31/2016 7:14 AM, Vojtěch Čihák wrote:

Hi,

what is difference in produced assembler between ifthen(); and classic if - then - else?


+1

I don't really see how this is different from properly writing  if ... then ... else... either... :-\

Ralf

---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Marco van de Voort
In reply to this post by Sven Barth-2
In our previous episode, Sven Barth said:

> After the discussion last year about the inline-if I've decided to add
> it as an intrinsic function instead of an extension of the language.
> Like all intrinsics it's part of the System unit and "declared" like this:
>
> === code begin ===
>
> function IfThen(Condition: Boolean; ThenExpr, ElseExpr: type): type;
>
> === code end ===
>
> Since it's declared in the System unit it won't interfere with the
> IfThen()s that are declared in the Math unit or other units, so they'll
> continue to work as before to avoid any surprises.
>
> An important point to note is that in general the result type is
> determined by the ThenExpr (there are a few usability exceptions
> regarding strings and chars).

I'm not really fond of the functionality, and I would not write new code
with it, but it is very handy when converting C code.
 
The only really bad thing is the name, as Florian already said, with the
versions in strutils and math.  The clash with delphi compatible functions
should be avoided.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Maciej Izak
2016-02-01 8:59 GMT+01:00 Marco van de Voort <[hidden email]>:
The only really bad thing is the name, as Florian already said, with the
versions in strutils and math.  The clash with delphi compatible functions
should be avoided.

+1 . IfThen instricit is IMO very bad idea. I have a lot of "IfThen" from math and strutils modules.

IfThen from System totally breaks the compatibility :\ . C'mon Sven. In one field you're rigorously but in something like this you're liberal (braking/dangerous change / for existing code base).

If i understand correctly "ThenExpr" is executed only when "Condition" is true and "ElseExpr" is executed only when "Condition" is false. For standard "IfThen" from Math and StrUtils "ThenExpr" and "ElseExpr" is executed before IfThen is called.

for me different syntax for System.IfThen is required (fpIfThen ? or http://docs.elementscompiler.com/Oxygene/Expressions/If/ ).
--
Best regards,
Maciej Izak

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

leledumbo
Administrator
> If i understand correctly "ThenExpr" is executed only when "Condition" is true and "ElseExpr" is executed only when "Condition" is false. For standard "IfThen" from Math and StrUtils "ThenExpr" and "ElseExpr" is executed before IfThen is called.

This is one thing that becomes my concern as expected side effect might not be triggered due to semantic differences, although I seldom use IfThen from either math/strutils (not lazy enough to write complete `if ... then begin ... end else begin ... end` for the sake of easy future modification).
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

David Butler
In reply to this post by Sven Barth-2
This is usually called "inline if".

Maybe call it "inlineif" or "iif", e..g

x := iif (a < 3, 1, 2)

or even

x := iif a < 3 then 1 else 2;


On Mon, Feb 1, 2016 at 10:26 AM, Maciej Izak <[hidden email]> wrote:
2016-02-01 8:59 GMT+01:00 Marco van de Voort <[hidden email]>:
The only really bad thing is the name, as Florian already said, with the
versions in strutils and math.  The clash with delphi compatible functions
should be avoided.

+1 . IfThen instricit is IMO very bad idea. I have a lot of "IfThen" from math and strutils modules.

IfThen from System totally breaks the compatibility :\ . C'mon Sven. In one field you're rigorously but in something like this you're liberal (braking/dangerous change / for existing code base).

If i understand correctly "ThenExpr" is executed only when "Condition" is true and "ElseExpr" is executed only when "Condition" is false. For standard "IfThen" from Math and StrUtils "ThenExpr" and "ElseExpr" is executed before IfThen is called.

for me different syntax for System.IfThen is required (fpIfThen ? or http://docs.elementscompiler.com/Oxygene/Expressions/If/ ).


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Maciej Izak
2016-02-01 9:35 GMT+01:00 David Butler <[hidden email]>:
This is usually called "inline if".

Maybe call it "inlineif" or "iif", e..g

x := iif (a < 3, 1, 2)

or even

x := iif a < 3 then 1 else 2;


anything is better than System.IfThen blatant incompatibility. I opt for oxygene syntax. Anyway reverting this "ferature" in current form is very important.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Michalis Kamburelis-3
In reply to this post by Maciej Izak
Maciej Izak wrote:

> +1 . IfThen instricit is IMO very bad idea. I have a lot of "IfThen"
> from math and strutils modules.
>
> IfThen from System totally breaks the compatibility :\ . C'mon Sven. In
> one field you're rigorously but in something like this you're liberal
> (braking/dangerous change / for existing code base).
>
> If i understand correctly "ThenExpr" is executed only when "Condition"
> is true and "ElseExpr" is executed only when "Condition" is false. For
> standard "IfThen" from Math and StrUtils "ThenExpr" and "ElseExpr" is
> executed before IfThen is called.
>
> for me different syntax for System.IfThen is required (fpIfThen ? or
> http://docs.elementscompiler.com/Oxygene/Expressions/If/ ).

As far as I understand, compatibility is not broken: new IfThen was
deliberately introduced as part of the System unit, that is implicitly
always used as the 1st unit. If you use Math (or StrUtils or any other
modules that provide IfThen implementations), they will "cover" the
System.IfThen definition. So your code will continue to work as it was.

And the name like FpIfThen look rather ugly, actually. As far as I'm
concerned, IfThen sounds simple and Ok.

Michalis
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Maciej Izak
2016-02-01 10:17 GMT+01:00 Michalis Kamburelis <[hidden email]>:
As far as I understand, compatibility is not broken: new IfThen was
deliberately introduced as part of the System unit, that is implicitly
always used as the 1st unit. If you use Math (or StrUtils or any other
modules that provide IfThen implementations), they will "cover" the
System.IfThen definition. So your code will continue to work as it was.

And the name like FpIfThen look rather ugly, actually. As far as I'm
concerned, IfThen sounds simple and Ok.

IfThen is not ok. It can potentially break compatibility. The probability is huge. IfThen is in many cases the only function that is used from Math or StrUtils. I have big codebase to maintain which is refactored very often. The risk to omit Math and StrUtils is very big.

It can be very hard to debug.

There are so many ways to implement this and was chosen the worst scenario. :\ 

--
Best regards,
Maciej Izak

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Michael Van Canneyt


On Mon, 1 Feb 2016, Maciej Izak wrote:

> 2016-02-01 10:17 GMT+01:00 Michalis Kamburelis <[hidden email]>:
>>
>> As far as I understand, compatibility is not broken: new IfThen was
>> deliberately introduced as part of the System unit, that is implicitly
>> always used as the 1st unit. If you use Math (or StrUtils or any other
>> modules that provide IfThen implementations), they will "cover" the
>> System.IfThen definition. So your code will continue to work as it was.
>>
>> And the name like FpIfThen look rather ugly, actually. As far as I'm
>> concerned, IfThen sounds simple and Ok.
>
>
> IfThen is not ok. It can potentially break compatibility. The probability
> is huge. IfThen is in many cases the only function that is used from Math
> or StrUtils. I have big codebase to maintain which is refactored very
> often. The risk to omit Math and StrUtils is very big.

This is not an argument.

If you take this as an argument, then the system unit is set in concrete,
for fear of breaking someones code whenever something new is introduced.

>
> It can be very hard to debug.
>
> There are so many ways to implement this and was chosen the worst scenario.
> :\

From my point of view, Sven took the best possible route by making it an
identifier of the system unit. The refactoring argument is nonsense, as it
applies to ANY identifier, not just this one.

We can discuss IIF or IfThen, but the same applies for IIF.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: New feature: IfThen() intrinsic

Maciej Izak
2016-02-01 10:42 GMT+01:00 Michael Van Canneyt <[hidden email]>:

This is not an argument.

If you take this as an argument, then the system unit is set in concrete,
for fear of breaking someones code whenever something new is introduced.

No. This is argument. That was reason in Delphi to introduce TObject.DisposeOf instead of any other name to help not breaking someones code.

From my point of view, Sven took the worst possible route, *especially there is a hundred other ways to achieve this* (!).

--
Best regards,
Maciej Izak

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
1234 ... 10