[fpc-devel] va(r)_arg vs open array

ik idokan at gmail.com
Tue Oct 3 12:41:39 CEST 2006


On 10/2/06, Daniël Mantione <daniel.mantione at freepascal.org> wrote:
>
>
> Op Mon, 2 Oct 2006, schreef ik:
>
> > > Well, I think that this is also a functional thing.
> > >
> > > >
> > > > * Syntactically, both methods can be safe.
> > > > * Syntactically, the FPC/Delphi one is more powerfull.
> > >
> > > Well take a look at the way Java implement it:
> > >
> > > .... function varrags(String ... a)
> > > {
> > >    for (int i = 0; i<= a.length; i++)
> > >    {
> > >       a[i] ...
> > >    }
> > > }
> > >
> > > varags(a,b,c,d,e,f,g);
> > >
> > > The thing I wish that you'll see is that here it's pure array like in
> > > Pascal, but the array is part of the content of the function and not
> > > part of the parameter usage ... (I can btw also use different types,
> > > so we solve the problem of unsafe types).
>
> You can have an array with a multitude of types in Java, but in Pascal
> this is not possible in Pascal. I.e. translating it to Pascal could be:
>
> 1  procedure varargs(a:...);
> 2
> 3  begin
> 4    for i:=low(a) to high(a) do
> 5      writeln(a[i]);
> 6  end;
> 7
> 8  begin
> 9   varargs(0.0, at varargs,[1,2,3],true);
> 10 end.
>
> In Pascal the combination of line 5 and line 9 is unacceptable. We are a
> strongly typed language with static types. C can accept it because it is
> type unsafe. Java can accept it because the types are determined at
> runtime, with a big speed penalty of course.
>
> A variant record is the proper solution. If you expect numbers, you access
> the Vinteger field. Expect a boolean? Use the Vboolean field. As a bonus,
> you can check the types of the parameters passed, and check them at
> runtime for extra safety.
>
> > > BTW in perl every group of scalars are actually an array... there is
> > > no difference .
>
> Perl has no static typing.
>
> > > > > The [] is the same as "InitbyObject". It's informative, but not really
> > > needed.
> > > >
> > > > The [] is the mechanism that allows you to pass multiple arrays.
> > >
> > > I don't understand what you mean :(
>
> Multiple arrays is not possible in C:
>
> procedure write_list_row(const fields:array of string;const widths:array of byte);
>
> begin
>   assert(high(fields)=high(widths);
>
>   for i:=low(fields) to high(fields)
>     writeln(fields[i]:widths[i]);
> end;
>
> begin
>   write_list_row(['Language','Strong/weak','dynamic/static'],[20,15,15]);
>   write_list_row(['Pascal','strong','static'],[20,15,15]);
>   write_list_row(['C','weak','static'],[20,15,15]);
>   write_list_row(['Java','strong','dynamic'],[20,15,15]);
> end;
>
> This can be achieved thanks to the [].

You are welcome to correct me, but I can pass an array as parameter to
C, but as a pointer ...

>
> > > > > Cool, but if you want to do better, then lets get one step further and
> > > > > say that nil value does not need to be "0 amount of values" in the
> > > > > parameter usage itself. Why not just to check
> > > > >
> > > > > if (not openarray = nil) then ...
> > > > >
> > > > > ?
> > > >
> > > > Huh, I don't understand this?
> > >
> > > If I will not add any parameter, I could check inside the function if
> > > the parameter is initilized rather then checking for length, so []
> > > will be for 0 items while, no "[]" will be no parameters at all.
>
> Not possible. The array is can be passed by value. It is the same thing
> that in "procecure x(y:byte)" variable y is mandatory, there is no way you
> can pass nothing.
>
> > > > Well, if it were to the Free Pascal developers, there would be no
> > > default
> > > > values at all :) We heavily grumbled when we had to implement it to be
> > > > Delphi compatible.
> > >
> > > But we can see how good and helpful it is and can accept it :)
>
> No, it sucks big time, IMHO. It is one the VB things Borland should not
> have put into Delphi. We've always had the opinion that an overload is the
> proper solution.

I find it helpful, for example:

function getRange (const S : string; Start, End : integer; i : integer
= 0) : integer;
function getRange (const S : string; Start, End : integer; f :
extended = 0.0) : extended;
function getRange (const S : string; Start, End : integer; s :
string='') : string;
...

Unless there is a magic to overload by return value, this way I can
solve the problem of overloading, so it is useful, and I can find
places I can use it. Other way to do the same will be to create
different name for each function. Well it is possible, but what is
easier to remember getRange or getRangeI getRangeF getRangeS etc. ? It
also less writing here for the use of the functions, and this less
writing make it easier to use the function removing the need to
remember "what do I actually need a float or an integer ?", when
sometimes the answer is not that simple ... But it also have a down
side, and that's to debug it and see what is the correct function that
in use. So there are no pros without cons .

>
> > > With an integer parameter, you can place "0" for example as default
> > > parameter, so with open array, you could also place default paramters,
> > > when #0 was just an example for that.
>
> Sure, we can implement that. But we are no fans of default parameters, and
> you have to stop somewhere, i.e. you want to avoid people putting complete
> constant record definitions in a procedure header. Simple types only.

Cool, sounds good reason for me :) I'll take this one back.

>
> > > > > > > 5. Feel like an hack.
> > > > > >
> > > > > > Where do you get that feeling?
> > > > >
> > > > > "OK, so I don't have a way to make a compiler voodoo magic, but I can
> > > > > use an open array to get the closer feeling", but as Daniel say, in
> > > > > order to complete the usage of such thing, I need a synthetic sugar,
> > > > > and that does not implemented... It does not feel native ... it feels
> > > > > like a patch/hack that was added to shout people up when they say "you
> > > > > do not have var args".
> > > >
> > > > On the contrary. I think we can consider constant arrays native? Then
> > > > there is nothing about bad about reusing the principle. IMHO. Feel free
> > > to
> > > > differ, but I consider the [] solution much more elegant than the C
> > > > varargs.
> > >
> > > Yes and no, it is more elegant, but with few prices ...
>
> There is a price, and that is that FPC pushes the type of the parameter,
> instead of just the value. I'll stick my fingers in my ears until I hear
> someone complaining that his code is too slow because of that :P
>
> > > > Actually I agree with you here.
> > >
> > > Finally :) What does it take to make it non object oriented thingy,
> > > that is, it can be used on $MODE FPC ?
>
> See thread "Suggestion for change". Propose it, defend that it is
> necessary. If you can defend it, I'll enable it.

The only thread I can find about the subject is "Suggestion for
change: Overly strict check" should I open a "bug" report of request a
feature for that ?

>
> > > > > Back in the Delphi2-3 days (maybe its till exists), there was a hack
> > > > > that if a variable is from a range of 000000..111111 it is an integer,
> > > > > if the range of the memory is 222222..333333 the variable is float, if
> > > > > it's AAAAAA..FFFFFF it's a class etc.. you don't expect any developer
> > > > > to go that law to know such things ... specially, that it is not a
> > > > > constant thing on every OS and arch .
> > > >
> > > > Huh?!! Again I am lost.
> > >
> > > I'd seen hacks to find what is the parameter type (in delphi), by
> > > getting the memory address of that paramter, and the position inside a
> > > range of memory that the parameter located at, reprisent the type of
> > > that parameter.
>
> ??? Why would that be necessary? You need it in C, but in FPC/Delphi, the
> type is in the varrec.
>
> > > > > So how good are we then the C developers, that pointers are like air
> > > > > to them, even on places no other language really needs them (including
> > > > > c++) ?
> > > > >
> > > > > "Maybe we should use object like variable types ?" (don't even bother
> > > > > to answer, I don't want such a thing)
> > > >
> > > > I don't think there is an alternative here. If you would pass an array
> > > of
> > > > pointers, you would get into trouble when passing integers. (Pascal
> > > > is type safe.) Record variants are the only sensible solution.
> > >
> > > I do not like variants. They are very memory weasting type, and most
> > > of the time operator overloading might make a better job.
>
> Hola, do not confuse variants with variant records. A variant is this:
>
> var a:variant;
>
> ... and is such a memory weasting thing, but a variant record is this:
>
> type t=record
>        case boolean of
>          false:(p:longint);
>          true:(p:pointer)';
>      end;
>
> ... which doesn't waste a single byte.

Thanks for clearing it out for me :) I know this as a union (well
actually now that I think on that, I forgot about it, when I stopped
working with Delphi 4 years ago, and I had only variant as a type in
my head).

>
>
> Daniël
>


More information about the fpc-devel mailing list