Recent

Author Topic: Can I somehow set priority of undecidable routines?  (Read 2771 times)

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Can I somehow set priority of undecidable routines?
« Reply #15 on: January 23, 2023, 12:19:45 pm »
I try to avoid any special treatment, as the place calling it is generated by a program (for over 1000 cases) and I want to keep them all look alike. This is why the typecast is not ideal either.
I understand where you are coming from, but I also understand that without any special treatment it is not possible for the compiler to make a correct distinction.

That is why I wrote earlier that I consider it a bug that using a cast won't work.

I just followed for this example the simple versions.
It is always difficult to known whether you write what you wrote because lack of experience of convenience for the example. No damage done as in that case it is ok.

I would opt for TIntegerArray and TStringArray though.

Quote
If I understand correctly, you suggest to use
but it will not work. If BOTH are pre-defined types then again, the compiler cannot decide which one to call when a([]); is called. The trick is to use one pre-defined one and one array of ... .
Yes but the suggestion made is not for making the distinction for the caller rather for consistency amongst your code. Say for example you have 100 of such routines and later on you decide to change the type of parameter for instance from integers to strings (or any other type).

afaik the only way to have the compiler determine the correct function (for an empty array) is to use .create.
Today is tomorrow's yesterday.

jollytall

  • Sr. Member
  • ****
  • Posts: 380
Re: Can I somehow set priority of undecidable routines?
« Reply #16 on: January 23, 2023, 01:28:37 pm »
I have just found another strange behavior:

Code: Pascal  [Select][+][-]
  1. program simple;
  2.  
  3. uses
  4. SysUtils;
  5.  
  6. type
  7.   tStringArray  = array of string;
  8.   tIntegerArray = array of integer;
  9.   tDoubleArray  = array of double;
  10.  
  11. procedure a(const x: tStringArray);
  12.   begin
  13.   writeln('In strings');
  14.   end;
  15. procedure a(const x: tIntegerArray);
  16.   begin
  17.   writeln('In integers');
  18.   end;
  19. procedure a(const x: array of double);
  20.   begin
  21.   writeln('In doubles');
  22.   end;
  23. procedure aa(const x: array of const); // TRY renaming it to a instead of aa
  24.   begin
  25.   Writeln('In const');
  26.   end;
  27.  
  28. var
  29.   v1: tStringArray;
  30.   v2: array of integer;
  31.   v3: tDoubleArray;
  32. begin
  33. a(['a','b']);      // if const exists then that is called, otherwise the correct one
  34. a([12,23]);        // same here
  35. a([12.34, 45.67]); // same here
  36. v1 := []; a(v1);   // works, always calling the right one
  37. v2 := []; a(v2);   // same here
  38. v3 := []; a(v3);   // same here
  39. a([]);             // only compiles when "const" is there OR there is one and only one with "array of something"
  40. Sleep(500);
  41. end.

I tried various combinations AND added a new version with "array of const" (there there is not even a possibility to make a new type, "type tConstArray = array of const"). I named it to "aa", but you can rename it to "a" to see the difference.
If the new const version is there then all bracket (constant) versions are calling the new routine and only the variable versions (v1, v2, v3) call the correct one (regardless how v was defined as a pre-defined type or an array of something).
If const version is not there, but from the three others (string, integer, double) there is one and only one defined array of something (in this case the double) then the non-empty brackets and the variables call the right one and the empty one calls the only "array of something" version.
If const is not there and there is zero or more than one "array of something" version of a, then the empty bracket does not compile.

I find it a very strange behavior. If for [12, 34] the compiler knows that it is an array of integers when there is no const version, then why does it call the array of const version when it is there. I could expect two different behaviors, either that (a) since it knows that [12, 34] is integer, it would call the integer version and disregard the array of const version OR (b) it would say that it is either the integer version or there is a new const version both suitable to be called, so it cannot decide (like in other examples would give a compile error), but I do not see how it can work both with and without the const version and do different things.
It seems that the array of const version has a priority over all other versions, what is especially strange knowing that array of const passes on a Variable type, what is much less efficient both in terms of memory and processing.

The beauty of the thing is that it gives me a working, but a bit ugly solution. going back to the original problem. If I change the parameters to the tIntegerArray type for most overloaded versions except one then it always work as intended. If the array is not empty, it calls the right overloaded version, while if it is empty it calls the one defined with "array of something" version.
If I want to make my code more coherent and a bit more elegant (though still a bit ugly), I can make all valid, used versions like tIntegerArray, tDoubleArray, etc. and make one more dummy version like "array of byte" or some other type never used and use that for handling the empty arrays.

PascalDragon

  • Hero Member
  • *****
  • Posts: 6354
  • Compiler Developer
Re: Can I somehow set priority of undecidable routines?
« Reply #17 on: January 23, 2023, 10:38:25 pm »
But I am personally more in favour of GetMem's solution.

It is a different solution, as you must pass a dynamic array, and not just some random construct array of strings.

FPC 3.2.0 and newer has dynamic array constructors which allows to pass literal arrays to dynamic array parameters.

I have just found another strange behavior:

Please report a bug.

jollytall

  • Sr. Member
  • ****
  • Posts: 380
Re: Can I somehow set priority of undecidable routines?
« Reply #18 on: January 24, 2023, 09:47:41 am »
Is it really a bug, or just some logic working behavior that I do not understand?

PascalDragon

  • Hero Member
  • *****
  • Posts: 6354
  • Compiler Developer
Re: Can I somehow set priority of undecidable routines?
« Reply #19 on: January 24, 2023, 10:07:44 pm »
Is it really a bug, or just some logic working behavior that I do not understand?

Well, seems like Delphi behaves the same. So not a bug...

 

TinyPortal © 2005-2018