[fpc-pascal] Named optional arguments

Sven Barth pascaldragon at googlemail.com
Sat Nov 27 11:03:01 CET 2021


Am 27.11.2021 um 03:32 schrieb Ryan Joseph via fpc-pascal:
>
>> On Nov 26, 2021, at 4:20 PM, Ryan Joseph <genericptr at gmail.com> wrote:
>>
>> It's mainly useful when reading code so you don't need to review the function definition, using code tools or any other method. I've been enjoying it in other languages when it's not compulsory and FPC already supports the syntax so I thought it would be low hanging fruit.
> I wanted to add a little case study from the compiler itself to see how to make some really long function more readable.
>
> 1) Original form (the compiler doesn't use spaces between punctuation). Very difficult to read if nothing else because the lack of spaces but it's also not clear at all which params are which. Even code tools are going to not help very much unless they can hilight the parameters in the editor. Either way you're going to be spending time try to figure this one out.
>
> candidates:=tcallcandidates.create(symtableprocentry,symtableproc,left,ignorevisibility,
>    not(nf_isproperty in flags),cnf_objc_id_call in callnodeflags,cnf_unit_specified in callnodeflags,
>    callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],cnf_anon_inherited in callnodeflags,spezcontext);
>
> 2) Adding some line breaks helps a lot but it's still not clear what some of the params are unless you jump to the function definition or get a tool tip on the constructor and then even so you need to count the params to see which is which, and this takes time and effort.
>
> candidates:=tcallcandidates.create(symtableprocentry,
>                                                              symtableproc,
>                                                              left,
>                                                              ignorevisibility,
>                                                              not(nf_isproperty in flags),
>                                                              cnf_objc_id_call in callnodeflags,
>                                                              cnf_unit_specified in callnodeflags,
>                                                              callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],
>                                                              cnf_anon_inherited in callnodeflags,
>                                                              spezcontext);
>
> 3) Clearly defined names each on their own line is obviously the easiest to read at a glance. Even if no line breaks were present the editor could style the param names a different color and they would be easy to read.
>
> candidates:=tcallcandidates.create(sym:=symtableprocentry,
>                                                              st:=symtableproc,
>                                                              ppn:=left,
>                                                              ignorevisibility:=ignorevisibility,
>                                                              allowdefaultparas:=not(nf_isproperty in flags),
>                                                              objcidcall:=cnf_objc_id_call in callnodeflags,
>                                                              explicitunit:=cnf_unit_specified in callnodeflags,
>                                                              searchhelpers:=callnodeflags*[cnf_anon_inherited,cnf_inherited]=[],
>                                                              anoninherited:=cnf_anon_inherited in callnodeflags,
>                                                              spezcontext:=spezcontext);

The use case is irrelevant, because

a) if named arguments would be used in the compiler it would be used as

candidates:=tcallcandidates.create(sym:=symtableprocentry, 
st:=symtableproc,ppn:=left, 
ignorevisibility:=ignorevisibility,allowdefaultparas:=not(nf_isproperty 
in flags),objcidcall:=cnf_objc_id_call in 
callnodeflags,explicitunit:=cnf_unit_specified in 
callnodeflags,searchhelpers:=callnodeflags*[cnf_anon_inherited,cnf_inherited]=[], 
anoninherited:=cnf_anon_inherited in 
callnodeflags,spezcontext:=spezcontext);

So you've gained *nothing*.

b) more often then not you need to look at the declaration or even the 
implementation anyway to know what the function is doing or expecting 
due the lack of up-to-date and complete documentation

Regards,
Sven


More information about the fpc-pascal mailing list