Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2010-01

FPC class syntax was extended to support delphi code

17 messages · 11 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Paul Ishenin

Hello, FPC-Pascal users discussions

I want to notify you that fpc trunk has extensions for the class syntax.

Class can have now the next sections:

1. 'var' sections to start regular fields declaration. 'var' can be used after other sections and after methods
2. 'class var' sections to start static fields declaration. Fields delcared in the 'class var' section are static fields
3. 'type' sections to declare types local to a class. It is allowed now to declare nested classes too.
4. 'const' section to declare constants local to a class.
5. 'class property' - similar to regular property but works with static fields and methods

Some examples:
http://wiki.lazarus.freepascal.org/class_extensions_examples

Please test and report bugs found.

Best regards,
Paul Ishenin.

David Emerson
to Paul Ishenin: Hello, FPC-Pascal users discussions I want to notify you that fpc trunk has extensions…

Thank you for this message! This stuff sounds really cool. In particular, I have been itching for class constants.

A few questions come to mind:

a. 'var' sections -- I assume that 'var' is optional when declaring fields that occur first (i.e. directly after "private", "public", etc)

b. What does "strict private" mean, as opposed to private without strict? (My best guess is that it would be accessible only within the methods+properties of that class within the unit, as opposed to being available anywhere in the same unit where the class is declared...???)

c. What is the purpose of a class method? It would seem to me that methods should do the same thing whether they are class methods or not. Traditional variables change from instance to instance, but methods do not vary between instances, as far as I know-- right?

d. What happens with inheritance?

d.1. wrt class constants and class vars-- are there separate "instances" (for lack of a better word) of these, one instance for each descendant? Or is the class var/const only stored once for the ancestor that declares it, and all descendants share that?

d.2. wrt class methods, can they be virtual? (This strikes me as being closely related to d.1)

I guess an example is in order for d:

type
  t_parent = class
  private
    class var
      x : integer;
    const
      c = 5;
  end;
  t_child = class (t_parent)
  private
    const
      c = 7;  // can I do this?
  end;

If I change t_child.x will it change t_parent.x?

e. Is it available in {$mode objfpc}? (I hope I hope I hope)?

I'd love to test this stuff out, though I usually stick with release versions... perhaps this is what is needed for me to take the plunge! Either way, I'm looking forward to this being released. Great work.

Cheers,
David

Paul Ishenin wrote
Hello, FPC-Pascal users discussions I want to notify you that fpc trunk has extensions for the class

syntax.

Class can have now the next sections: 1. 'var' sections to start regular fields declaration. 'var' can be

used

after other sections and after methods 2. 'class var' sections to start static fields declaration. Fields delcared in the 'class var' section are static fields 3. 'type' sections to declare types local to a class. It is allowed

now

to declare nested classes too. 4. 'const' section to declare constants local to a class. 5. 'class property' - similar to regular property but works with

static

Show quoted text 13 lines
fields and methods Some examples: http://wiki.lazarus.freepascal.org/class_extensions_examples Please test and report bugs found. Best regards, Paul Ishenin. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Doug Chamberlin
to David Emerson
David Emerson wrote
b. What does "strict private" mean, as opposed to private without strict? (My best guess is that it would be accessible only within the methods+properties of that class within the unit, as opposed to being available anywhere in the same unit where the class is declared...???)

In Delphi what you have described is exactly what strict private gives you.

c. What is the purpose of a class method? It would seem to me that methods should do the same thing whether they are class methods or not. Traditional variables change from instance to instance, but methods do not vary between instances, as far as I know-- right?
Class methods allow you to call the method without instantiating the
class first. For example, Result := TMyClass.MyClassFunction;
Doug C. ----- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
David Emerson
to Doug Chamberlin
Doug Chamberlin wrote
Class methods allow you to call the method without instantiating the class first. For example, Result := TMyClass.MyClassFunction;

Oh, that is so cool! I suppose that probably means that class methods can only reference class variables/methods/properties.

Cheers,
David

Doug Chamberlin
to David Emerson
David Emerson wrote 6 lines
Doug Chamberlin wrote: > Class methods allow you to call the method without instantiating the > class first. For example, Result := TMyClass.MyClassFunction; Oh, that is so cool! I suppose that probably means that class methods can only reference class variables/methods/properties.

Yup!

Of course, there are pros and cons to all this. Our once simple, straightforward language is not littered with "convenience" features that are not example, what is the big advantage of class methods over simple functions and procedures?

Doug C. ----- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
Anthony Walter
to Doug Chamberlin
Show quoted text 8 lines
Yup! Of course, there are pros and cons to all this. Our once simple, straightforward language is not littered with "convenience" features that are not example, what is the big advantage of class methods over simple functions and procedures?

Class methods can be virtual and have access to other (perhpas protected) class members of the class.

type
  TA = class
  public
    class procedure Hello; virtual;
  end;
  TB = class(TA)
  public
    class procedure Hello; override;
  end;
  TAClass = class of TA;

{ TA }

class procedure TA.Hello;
begin
  ShowMessage('Hello this is ' + ClassName); // see I can access ClassName
end;

{ TB }

class procedure TB.Hello;
begin
  inherited Hello;
  ShowMessage('A different message here');
end;

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  SomeClass: TAClass;
begin
  SomeClass := TB;
  SomeClass.Hello;
end;
Aleksa Todorovic
to David Emerson: Thank you for this message! This stuff sounds really cool. In particular, I have been…
David Emerson wrote
d.2. wrt class methods, can they be virtual? (This strikes me as being closely related to d.1)

Definitely, yes! (and I believe that was available before class vars/consts) I use this great feature for (de)serialization of messages in my client/server communication:

  TMessage = class
  public
    constructor Create; virtual;
    class function GetCode: Word; virtual;
    Code: Word;
    ...
  end;
constructor TMessage.Create;
begin
  Code := GetCode;
end;

So, when I want to create new message, I just call TLoginMessage.Create or TChatMessage.Create or whatever (those classes override GetCode, and everything works perfect).

Cox, Stuart TRAN:EX
to Doug Chamberlin: Yup! Of course, there are pros and cons to all this. Our once simple, straightforward…
Show quoted text 20 lines
-----Original Message----- From: On Behalf Of Doug Chamberlin Sent: Wednesday, January 13, 2010 11:21 AM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] FPC class syntax was extended to support delphi code David Emerson wrote: > Doug Chamberlin wrote: >> Class methods allow you to call the method without instantiating the >> class first. For example, Result := TMyClass.MyClassFunction; > > Oh, that is so cool! I suppose that probably means that class methods > can only reference class variables/methods/properties. Yup! Of course, there are pros and cons to all this. Our once simple, straightforward language is not littered with "convenience" features that are not example, what is the big advantage of class methods over simple functions and procedures?

Some operations (procedures/functions) just go naturally with Classes but don't belong to any particular instance of that class. An example might be calculating the area of overlap between two geographic polygons (instances of the class) where the function returning the overlap area is a class function rather than an instance function/method of either of the two polygons. Contrived, but imaginable.

Show quoted text 10 lines
-- Doug C. ----- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail? _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Doug Chamberlin
to Cox, Stuart TRAN:EX: Some operations (procedures/functions) just go naturally with Classes but don't belong to…
Some operations (procedures/functions) just go naturally with Classes but don't belong to any particular instance of that class. An example might be calculating the area of overlap between two geographic polygons (instances of the class) where the function returning the overlap area is a class function rather than an instance function/method of either of the two polygons. Contrived, but imaginable.

Oh, I can imagine such methods also. And I've used them before. I just don't see the big advantage over having them be global functions/procedures located in the same unit as the class they operate on. So, as often as not, I go and create the global functions instead. Never could decide either way to go.

Doug C. ----- A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? A: Top-posting. Q: What is the most annoying thing in e-mail?
Paul Ishenin
to David Emerson: Thank you for this message! This stuff sounds really cool. In particular, I have been…
David Emerson wrote
a. 'var' sections -- I assume that 'var' is optional when declaring fields that occur first (i.e. directly after "private", "public", etc)

Yes.

Show quoted text 5 lines
b. What does "strict private" mean, as opposed to private without strict? (My best guess is that it would be accessible only within the methods+properties of that class within the unit, as opposed to being available anywhere in the same unit where the class is declared...???)

"strict private" is not a new feature. it means that something is private for this class only and can't be accessed by other classes or routines of the unit.

Show quoted text 5 lines
c. What is the purpose of a class method? It would seem to me that methods should do the same thing whether they are class methods or not. Traditional variables change from instance to instance, but methods do not vary between instances, as far as I know-- right?

Class method is not a new feature as well as static class method. Class method allows you to have methods which belongs to the class instead of an instance of the class. Class methods can be virtual. Static class methods can't.

Show quoted text 7 lines
d. What happens with inheritance? d.1. wrt class constants and class vars-- are there separate "instances" (for lack of a better word) of these, one instance for each descendant? Or is the class var/const only stored once for the ancestor that declares it, and all descendants share that?

Class vars (static class fields) are stored only once for the class which declares them and all descendants share that.

Example:
TSomeClass = class
class var Value: Integer;
end;
TDescendant = class(TSomeClass);
begin
  TSomeClass.Value := 1;
  TDescendant.Value := 2;
  WriteLn(TSomeClass.Value); // this must output 2
end;

Class static field is not a new feature. But now you can declare them using 'class var' section after methods or 'type'/'const' section.

d.2. wrt class methods, can they be virtual? (This strikes me as being closely related to d.1)

class methods can be virtual. static class methods can't.

Show quoted text 17 lines
I guess an example is in order for d: type t_parent = class private class var x : integer; const c = 5; end; t_child = class (t_parent) private const c = 7; // can I do this? end;

In ObjFpc mode you can't do this because t_child.c duplicates t_parent.c. In Delphi mode you can do this. I have no personal opinion how ObjFpc mode should work here but this behavior is consistent with restrictions for identifier duplication we currently have in objfpc mode.

e. Is it available in {$mode objfpc}? (I hope I hope I hope)?

yes.

Best regards,
Paul Ishenin.

Andreas Schneider
to Doug Chamberlin: Oh, I can imagine such methods also. And I've used them before. I just don't see the big…

I think they come in very handy for the Singleton OOP concept. You need to have a "factory" that handles the object query/instantiation. If no instance is available, it creates a new one (and stores it) and if one is already available, it just returns that.
Naturally that looks better to have TSomeClass.GetInstance() instead of GetInstanceOfSomeClass() ...
Sure, it's possible to do without class methods, but from an OOP viewpoint it just looks and feels wrong ;-) (imho)

Doug Chamberlin wrote 6 lines
Oh, I can imagine such methods also. And I've used them before. I just don't see the big advantage over having them be global functions/procedures located in the same unit as the class they operate on. So, as often as not, I go and create the global functions instead. Never could decide either way to go.
Marc Weustink
to Paul Ishenin: Yes. "strict private" is not a new feature. it means that something is private for this…
Paul Ishenin wrote 25 lines
David Emerson wrote: > d. What happens with inheritance? > > d.1. wrt class constants and class vars-- are there separate > "instances" (for lack of a better word) of these, one instance for > each descendant? Or is the class var/const only stored once for the > ancestor that declares it, and all descendants share that? > Class vars (static class fields) are stored only once for the class which declares them and all descendants share that. Example: TSomeClass = class class var Value: Integer; end; TDescendant = class(TSomeClass); begin TSomeClass.Value := 1; TDescendant.Value := 2; WriteLn(TSomeClass.Value); // this must output 2 end; Class static field is not a new feature. But now you can declare them using 'class var' section after methods or 'type'/'const' section.

Can we have a virtual version too like described here http://hallvards.blogspot.com/2007/05/hack17-virtual-class-variables-part-i.html

Marc

Arioch
to Andreas Schneider: I think they come in very handy for the Singleton OOP concept. You need to have a…

В письме от Thu, 14 Jan 2010 18:50:50 +0400, Andreas Schneider сообщал:

Can FPC have default class properties in Delphi mode or even ObjFpc mode?

i probably won't really do it, for my major concern is still Delphi, and that makes a special note that "defaul" and "class" are mutually exclusive.

Pity... i wished to do a light-weight factory (which Delphi class references are to an extent). I would have to resort to global procedure, but that is less elegant.
And calling TClassName.a(DataPayload) is awful. TClassName[DataPayload] would be neat...

Show quoted text 11 lines
I think they come in very handy for the Singleton OOP concept. You need to have a "factory" that handles the object query/instantiation. If no instance is available, it creates a new one (and stores it) and if one is already available, it just returns that. Naturally that looks better to have TSomeClass.GetInstance() instead of GetInstanceOfSomeClass() ... Sure, it's possible to do without class methods, but from an OOP viewpoint it just looks and feels wrong ;-) (imho)
Написано в почтовом клиенте браузера Opera: http://www.opera.com/mail/
Arioch1

To draw a perspective, i am coming from, i want to use a library, that is built with long procedures, having 5-10 parametes, of those i usually really only need to set one or two.

So i naturally decided to make a wrapper with fluent-style, chained API, so i can only set those params that i actually need customized. But Fluent API requires automatic lifetime management, which in Delphi means using ref-counted interfaces.

And that comes with a problem - constructor return an object, not an interface.
And even i make all the methods on object go protected and on;y exposed via interface, i have doubts that all the compilers would successfully implicitly typecast it. Most probably they would not. And doing manual typecast damages clean and simple ease of use for Fluent-style API.

Maybe you know about Jedi CodeLib library. It supports FPC 2.4 and recently unofficial patchset for 2.6 was released.
It has a TJclStringList/IJclStringList extenstion of a stock class.

Recently on stackoverflow there came yet another question that in effect was reduced "how to read all the lines from text file and split them on some delimeter.

 My usual answer for this goes along the lines
var s: string; isl1, isl2: IJclStringList;
...
isl1 := TJclStringList.Create; isl1.LoadFromFile(...);
...
for s in isl1 do begin
   isl2.Split(s, delimeter-char).Trim.Add(['some string', 'some another
string']).UpperCase. ...;
   // refining of strings can be chained
    // iterating through refined split data in isl2
end;
 This time i was in a haste and drafted like
isl1 := TJclStringList.Create.LoadFromFile(...);

Well, actually that most probably would not even compile, but if it would - it would be a memory leak, because between constructor and LoadFrom*** call
- there is no interface reference yet, but a PODO reference.

This obvious error, but is so easy to make when u want to type fast and fluentized.
So that gave me another reason to try to side-step Delphi object constructor.
But then how would i call factory-method? some simple name like "a", "b", "c,", "_" - would have no sense an d look ugly and hard to remember. Some lone name would harm conciseness of fluent style and would be against OOP "object.verb" style. It would be like making method TStringList.LoadStringListFromFile - DRY principle is good even in naming

 Then i got a flash and devised to outsmart Delphi with a construct like
this:
type
  TData = class end;  // some object we need to operate upon
  IDataHandler = interface end; //some methods to make Fluent-Style,
daisy-chain API
  { TDataExporter }
  TDataExporter = class(IDataHandler, TInterfacedObject)
     protected
        Payload: TData;
        constructor CreateFor(const d: TData);
        class function    MakeNewExporter(const d: TData): IDataHandler;
static;
        /// all other functions, setting this or that parameter and
        /// returning Self as IDataHandler
     public
        procedure AfterConstruction; override;
        class property Factory[Payload: TData]: IDataHandler read
MakeNewExporter; default;
  end;

{ TDataExporter }

class function TDataExporter.MakeNewExporter(const d: TData): IDataExporter;
begin
  Result := TDataExporter.CreateFor(d);
end;
procedure TDataExporter.AfterConstruction;
begin
  if Self.Payload = nil then raise Exception.Create('You should not create
via inherited TObject.Create!');
end;
constructor TDataExporter.CreateFor(const d: TData);
begin
  if d = nil then raise Exception.Create('Payload data is required!');
  Self.Payload := d;
end;

And you know what... dunno if it works or not, but at least it compiled in CT 3.10 Win64

var i: IDataHandler;
begin
  i := TDataExporter[TData.Create];
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: IDataHandler;  d: TData;
begin
  d := TData.Create;
  i := TDataExporter[d];
end;
unit1.pas(52,22) Error: Illegal qualifier

in both Delphi and ObjFpc mode :-(((

Arioch1 wrote

Show quoted text 13 lines
Can FPC have default class properties in Delphi mode or even ObjFpc mode? Andreas Schneider-7 wrote > I think they come in very handy for the Singleton OOP concept. You need > to > have a "factory" that handles the object query/instantiation. If no > instance > is available, it creates a new one (and stores it) and if one is already > available, it just returns that. > Naturally that looks better to have TSomeClass.GetInstance() instead of > GetInstanceOfSomeClass() ... > Sure, it's possible to do without class methods, but from an OOP > viewpoint it > just looks and feels wrong ;-) (imho)