Recent

Author Topic: Extending a dynamic array by one element.  (Read 1466 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 8027
Extending a dynamic array by one element.
« on: July 19, 2024, 10:46:18 pm »
I am extremely uncomfortable with the use of + as a concatenation operator due to its being far more useful as an arithmetic operator when numeric arrays are being manipulated, and for the sake of discussion suggest >< instead.

Assuming

Code: Pascal  [Select][+][-]
  1.   TVertexDegs= record
  2.                  lat, lon: double
  3.                end;
  4.   TRegionDegs= array of TVertexDegs;
  5.  

then I presume that concatenation of a single element is best done like

Code: Pascal  [Select][+][-]
  1. operator >< (const region: TRegionDegs; const point: TVertexDegs): TRegionDegs;
  2.  
  3. begin
  4.   result := region;
  5.   SetLength(result, Length(result) + 1);
  6.   result[High(result)] := point
  7. end { >< } ;
  8.  

I'm uncomfortable, however, with the situation where an element is being tacked onto the front. Is there something more efficient than

Code: Pascal  [Select][+][-]
  1. operator >< (const point: TVertexDegs; const region: TRegionDegs): TRegionDegs;
  2.  
  3. var
  4.   i: integer;
  5.  
  6. begin
  7.   SetLength(result, Length(region) + 1);
  8.   result[0] := point;
  9.   for i := 0 to High(region) do
  10.     result[i + 1] := region[i]
  11. end { >< } ;
  12.  

What about the third case, where both parameters are arrays?

And can these three cases be generalised using generics?

Background: APL uses , for concatenation, Perl uses . and for my own domain-specific compilers I favour _ Under the circumstances, I think that Object Pascal's >< is fair game.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Warfley

  • Hero Member
  • *****
  • Posts: 1751
Re: Extending a dynamic array by one element.
« Reply #1 on: July 19, 2024, 11:20:35 pm »
Code: Pascal  [Select][+][-]
  1. {$ModeSwitch ArrayOperators}
  2.  
  3. { Append one element }
  4. arr += [element]
  5. // will be optimized to
  6. SetLength(arr, Length(arr) + 1);
  7. Arr[High(arr)] := element;
  8.  
  9. { Append Array }
  10. arr1 += arr2;
  11. // Same as Concat

There is a specific optimization for single element concatinations, so it's not just the shortest way of doing it, but also the most efficient.

Generally, don't try to be smart, let the compiler be smart for you and find the most optimal implementation

jamie

  • Hero Member
  • *****
  • Posts: 6735
Re: Extending a dynamic array by one element.
« Reply #2 on: July 19, 2024, 11:22:07 pm »
There is the "Insert" that works with dynamics.
The only true wisdom is knowing you know nothing

MarkMLl

  • Hero Member
  • *****
  • Posts: 8027
Re: Extending a dynamic array by one element.
« Reply #3 on: July 19, 2024, 11:31:53 pm »
Generally, don't try to be smart, let the compiler be smart for you and find the most optimal implementation

Which is actually the algorithm I used in my first case (of three).

However in this particular case I /am/ prepared to try to be smart, since I would like to be able to reserve the normal arithmetic operators for addition (etc.) of arrays... even without agreeing with the vituperations of certain core developers against += etc. :-)

Noting my comment on APL, I'd also remark that it allowed operations between arrays and elements (which were extended to the same length) but not normally between arrays of different length. So as such, a separate concatenation operator is highly desirable.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

silvercoder70

  • Jr. Member
  • **
  • Posts: 91
    • Tim Coates
Re: Extending a dynamic array by one element.
« Reply #4 on: July 20, 2024, 10:01:22 am »
as much as I like the idea of operators, one issue that comes to mind for me is readability and being easy to understand. Does that get lost?
Explore the beauty of modern Pascal programming with Delphi & Free Pascal - https://www.youtube.com/@silvercoder70

Thaddy

  • Hero Member
  • *****
  • Posts: 16168
  • Censorship about opinions does not belong here.
Re: Extending a dynamic array by one element.
« Reply #5 on: July 20, 2024, 10:55:49 am »
The non-feature anouncement is here:
https://wiki.freepascal.org/User_Changes_3.2.0#Operator_overload_+_no_longer_allowed_for_dynamic_arrays
Somebody was sane enough to add a modeswitch.
(Sorry Sarah, bad night, and thanks for the modeswitch)
« Last Edit: July 20, 2024, 10:58:29 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Extending a dynamic array by one element.
« Reply #6 on: July 22, 2024, 09:18:12 pm »
What about the third case, where both parameters are arrays?

Why not simply use the intrinsics that are also internally used by the operators? Namely Concat and Insert. The compiler will try to optimize these and if the compiler ever improves there your code will benefit automatically as well.

And can these three cases be generalised using generics?

Operator overloads can't be generic. They can only be indirectly generic if they're part of a generic record (but one of the operands then needs to be of the record's type).

MarkMLl

  • Hero Member
  • *****
  • Posts: 8027
Re: Extending a dynamic array by one element.
« Reply #7 on: July 22, 2024, 09:25:05 pm »
Why not simply use the intrinsics that are also internally used by the operators? Namely Concat and Insert. The compiler will try to optimize these and if the compiler ever improves there your code will benefit automatically as well.

I'm fine with that, but where do I find them documented? Via https://www.freepascal.org/docs.html I can get to Concat() for four strings ("also be used to concatenate 2 dynamic arrays") but there's nothing useful there about its being a preferred intrinsic or its behaviour when one of the parameters isn't actually a string/array.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

TRon

  • Hero Member
  • *****
  • Posts: 3623
Re: Extending a dynamic array by one element.
« Reply #8 on: July 22, 2024, 09:50:25 pm »
I'm fine with that, but where do I find them documented? Via https://www.freepascal.org/docs.html I can get to Concat() for four strings ("also be used to concatenate 2 dynamic arrays") but there's nothing useful there about its being a preferred intrinsic or its behaviour when one of the parameters isn't actually a string/array.
ATM it is not documented in the official documentation.
This tagline is powered by AI (AI advertisement: Free Pascal the only programming language that matters)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Extending a dynamic array by one element.
« Reply #9 on: July 22, 2024, 11:11:50 pm »
Why not simply use the intrinsics that are also internally used by the operators? Namely Concat and Insert. The compiler will try to optimize these and if the compiler ever improves there your code will benefit automatically as well.

I'm fine with that, but where do I find them documented? Via https://www.freepascal.org/docs.html I can get to Concat() for four strings ("also be used to concatenate 2 dynamic arrays") but there's nothing useful there about its being a preferred intrinsic or its behaviour when one of the parameters isn't actually a string/array.

For Concat the parameters need to be of the same type.
These intrinsics are implicitly preferred nowadays (since 3.2.0), because the RTL doesn't provide any other functionality for concatenation, insertion or deletion for dynamic arrays.

 

TinyPortal © 2005-2018