Discussion:
Compile time functions
(too old to reply)
J. Gareth Moreton
2018-07-28 15:48:18 UTC
Permalink
Another little progress update with implementing pure functions.
1. In my code (not submitted yet), the compiler now recognises and accepts
the 'pure' directive.  There are a number of other directives that it
can't be used with ('noreturn' being one of them) and it can't be used on
object methods.
2. A compiler hint is thrown if a function is not pure, but can definitely
be made pure. This is done via a new procinfo flag named
"pi_pure_uncertain", which is set if any loops, jumps or calls are
encountered, as well as anything that makes the function impure. If the
flag is not set when the function's node tree has been built, then it's
definitely a pure function. Note that the compiler won't start treating it
as a pure function - it only gives the hint that it could do.
3. A compiler warning is thrown if a function marked as pure tries to
access a variable whose scope falls outside of the subroutine (i.e. it's
not local).  Similar warnings are thrown if the ^ and @ operators are
used.

I haven't programmed in the actual compile-time evaluation yet because
that requires stepping through the nodes like an interpreter.  That's my
next challenge once I get the initial compilation and validation done.
Some things will take a little bit of thought.  With a pure function
calling another pure function, it's not always known if the callee is pure
at this point (e.g. with a forward declaration and/or where the 'pure'
directive only appears in the implementation section), so it will have to
come back to check it later somehow, which might be difficult if the
original pure function is being called before its own implementation (as
part of a constant assignment, for example).

Though not tested or fully validated yet, it's intended that only
floating-point and ordinal type parameters and variables are supported
initially for the sake of simplicity.  Support for record types and
strings will be a bit more complicated and something I'll do later,
assuming there's a need for more complex types in pure functions - I can
think of examples where they will, such as with "IntToStr" (when called by
another pure function) with strings, and a library of routines for handling
complex numbers, say (record type consisting of 2 Doubles).

Hopefully I can present something in the near future to be tested and
ripped apart by other developers and SQA!

Gareth aka. Kit
Sven Barth via fpc-devel
2018-07-28 17:14:14 UTC
Permalink
Post by J. Gareth Moreton
Another little progress update with implementing pure functions.
1. In my code (not submitted yet), the compiler now recognises and accepts
the 'pure' directive. There are a number of other directives that it can't
be used with ('noreturn' being one of them) and it can't be used on object
methods.
You could allow it for static class methods which don't have a Self
argument and are essentially scoped ordinary routines.

Regards,
Sven
J. Gareth Moreton
2018-07-28 16:33:54 UTC
Permalink
I did wonder about that, but wasn't sure how it would affect things where
inheritance is concerned.  I dare ask, do you have an example of a class
method that you would consider pure?

And yes, object methods can't be pure because accessing the fields of the
current object (Self) is internally dereferencing a pointer .

Gareth aka. Kit

On Sat 28/07/18 18:14 , "Sven Barth" ***@googlemail.com sent:
J. Gareth Moreton schrieb am Sa., 28. Juli 2018, 18:49:
Another little progress update with implementing pure functions.
1. In my code (not submitted yet), the compiler now recognises and accepts
the 'pure' directive.  There are a number of other directives that it
can't be used with ('noreturn' being one of them) and it can't be used on
object methods.
You could allow it for static class methods which don't have a Self
argument and are essentially scoped ordinary routines. 
Regards, Sven 
Sven Barth via fpc-devel
2018-07-28 19:37:29 UTC
Permalink
Post by J. Gareth Moreton
I did wonder about that, but wasn't sure how it would affect things where
inheritance is concerned. I dare ask, do you have an example of a class
method that you would consider pure?
They don't have inheritance. If they have the modifier "static" they really
are simply scoped functions or procedures. They can even be assigned to
non-"of object" procedure variables.

Regards,
Sven
J. Gareth Moreton
2018-07-28 20:03:34 UTC
Permalink
Aah, right.
I'm probably being rather dumb here from not having used them before, but
do you mean things like this?

type
  TNewClass = class    function Special: Boolean; static;
end;

I gather you can't access Self in such methods.

Gareth aka. Kit

On Sat 28/07/18 20:37 , "Sven Barth" ***@googlemail.com sent:
J. Gareth Moreton schrieb am Sa., 28. Juli 2018, 19:34:
I did wonder about that, but wasn't sure how it would affect things where
inheritance is concerned.  I dare ask, do you have an example of a class
method that you would consider pure?

They don't have inheritance. If they have the modifier "static" they
really are simply scoped functions or procedures. They can even be assigned
to non-"of object" procedure variables. 
Regards, Sven
Dmitry Boyarintsev
2018-07-28 22:11:39 UTC
Permalink
These are known as “class” methods (rather than “static”) in object pascal.

Thanks,
Dmitry
Post by J. Gareth Moreton
Aah, right.
I'm probably being rather dumb here from not having used them before, but
do you mean things like this?
type
TNewClass = class
function Special: Boolean; static;
end;
I gather you can't access Self in such methods.
Gareth aka. Kit
Post by J. Gareth Moreton
I did wonder about that, but wasn't sure how it would affect things where
inheritance is concerned. I dare ask, do you have an example of a class
method that you would consider pure?
They don't have inheritance. If they have the modifier "static" they
really are simply scoped functions or procedures. They can even be assigned
to non-"of object" procedure variables.
Regards,
Sven
J. Gareth Moreton
2018-07-28 21:22:21 UTC
Permalink
Aah, right.  Class methods I have used in past projects, but my
understanding is that, in these instances, Self can still be accessed, but
represents the class rather than the object, can be called without an
instantiated object, and still have the issues that they can be virtual and
overridden (something i'm disallowing with pure functions because of the
initial complexity of determining which version of a method to call).

Can you clarify, Sven, with "static" and "class"?

Gareth aka. Kit

On Sat 28/07/18 23:11 , "Dmitry Boyarintsev" ***@gmail.com
sent:
These are known as “class” methods (rather than “static”) in
object pascal.
Thanks,Dmitry

On Saturday, July 28, 2018, J. Gareth Moreton wrote:
Aah, right.
I'm probably being rather dumb here from not having used them before, but
do you mean things like this?

type
  TNewClass = class    function Special: Boolean; static;
end;

I gather you can't access Self in such methods.

Gareth aka. Kit

On Sat 28/07/18 20:37 , "Sven Barth" ***@googlemail.com sent:
J. Gareth Moreton schrieb am Sa., 28. Juli 2018, 19:34:
I did wonder about that, but wasn't sure how it would affect things where
inheritance is concerned.  I dare ask, do you have an example of a class
method that you would consider pure?

They don't have inheritance. If they have the modifier "static" they
really are simply scoped functions or procedures. They can even be assigned
to non-"of object" procedure variables. 
Regards, Sven
Thorsten Engler
2018-07-29 02:39:55 UTC
Permalink
type

TMyClass = class of TMyObject;

TMyObject = class

procedure InstanceMethod; //Self = TMyObject, can be virtual

class procedure ClassMethod; //Self = TMyClass, can be virtual

class procedure StaticClassMethod; static; //no Self, really just a global procedure in a scoped namespace

end;



var

o: TMyObject;

c: TMyClass;

begin

o.InstanceMethod; //if virtual, calls resolved based on actual class

o.ClassMethod; //if virtual calls, resolved based on actual class

o.StaticCalssMethod; //can’t be virtual, resolved on variable type



TMyObject.ClassMethod; //call resolved based on given type

TMyObject.StaticClassMethod; //call resolved based on given type



c.ClassMethod; //if virtual, calls resolved based on actual class

//haven’t tried if this one works, I assume it does:

c.StaticClassMethod; //can’t be virtual, resolved on variable type

end;



From: fpc-devel <fpc-devel-***@lists.freepascal.org> On Behalf Of J. Gareth Moreton
Sent: Sunday, 29 July 2018 07:22
To: FPC developers' list <fpc-***@lists.freepascal.org>
Subject: Re: [fpc-devel] Compile time functions



Aah, right. Class methods I have used in past projects, but my understanding is that, in these instances, Self can still be accessed, but represents the class rather than the object, can be called without an instantiated object, and still have the issues that they can be virtual and overridden (something i'm disallowing with pure functions because of the initial complexity of determining which version of a method to call).

Can you clarify, Sven, with "static" and "class"?



Gareth aka. Kit


On Sat 28/07/18 23:11 , "Dmitry Boyarintsev" ***@gmail.com <mailto:***@gmail.com> sent:

These are known as “class” methods (rather than “static”) in object pascal.



Thanks,

Dmitry

On Saturday, July 28, 2018, J. Gareth Moreton <***@moreton-family.com <javascript:top.opencompose('***@moreton-family.com','','','')> > wrote:

Aah, right.



I'm probably being rather dumb here from not having used them before, but do you mean things like this?

type
TNewClass = class

function Special: Boolean; static;

end;


I gather you can't access Self in such methods.

Gareth aka. Kit


On Sat 28/07/18 20:37 , "Sven Barth" ***@googlemail.com <javascript:top.opencompose('***@googlemail.com','','','')> sent:

J. Gareth Moreton <***@moreton-family.com <mailto:***@moreton-family.com> > schrieb am Sa., 28. Juli 2018, 19:34:

I did wonder about that, but wasn't sure how it would affect things where inheritance is concerned. I dare ask, do you have an example of a class method that you would consider pure?



They don't have inheritance. If they have the modifier "static" they really are simply scoped functions or procedures. They can even be assigned to non-"of object" procedure variables.



Regards,

Sven
Sven Barth via fpc-devel
2018-07-29 07:14:41 UTC
Permalink
Post by Thorsten Engler
type
TMyClass = class of TMyObject;
TMyObject = class
procedure InstanceMethod; //Self = TMyObject, can be virtual
class procedure ClassMethod; //Self = TMyClass, can be virtual
class procedure StaticClassMethod; static; //no Self, really just a
global procedure in a scoped namespace
end;
var
o: TMyObject;
c: TMyClass;
begin
o.InstanceMethod; //if virtual, calls resolved based on actual class
o.ClassMethod; //if virtual calls, resolved based on actual class
o.StaticCalssMethod; //can’t be virtual, resolved on variable type
TMyObject.ClassMethod; //call resolved based on given type
TMyObject.StaticClassMethod; //call resolved based on given type
c.ClassMethod; //if virtual, calls resolved based on actual class
c.StaticClassMethod; //can’t be virtual, resolved on variable type
end;
@Gareth: And I mean the StaticClassMethod here.

Regards,
Sven
J. Gareth Moreton
2018-07-29 13:28:28 UTC
Permalink
Thanks everyone! I'm still learning some parts of Pascal!  I'll see if I
can accommodate for that.

Gareth aka. Kit

On Sun 29/07/18 08:14 , Sven Barth via fpc-devel
fpc-***@lists.freepascal.org sent:
Thorsten Engler schrieb am So., 29. Juli 2018, 04:40:

type

  TMyClass = class of TMyObject;

  TMyObject = class

    procedure InstanceMethod; //Self = TMyObject, can be virtual

    class procedure ClassMethod; //Self = TMyClass, can be virtual

    class procedure StaticClassMethod; static; //no Self, really just a
global procedure in a scoped namespace

  end;

 

var

  o: TMyObject;

  c: TMyClass;

begin

  o.InstanceMethod; //if virtual, calls resolved based on actual class

  o.ClassMethod; //if virtual calls, resolved based on actual class

  o.StaticCalssMethod; //can’t be virtual, resolved on variable type

 

  TMyObject.ClassMethod; //call resolved based on given type

  TMyObject.StaticClassMethod; //call resolved based on given type

 

  c.ClassMethod; //if virtual, calls resolved based on actual class

  //haven’t tried if this one works, I assume it does:

  c.StaticClassMethod; //can’t be virtual, resolved on variable type

end; @Gareth: And I mean the StaticClassMethod here. 
Regards, Sven  _______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org [2]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[3]">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



Links:

Loading...