Recent

Author Topic: A suggestion for a new FPC feature  (Read 6709 times)

Thaddy

  • Hero Member
  • *****
  • Posts: 9167
Re: A suggestion for a new FPC feature
« Reply #30 on: June 25, 2019, 01:07:25 pm »
 :D Looks even better... 8-)
Doesn't need to be added: to the language perse:
Code: Pascal  [Select]
  1. {$macro on}{$define union:=record}

But anyway: I think my syntax is more clear, because it identifies union members of records as union, with the possibility to add non-union members.
After all, unions are part of a record. Unless - what I wrote - they are declared first and are strict variant records to be used as members in subsequent records.

That's basically how I always do it, with the exception of that little eye candy macro.... :P

You really can construct a 1-1 memory lay-out compared to C syntax, although more verbose, which is good. That has always been the case.
« Last Edit: June 25, 2019, 01:19:01 pm by Thaddy »
also related to equus asinus.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: A suggestion for a new FPC feature
« Reply #31 on: June 25, 2019, 01:19:09 pm »
PChar and dynamic arrays are stored in memory with a 32-bit integer at [-1] that denotes the actual length. For PChar that is invisible, as their length should be decided by the first #0 char. But that means that the compiler can treat a PChar as a regular one.

So, a struct like this:

Code: C  [Select]
  1. typedef struct {
  2.   GUID  PowerSetting;
  3.   DWORD DataLength;
  4.   UCHAR Data[1];
  5. }

is actually how you would convert a dynamic Pascal array to C...  :o


For comparison, the last large project I worked on (bug fixing) was written in C++, and fully static. No dynamic memory at all. There was this huge struct filled with other nested structs, that was written as-is from memory to disk and vice versa. Just save 1 record of size sizeof() to disk, or take the global pointer and load that amount of bytes into it. Oh, yes, did I mention that everything was defined globally?

And with each new version , new stuff was added. To the end of the file, of course. And if you changed any of the record packing settings, everything stopped working. You couldn't actually reference any of the structs inside, as their location and size was defined by the version of the program. It was a lot of fun making bugfixes for that...

And all of you say: "Well, of course that should be possible to do in FPC as well, because some programs work like that and we should be able to communicate with that." Instead of the sane approach: writing in/export functions.
« Last Edit: June 26, 2019, 01:05:47 pm by SymbolicFrank »

Thaddy

  • Hero Member
  • *****
  • Posts: 9167
Re: A suggestion for a new FPC feature
« Reply #32 on: June 25, 2019, 01:45:14 pm »
That is simply not correct SymbolicFrank,

A C union size is determined - as I already explained - by its largest member.
That's what we are talking about: the union does not even contain a length size.....

See https://en.wikipedia.org/wiki/Union_type
also related to equus asinus.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: A suggestion for a new FPC feature
« Reply #33 on: June 25, 2019, 02:08:19 pm »
That is simply not correct SymbolicFrank,

A C union size is determined - as I already explained - by its largest member.
That's what we are talking about: the union does not even contain a length size.....

See https://en.wikipedia.org/wiki/Union_type

What I wrote is correct, and it wasn't in response to something you said. It wasn't about unions, either.

PascalDragon

  • Hero Member
  • *****
  • Posts: 668
  • Compiler Developer
Re: A suggestion for a new FPC feature
« Reply #34 on: July 02, 2019, 09:45:43 am »
PChar and dynamic arrays are stored in memory with a 32-bit integer at [-1] that denotes the actual length. For PChar that is invisible, as their length should be decided by the first #0 char. But that means that the compiler can treat a PChar as a regular one.

So, a struct like this:

Code: C  [Select]
  1. typedef struct {
  2.   GUID  PowerSetting;
  3.   DWORD DataLength;
  4.   UCHAR Data[1];
  5. }

is actually how you would convert a dynamic Pascal array to C...  :o

You're wrong. PChar does not have any length at the front, it's simply a pointer to a memory with characters with the first #0 denoting the end.
Just take a look at this:
Code: Pascal  [Select]
  1. var
  2.   Test: PChar = 'Blubb';
  3. begin
  4. end.
The corresponding assembly code looks like this:
Code: [Select]
.section .rodata.n_.Ld1,"d"
.balign 8
.Ld1:
# [24] Test: PChar = 'Blubb';
.ascii "Blubb\000"

Also dynamic arrays contain not the length, but the high index as well as a reference count. And if you put a dynamic array into a record the record will only contain a reference to that dynamic array, not the dynamic array itself, so the structure you quoted is not a 1:1 equivalent to
Code: Pascal  [Select]
  1. TMyRecord = record
  2.   PowerSetting: TGUID;
  3.   Data: array of UCHAR;
  4. end;

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7499
Re: A suggestion for a new FPC feature
« Reply #35 on: July 02, 2019, 11:00:43 am »
I'd be careful to expand on anonymous functions. It is very limited.

It is one of the few pascal features that regularly bite me.

A typical template that goes wrong is:

Code: Pascal  [Select]
  1. procedure  tsomethread.queueit(const msgtypes : array of integer);
  2. var msg : Tsomemessage;
  3.      i :integer;
  4. begin
  5.   for i:=0 to high(msgtypes) do
  6.      begin
  7.         msg:=translate(msgtypes[i]);
  8.         queue(procedure
  9.                     begin
  10.                      callwithmessasage (msg);
  11.                    end
  12.                  );
  13.      end;
  14. end;
  15.  
  16.  

Can you spot the problem?
« Last Edit: July 02, 2019, 11:03:39 am by marcov »

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: A suggestion for a new FPC feature
« Reply #36 on: July 02, 2019, 12:53:16 pm »
Ok, I'll bite. I got the other stuff wrong, so I probably don't get this one either.

Msg is in scope. On the one hand, the variable msg changes every loop, but on the other hand the parameter msg should be copied. As the anonymous function isn't executed immediately, it stores msg as a field, according to the explanation of PascalDragon, and the procedure is stored in queue for later use. So they should all have their own copy.

I don't see it.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7499
Re: A suggestion for a new FPC feature
« Reply #37 on: July 02, 2019, 01:20:36 pm »
Ok, I'll bite. I got the other stuff wrong, so I probably don't get this one either.

Msg is in scope. On the one hand, the variable msg changes every loop, but on the other hand the parameter msg should be copied. As the anonymous function isn't executed immediately, it stores msg as a field, according to the explanation of PascalDragon, and the procedure is stored in queue for later use. So they should all have their own copy.

I don't see it.

That is what you would expect indeed, but not how it works, a reference to msg is stored, not msg itself. This can be changed by making msg a parameter to the anonymous function, but then that doesn't match the signature of queue(). And queue (and synchronize to a less degree, I hardly use that nowadays) are my main usecase for anonymous functions.


SymbolicFrank

  • Hero Member
  • *****
  • Posts: 635
Re: A suggestion for a new FPC feature
« Reply #38 on: July 02, 2019, 01:41:09 pm »
Ah, yes, it's not a parameter of the anonymous function, but of the called function.

Things like this are why I always try to program as I would in Pascal, no matter the language. If my co-workers allow it, of course.

PascalDragon

  • Hero Member
  • *****
  • Posts: 668
  • Compiler Developer
Re: A suggestion for a new FPC feature
« Reply #39 on: July 03, 2019, 01:54:19 pm »
Ok, I'll bite. I got the other stuff wrong, so I probably don't get this one either.

Msg is in scope. On the one hand, the variable msg changes every loop, but on the other hand the parameter msg should be copied. As the anonymous function isn't executed immediately, it stores msg as a field, according to the explanation of PascalDragon, and the procedure is stored in queue for later use. So they should all have their own copy.

I don't see it.
The internal state object is shared for all anonymous functions created inside a function. So they all will have the same reference to msg.

I'd be careful to expand on anonymous functions. It is very limited.

It is one of the few pascal features that regularly bite me.

A typical template that goes wrong is:

Code: Pascal  [Select]
  1. procedure  tsomethread.queueit(const msgtypes : array of integer);
  2. var msg : Tsomemessage;
  3.      i :integer;
  4. begin
  5.   for i:=0 to high(msgtypes) do
  6.      begin
  7.         msg:=translate(msgtypes[i]);
  8.         queue(procedure
  9.                     begin
  10.                      callwithmessasage (msg);
  11.                    end
  12.                  );
  13.      end;
  14. end;
  15.  
  16.  

Can you spot the problem?
That was another thing I wanted to experiment with using the lambda syntax: have variables by default be copies instead of references and have references declared explicitly like this:
Code: Pascal  [Select]
  1. lambda (...) with var x as inc(x)
The with ... clause could be used to declare variables as by reference instead of by value.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 5695
    • wiki
Re: A suggestion for a new FPC feature
« Reply #40 on: July 03, 2019, 02:45:48 pm »
That was another thing I wanted to experiment with using the lambda syntax: have variables by default be copies instead of references and have references declared explicitly like this:
Code: Pascal  [Select]
  1. lambda (...) with var x as inc(x)
The with ... clause could be used to declare variables as by reference instead of by value.

IMHO The lambda syntax is so not Pascal.

Personally I am contra the whole inline declaration. But if needs must be...

1) About copy vs ref
My proposal:
Code: Pascal  [Select]
  1. queue(
  2.   procedure
  3.   var msg: string = msg;
  4.   begin
  5.     callwithmessasage (msg);
  6.   end
  7. );
  8.  
Using entirely existing syntax.
"msg" in the right hand expression of the var block, refers to the outer "msg".

2)  Just because every other language forgets to distinguish between a "closure" and an "inline declaration", do we need to do the same? After all Pascal is about expressing things more clearly.
A closure (no matter if declared inline, or as a nested proc) should be marked as such by an appropriate keyword/modifier.
« Last Edit: July 03, 2019, 02:47:25 pm by Martin_fr »

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7499
Re: A suggestion for a new FPC feature
« Reply #41 on: July 03, 2019, 03:10:16 pm »
I don't like the lamba either (and the inferring of variables even less).

But the trouble is indeed that the delphi syntax only allows to specify how to catch variables by making them parameters, but that hits the signature.  Syntax wise, some way to mark values are byvalue would be enough, and martin's syntax is not bad.
« Last Edit: July 03, 2019, 03:11:49 pm by marcov »

fcu

  • New Member
  • *
  • Posts: 41
Re: A suggestion for a new FPC feature
« Reply #42 on: July 03, 2019, 04:54:03 pm »
off topic  :-\
i was always confusing about the range declaration in the array
in c it looks resonable
Code: C  [Select]
  1.  #define ARRAY_MAX 16
  2.  int int_array[ARRAY_MAX]
  3.  
i hope fpc team think about it
Code: Pascal  [Select]
  1. const ARRAY_MAX = 16;
  2. var int_array : array[ARRAY_MAX] of longint; // looks nice without 0 and ARRAY_MAX-1
  3.  


howardpc

  • Hero Member
  • *****
  • Posts: 3177
Re: A suggestion for a new FPC feature
« Reply #43 on: July 03, 2019, 05:41:48 pm »
In Pascal you can of course write
Code: Pascal  [Select]
  1. const
  2.   ArrayHigh = 15;
  3. type
  4.   TArrayRange = 0..ArrayHigh;
  5. var
  6.   int_array: array[TArrayRange] of LongInt;

fcu

  • New Member
  • *
  • Posts: 41
Re: A suggestion for a new FPC feature
« Reply #44 on: July 03, 2019, 06:25:01 pm »
In Pascal you can of course write
Code: Pascal  [Select]
  1. const
  2.   ArrayHigh = 15;
  3. type
  4.   TArrayRange = 0..ArrayHigh;
  5. var
  6.   int_array: array[TArrayRange] of LongInt;

but it becomes worse
i talking about less typing