delphipascallazarusfreepascalturbo-pascal

Is it possible to turn a statement into a expression?


In C, you can assign two variables in one line with

b = a = sqrt(10);

In Delphi

b := a := Sqrt(10);

is not allowed.

With IfThen, there is an "alternative" for the ternary operator ?: as discussed in Delphi - Equivalent to C#'s ternary operator? In summary, IfThen doesn't seem absolutely necessary.

So maybe there is also something like this:

function AssignAndReturn(var LHS: Integer; RHS: Integer): Integer;
begin
  LHS := RHS;
  Result := RHS;
end;

(...)

var
  a, b: Integer;
begin
  b := AssignAndReturn(a, Round(Sqrt(10)));

I'm not trying to "make everything look like C". I just noticed, that sometimes it would be nice to "reuse" the right hand side of an assignment in the same line again. (See Lazarus/Free Pascal: How to improve coding style (to avoid using endless loop) of a while loop whose boolean expression is reassigned every pass for example.)


Solution

  • The short answer is:
    No. What you want is not possible. And arguably would be of little if any benefit in Delphi.


    First, let's discuss a more practical example. To be frank, a = b = f(x); is a rather poor example.


    So instead, let's consider the following, more practical scenario:

    //Option 1
    if ((b = f(x)) > 42)
      //use b
    

    There's no Delphi equivalent to the above, but it's at least as readable/maintainable to write:

    //Option 2
    b := f(x);
    if (b > 42) then
      //use b
    

    There is another option to consider; especially if Option 1 is sitting in the middle of a larger function. Remember small functions are more maintainable and easier for a compiler to optimise. So consider:

    //Option 3
    ...
    ProcessRule42(f(x));
    ...
    //Where Rule42 is is implemented as:
    procedure ProcessRule42(b: Integer);
    begin
      if (b > 42) then
        //use b
    end;
    

    Delphi doesn't really seem to be suffering due to not being able to write: if (b := f(x)) > 42 then //use b.

    Is there any real benefit to Option 1?

    If the Option 2 is at least as good, why would one ever bother with Option 1. The benefit is seen when you consider scoping rules.

    //b does not exist
    if ((var b = f(x)) > 42) {
      //use b
    }
    //b does not exist 
    
    // Using the Delphi approach, this becomes:
    //b does not exist
    var b = f(x);
    if (b > 42) {
      //use b
    }
    //b still exists
    

    Delphi simply does not have the same scoping concerns. Delphi variables are all declared at the beginning of the method, and available for the whole method.


    Conclusion

    This brings us back to what others have been trying to explain. Delphi is a different language with slightly different approaches to some problems. While I applaud you for examining other options and considering what concepts can be borrowed from other languages: be careful of trying to force-fit some concepts where they don't belong.

    If you break too many Delphi paradigms, your code may become unnecessarily difficult for Delphi programmers to maintain.