Forum > Suggestions

Proposal: Record Composition

<< < (2/7) > >>

Fibonacci:
+1

Its essentially anonymous records many ppl asked for, but with addition of including other named records.

An exmaple of how PEB structure may benefit from your Record Composition. Part of the PEB record contains:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---_PEB = packed record  // (...)  a: packed record  case byte of    0: (KernelCallbackTable: Pointer;);    1: (UserSharedInfoPtr: Pointer;);  end; 
Need to call
PEB.a.KernelCallbackTable

With your modification
   

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---_PEB = packed record  // (...)  uses packed record  case byte of    0: (KernelCallbackTable: Pointer;);    1: (UserSharedInfoPtr: Pointer;);  end;
Here it would be just
PEB.KernelCallbackTable

So full PEB record would be visible in IDE after typing PEB<dot>

PEB.BeingDebugged
instead of
PEB.byteBools.BeingDebugged

PEB.IsLongPathAwareProcess
instead of
PEB.byteBools.BitField.IsLongPathAwareProcess

Curt Carpenter:
It appears to me to be writer-friendly, but, like so much from C, not really an improvement to reader friendliness.  And wasn't the later part of the basic philosophy that led to pascal?  (I realize that tools can make complex structures more transparent to the reader.)

Warfley:
I would actually argue it's the other way around, it's easier to read then to write. Because when you use a record that has some composite fields, you can use all those fields without needing to know how the record is made up internally. On the other hand, now when writing the record it get's harder because you need to know whenever you can change a record you must keep in mind that it may create field collisions with other records that are composited together.

To give you an example where this may be useful, one of my goto projects for trying out a bit more low level programming (especially when learning a new low level language) is writing an emulator, usually for the original Nintendo Gameboy. This system has a few 8 bit registers, A, B, C, D, E, F, H ,L as well as the 16 bit registers AF, BC, DE, HL. As these names imply these registers are just overlays over the 8 bit registers.
But when you read the manual of the gameboy, for all the opcodes and operations they are described as if they are just registers that happen to share the memory with the 8 bit registers.

So when you look at the manual, and it states that the operation for the opcode 0x02 is LD A -> (BC), writing:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---RAMState[CPURegs.BC] := CPURegs.A;is much more concise and easier to understand than having to go over a seperate hop:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---MemState[CPURegs.BC.Reg16] := CPURegs.AF.Reg8[0];It allows you to much closer follow the manual and having the code being easy to map onto these constructs.

Of course this is kinda a low level feature, and you probably won't see it being used very commonly in most programs, but when writing such things as an emulator, a network protocol or an interface to some C library, this can make your code much cleaner, as your code can cleanly follow the high level descriptions of the reference material, rather than having to follow your internal representation of the data.

I also wouldn't consider it a typical C feature, as it was added to C only very recently (2011), and  it's kindof a generalization of the variant record feature of Pascal. So it is arguably a very pascallian feature, that C took from pascal (well I think D was the first C ancestor to adopt it and C adopted it then from D), they just lifted the restrictions of variant parts being only at the end of a record and generalized it to any struct or Union at any place.

Lulu:
a quick comment:
from my Pascal-loving amateur point of view, who doesn't see the possible problems this could cause, at first glance I understood what Warfley was proposing, and, I must say, I can even visualize how I'll integrate it into my future codes!  :)

Warfley:
A minor update, just fixed it to also work with generics, now the following is possible:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  generic TComposed<T> = record    uses child: T;    B: Double;  end;

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version