Sign in Join

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

Mailing lists / fpc-pascal / 2016-06

Quick Modern Object Pascal Introduction, for Programmers

32 messages · 12 people · –

Reply by email Subscribe to this list Your subscription

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

Michalis Kamburelis

Hi,

So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)

Read on:

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.pdf

This document started just Thursday morning. I thought that such document would be a helpful resource for the developers interested in my Castle Game Engine (http://castle-engine.sourceforge.net/ ). The document is directed at programmers who already know the concepts (like classes, virtual methods) but they don't know how they look like in Object Pascal. Or maybe they know Object Pascal classes, but don't know about some "advanced" (but really useful IMHO) language features added in the recent years. For example, many people are not aware that Pascal has generics -- a powerful and important language feature, IMHO. Many people are not sure what happens when an exception occurs during the constructor -- which is quite important to know, if you want to write correct destructors, I think.

This document quickly grew over the last 3 days:) It starts from really basic stuff, and quite quickly jumps into "advanced" stuff. The PDF is now 52-pages long, and calling it a "Quick Introduction" becomes harder and harder:)

Parts of it apply only to recent FPC versions, and only to {$mode objfpc} mode. I deliberately didn't want to burden the reader with historic details, or differences between Delphi and FPC, or FPC $modes. This is for readers who just use the latest FPC version, as their primary Pascal compiler, and want to use the language with all it's current features.

Share and redistribute as you like. The source is in AsciiDoc, available on GitHub
https://github.com/michaliskambi/modern-pascal-introduction , and corrections and improvements and all comments are very much welcome! You're also welcome to reuse parts of it for FPC/Lazarus wiki or any other document (license is the same as wikipedia). I hope you will find this useful:)

Regards,
Michalis

Reply by email

Dennis Poon
to Michalis Kamburelis: So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)…
Michalis Kamburelis wrote 12 lines

Good work and thank you for your contribution to the community.

Dennis

Reply by email

Mr Bee
to Michalis Kamburelis: So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)…

Good work, sir. Thank you very much. I might use your article to direct people who still thinks Pascal today is still like the old Pascal of the 70's. :)  I have a little suggestion though. I prefer to use {$J-} directive in my Pascal program. I think it encourages good programming practice in Pascal. The {$J-} means constant is a constant no matter how you declare it. To bad FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which means a constant becomes a variable once you include the data type eventhough it's declared within a 'const' block. CMIIW.

Regards,
–Mr Bee

Pada Minggu, 19 Juni 2016 13:27, Michalis Kamburelis menulis:

Hi,

So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)

Read on:

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.pdf

This document started just Thursday morning. I thought that such document would be a helpful resource for the developers interested in my Castle Game Engine (http://castle-engine.sourceforge.net/ ). The document is directed at programmers who already know the concepts (like classes, virtual methods) but they don't know how they look like in Object Pascal. Or maybe they know Object Pascal classes, but don't know about some "advanced" (but really useful IMHO) language features added in the recent years. For example, many people are not aware that Pascal has generics -- a powerful and important language feature, IMHO. Many people are not sure what happens when an exception occurs during the constructor -- which is quite important to know, if you want to write correct destructors, I think.

This document quickly grew over the last 3 days:) It starts from really basic stuff, and quite quickly jumps into "advanced" stuff. The PDF is now 52-pages long, and calling it a "Quick Introduction" becomes harder and harder:)

Parts of it apply only to recent FPC versions, and only to {$mode objfpc} mode. I deliberately didn't want to burden the reader with historic details, or differences between Delphi and FPC, or FPC $modes. This is for readers who just use the latest FPC version, as their primary Pascal compiler, and want to use the language with all it's current features.

Share and redistribute as you like. The source is in AsciiDoc, available on GitHub
https://github.com/michaliskambi/modern-pascal-introduction , and corrections and improvements and all comments are very much welcome! You're also welcome to reuse parts of it for FPC/Lazarus wiki or any other document (license is the same as wikipedia). I hope you will find this useful:)

Regards,
Michalis

Reply by email

Mark Morgan Lloyd
to Michalis Kamburelis: So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)…
Michalis Kamburelis wrote 10 lines

Nicely done, a good practical approach

I'd suggest warning readers early about "dangling else", and using otherwise rather than else in the case examples.

A private online service I use has somebody who still bears the scars of Olivetti attempting to write an operating system in (strict, unexpanded) Pascal. I think that Turbo Pascal came along a bit after that, but by then the damage was done.

It's unfortunate that there's a lot of C programmers who wouldn't dream of writing in K&R, but who still assume that Pascal is still as primitive as it was in the 1970s.

There's a few places where a native English author would have done things a bit differently. For example, in most places "Castle Game Engine" would probably be prefixed by "the", and also "it allows [something, what] to deal with cases when simple class inheritance is not enough".

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Sven Barth
to Mark Morgan Lloyd

Am 20.06.2016 11:56 schrieb "Mark Morgan Lloyd" <

: There's a few places where a native English author would have done things

a bit differently. For example, in most places "Castle Game Engine" would probably be prefixed by "the", and also "it allows [something, what] to deal with cases when simple class inheritance is not enough".

Michalis also provided a link to the source repo, so you can clone, correct such problems and issue a merge request.

Regards,
Sven

Reply by email

Marcos Douglas
to Michalis Kamburelis: So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)…
Michalis Kamburelis wrote 11 lines

Good job, thanks for share.
Don't agree with "Ugly (COM) interfaces". Yeah, _AddRef, _Release, QueryInterface is ugly implementation but reference-counting mechanism is nice.

Best regards,
Marcos Douglas

Reply by email

Mr Bee
to Michalis Kamburelis: So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)…

Good work, sir. Thank you very much. I might use your article to direct people who still thinks Pascal today is still like the old Pascal of the 70's. :)  I have a little suggestion though. I prefer to use {$J-} directive in my Pascal program. I think it encourages good programming practice in Pascal. The {$J-} means constant is a constant no matter how you declare it. Too bad FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which means a constant becomes a variable once you include the data type eventhough it's declared within a 'const' block. CMIIW. Regards,
–Mr Bee

Pada Minggu, 19 Juni 2016 13:27, Michalis Kamburelis menulis:

Hi,

So, I wrote a document describing (quickly!) many features of the modern Object Pascal:)

Read on:

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html

http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.pdf

This document started just Thursday morning. I thought that such document would be a helpful resource for the developers interested in my Castle Game Engine (http://castle-engine.sourceforge.net/ ). The document is directed at programmers who already know the concepts (like classes, virtual methods) but they don't know how they look like in Object Pascal. Or maybe they know Object Pascal classes, but don't know about some "advanced" (but really useful IMHO) language features added in the recent years. For example, many people are not aware that Pascal has generics -- a powerful and important language feature, IMHO. Many people are not sure what happens when an exception occurs during the constructor -- which is quite important to know, if you want to write correct destructors, I think.

This document quickly grew over the last 3 days:) It starts from really basic stuff, and quite quickly jumps into "advanced" stuff. The PDF is now 52-pages long, and calling it a "Quick Introduction" becomes harder and harder:)

Parts of it apply only to recent FPC versions, and only to {$mode objfpc} mode. I deliberately didn't want to burden the reader with historic details, or differences between Delphi and FPC, or FPC $modes. This is for readers who just use the latest FPC version, as their primary Pascal compiler, and want to use the language with all it's current features.

Share and redistribute as you like. The source is in AsciiDoc, available on GitHub
https://github.com/michaliskambi/modern-pascal-introduction , and corrections and improvements and all comments are very much welcome! You're also welcome to reuse parts of it for FPC/Lazarus wiki or any other document (license is the same as wikipedia). I hope you will find this useful:)

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Mr Bee: Good work, sir. Thank you very much. I might use your article to direct people who still…

2016-06-20 5:31 GMT+02:00 Mr Bee :
[...]

Show quoted text 7 lines
I have a little suggestion though. I prefer to use {$J-} directive in my Pascal program. I think it encourages good programming practice in Pascal. The {$J-} means constant is a constant no matter how you declare it. To bad FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which means a constant becomes a variable once you include the data type eventhough it's declared within a 'const' block. CMIIW.

Ouch. For some reason, I thought that {$J-} is the default in {$mode objfpc} since years, and we have left that mistake behind us. Quick test showed me that I was mistaken. This makes a *lot* of my code less safe that I assumed, as in many recent projects I didn't bother to explicitly use {$J-}.

This is an excellent suggestion then, thank you. I updated the document to encourage everywhere doing

  {$mode objfpc}{$H+}{$J-}

at the beginning.

I definitely *do not want* to explain to any new programmer what a "writeable constant" is... This concept should remain buried:)

Regards,
Michalis

Reply by email

Marc Hanisch
to Michalis Kamburelis

Thanks Michalis for your excellent work! It's very important to left the early 90s associated with Pascal programming behind us and to encourage new developers to have a look onto the modern aspects of Object Pascal!

Maybe a little bit offtopic, but I have a question regarding the compiler directives: is there a way to tell Lazarus to use these directives in every new unit?

Best regards,
Marc

2016-06-21 7:47 GMT+02:00 Michalis Kamburelis :

Show quoted text 34 lines
2016-06-20 5:31 GMT+02:00 Mr Bee : [...] > I have a little suggestion though. I prefer to use {$J-} directive in my > Pascal program. I think it encourages good programming practice in Pascal. > The {$J-} means constant is a constant no matter how you declare it. To bad > FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which > means a constant becomes a variable once you include the data type > eventhough it's declared within a 'const' block. CMIIW. > Ouch. For some reason, I thought that {$J-} is the default in {$mode objfpc} since years, and we have left that mistake behind us. Quick test showed me that I was mistaken. This makes a *lot* of my code less safe that I assumed, as in many recent projects I didn't bother to explicitly use {$J-}. This is an excellent suggestion then, thank you. I updated the document to encourage everywhere doing {$mode objfpc}{$H+}{$J-} at the beginning. I definitely *do not want* to explain to any new programmer what a "writeable constant" is... This concept should remain buried:) Regards, Michalis _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply by email

Mr Bee
to Michalis Kamburelis: 2016-06-20 5:31 GMT+02:00 Mr Bee : [...] Ouch. For some reason, I thought that {$J-} is…
 I definitely *do not want* to explain to any new programmer what a "writeable constant" is... This concept should remain buried :) Exactly! I also don't understand why the {$MODE OBJFPC} uses the {$J+} as the default. :)

–Mr Bee

Pada Selasa, 21 Juni 2016 12:47, Michalis Kamburelis menulis:

2016-06-20 5:31 GMT+02:00 Mr Bee :
[...]

Show quoted text 7 lines
I have a little suggestion though. I prefer to use {$J-} directive in my Pascal program. I think it encourages good programming practice in Pascal. The {$J-} means constant is a constant no matter how you declare it. To bad FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which means a constant becomes a variable once you include the data type eventhough it's declared within a 'const' block. CMIIW.

Ouch. For some reason, I thought that {$J-} is the default in {$mode objfpc} since years, and we have left that mistake behind us. Quick test showed me that I was mistaken. This makes a *lot* of my code less safe that I assumed, as in many recent projects I didn't bother to explicitly use {$J-}.

This is an excellent suggestion then, thank you. I updated the document to encourage everywhere doing

  {$mode objfpc}{$H+}{$J-}

at the beginning.

I definitely *do not want* to explain to any new programmer what a "writeable constant" is... This concept should remain buried:)

Regards,
Michalis

Reply by email

Mr Bee
to Marc Hanisch: Thanks Michalis for your excellent work! It's very important to left the early 90s…
 Maybe a little bit offtopic, but I have a question regarding the compiler directives: is there a way to tell Lazarus to use these directives in every new unit? I even expect a bit further. These {$MODE OBJFPC}, {$H+}, and {$J-} directives should be the *default* directives for every new FPC programs/units. We're now using Free Pascal compiler on 2016. Why do we need to explicitly declare Free Pascal mode in a Free Pascal program? In 21st century, our string should not be limited to 255 chars anymore. And what the hell is "writable constant"? It's contradictio in terminis. :)

If somehow someone want to deals with those things, let them use the appropriate directives explicitly. But for most programs we build today, those things should be the default.

–Mr Bee

Pada Selasa, 21 Juni 2016 13:15, Marc Hanisch menulis:

Thanks Michalis for your excellent work! It's very important to left the early 90s associated with Pascal programming behind us and to encourage new developers to have a look onto the modern aspects of Object Pascal! Maybe a little bit offtopic, but I have a question regarding the compiler directives: is there a way to tell Lazarus to use these directives in every new unit? Best regards,Marc
2016-06-21 7:47 GMT+02:00 Michalis Kamburelis :

2016-06-20 5:31 GMT+02:00 Mr Bee :
[...]

Show quoted text 7 lines
I have a little suggestion though. I prefer to use {$J-} directive in my Pascal program. I think it encourages good programming practice in Pascal. The {$J-} means constant is a constant no matter how you declare it. To bad FPC is still using {$J+} as the default even in the {$MODE OBJFPC}, which means a constant becomes a variable once you include the data type eventhough it's declared within a 'const' block. CMIIW.

Ouch. For some reason, I thought that {$J-} is the default in {$mode objfpc} since years, and we have left that mistake behind us. Quick test showed me that I was mistaken. This makes a *lot* of my code less safe that I assumed, as in many recent projects I didn't bother to explicitly use {$J-}.

This is an excellent suggestion then, thank you. I updated the document to encourage everywhere doing

  {$mode objfpc}{$H+}{$J-}

at the beginning.

I definitely *do not want* to explain to any new programmer what a "writeable constant" is... This concept should remain buried:)

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Dennis Poon: May I suggest the addition of : 1) user defined operator? 2) use of ClassType function…

2016-06-20 6:16 GMT+02:00 Dennis Poon :

May I suggest the addition of : 1) user defined operator?

Added. I had it on my TODO list already:) See it here: http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_operator_overloading .

I documented also overriding operators for classes and records, and mentioned the need for "class operator" on records to be able to work with TFPGList and such.

2) use of ClassType function for cloning objects

I added two things:

- A section about TPersistent.Assign. This is the "basic approach to cloning" that should probably be shown first. See it here: http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_cloning_tpersistent_assign . I mentioned the special rules when calling the "inherited" from Assign overrides, and AssignTo, and the fact that TPersistent makes the default visibility "published".

- And the ClassType, with the example of Clone method using it, is added at the desciption of "class references" on
http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_class_references .

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Mark Morgan Lloyd: Nicely done, a good practical approach I'd suggest warning readers early about "dangling…

2016-06-20 11:44 GMT+02:00 Mark Morgan Lloyd
:
[...]

I'd suggest warning readers early about "dangling else", and using otherwise rather than else in the case examples.

As for dangling else - good idea, I added a text and example mentioning it briefly at the of
http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_testing_if .

As for "otherwise" in "case" - I admit I prefer the "else" keyword there. Although I don't have any other argument for it than being accustomed to it, from reading existing sources. I just grepped FPC and Lazarus source code, and I couldn't find any "case" with "otherwise" section... while I easily found occurrences of "case" with "else" sections.

For this reason, I am inclined to keep the example with "case .. else", not "case .. otherwise". Indeed, one needs to be more careful then (to not mix the "else" with an "if" from the last statement).

It's unfortunate that there's a lot of C programmers who wouldn't dream of writing in K&R, but who still assume that Pascal is still as primitive as it was in the 1970s.

That's a great analogy. I may steal it some day:)

Show quoted text 6 lines
There's a few places where a native English author would have done things a bit differently. For example, in most places "Castle Game Engine" would probably be prefixed by "the", and also "it allows [something, what] to deal with cases when simple class inheritance is not enough".

Thanks! I improved it a bit, adding "the" at some places and changed to sentence to simpler "Useful when a simple class inheritance is not enough.".

I'm not a native English speaker, so any corrections and suggestions are very welcome when it comes to the language (and everything else:)

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Marcos Douglas: On Sun, Jun 19, 2016 at 3:26 AM, Michalis Kamburelis Good job, thanks for share. Don't…

2016-06-20 14:30 GMT+02:00 Marcos Douglas :

Don't agree with "Ugly (COM) interfaces". Yeah, _AddRef, _Release, QueryInterface is ugly implementation but reference-counting mechanism is nice.

Reference-counting is a useful concept, but "entangling" it with interfaces is somewhat ugly IMHO. Those two concepts, and needs, should be unrelated language features in my opinion:

- you use interfaces when you want to cast a class to multiple possible interfaces,
- you use reference-counting to get automatic memory management (to some extent, e.g. beware of cycles).

Both of these are useful, but forcing them together seems ugly. And it causes actual problems:

- Various classes, using standard TComponent, have to "hack around" reference counting by proving _AddRef implementations that do nothing,
- Even with hack above, you need to be extra careful about interface temporary variables (you cannot free the class instance, if some temporary interface variable may refer to it).

Regards,
Michalis

Reply by email

Dennis Poon
to Michalis Kamburelis: 2016-06-20 6:16 GMT+02:00 Dennis Poon : Added. I had it on my TODO list already:) See it…
Show quoted text 14 lines
> 2) use of ClassType function for cloning objects I added two things: - A section about TPersistent.Assign. This is the "basic approach to cloning" that should probably be shown first. See it here: http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_cloning_tpersistent_assign . I mentioned the special rules when calling the "inherited" from Assign overrides, and AssignTo, and the fact that TPersistent makes the default visibility "published". - And the ClassType, with the example of Clone method using it, is added at the desciption of "class references" on http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_class_references

Just read your example

|function TMyClass.Clone(AOwner: TComponent): TMyClass; begin // This
would always create an instance of exactly TMyClass: //Result :=
TMyClass.Create(AOwner); // This can potentially create an instance of
TMyClass descendant: Result := TMyClassRef(ClassType).Create(AOwner);
Result.Assign(Self); end |

|I remember someone once asked whether we should override the method Assign or AssignTo.|
|I am worried, choosing the wrong method to override will produce unexpected result.|
||
|Dennis|

||
|
|

Reply by email

Sven Barth
to Mr Bee: If somehow someone want to deals with those things, let them use the appropriate…
"Mr Bee" wrote
> Maybe a little bit offtopic, but I have a question regarding the

compiler directives: is there a way to tell Lazarus to use these directives in every new unit?

I even expect a bit further. These {$MODE OBJFPC}, {$H+}, and {$J-}

directives should be the *default* directives for every new FPC programs/units. We're now using Free Pascal compiler on 2016. Why do we need to explicitly declare Free Pascal mode in a Free Pascal program? In 21st century, our string should not be limited to 255 chars anymore. And what the hell is "writable constant"? It's contradictio in terminis. :)

We have a strong focus on backwards compatibility, so the default mode stays "fpc" and changing a modes' default settings would also affect backwards compatibility.

Regards,
Sven

Reply by email

Karoly Balogh (Charlie/SGR
to Mr Bee: If somehow someone want to deals with those things, let them use the appropriate…

Hi,

Mr Bee wrote
> Maybe a little bit offtopic, but I have a question regarding the >compiler directives: is there a way to tell Lazarus to use these >directives in every new unit?

No clue about Lazarus, but one can put -mOBJFPC in his compiler config file (same with other modes), and tell Lazarus somehow to use that config file. I'm positive that it's possible and that changes the default. Same with a lot of other modeswitches or default-changers, if you don't wanna pollute all your sources with such switches, put it in your config file. Just don't forget to document these options for your project's build system.

(And if you use components which expects other modes (Delphi is pretty common), you might need to add the modeswitch to them instead...)

Charlie

Reply by email

Michalis Kamburelis
to Marc Hanisch: Thanks Michalis for your excellent work! It's very important to left the early 90s…

2016-06-21 8:15 GMT+02:00 Marc Hanisch :

Show quoted text 8 lines
Thanks Michalis for your excellent work! It's very important to left the early 90s associated with Pascal programming behind us and to encourage new developers to have a look onto the modern aspects of Object Pascal! Maybe a little bit offtopic, but I have a question regarding the compiler directives: is there a way to tell Lazarus to use these directives in every new unit?

In Lazarus, you can choose the mode ("Object Pascal - default (ObjFpc)") and $H+ ("Use AnsiStrings") in the Project -> Options -> Compilation Options. This is equivalent to starting all your code with "{$mode objfpc}{$H+}".

In fact, these are already the default: ObjFpc and $H+. So, if you're using Lazarus for your development, these are already set at nice default values.

It seems not possible to set the "{$writeableconst off}" (equivalent to "{$J-}") using Lazarus options. Probably because it seems not possible to do it using FPC command-line, so Lazarus would not have how to communicate it to FPC. Seems like a simple omission, and a bugreport to FPC would fix it:)

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Dennis Poon: Just read your example |function TMyClass.Clone(AOwner: TComponent): TMyClass; begin //…
|I remember someone once asked whether we should override the method Assign or AssignTo.| |I am worried, choosing the wrong method to override will produce unexpected result.|

The AssignTo is only used by TPersistent.Assign, so it's a "fallback" --- if class A cannot copy *from* B, then AssignTo is called on B to let B assign *to* A. This allows to implement the copying on any end, which is useful e.g. when you cannot change the source code of A.

This is documented on
http://www.freepascal.org/docs-html/rtl/classes/tpersistent.assign.html .

The short advice is that you usually want to override Assign, and forget about AssignTo. Overriding Assign is always enough if you think about a typical cloning scenario, when you usually copy instance of class A to another instance of class A, and not mix classes.

Regards,
Michalis

Reply by email

Marco van de Voort
to Michalis Kamburelis: 2016-06-20 6:16 GMT+02:00 Dennis Poon : Added. I had it on my TODO list already:) See it…

In our previous episode, Michalis Kamburelis said:

- A section about TPersistent.Assign. This is the "basic approach to cloning" that should probably be shown first. See it here: http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_cloning_tpersistent_assign

See also
http://stackoverflow.com/questions/4041760/correct-way-to-duplicate-delphi-object/4041906#4041906

That is for an own root class and pre class helpers, but you could do it also in or TPersistent helper:

type tpersisthelp = class helper for TPersistent
    function Clone(t: TPersistentClass = nil): TPersistent;
end;
function tpersisthelp.Clone(t: TPersistentClass = nil): TPersistent;
  begin
    if Assigned(t) then
      Result := t.Create
    else
      Result := TPersistentClass(Self.ClassType).Create;
    Result.Assign(Self);
  end;

Since TComponent declares a virtual destructor that might even be better.

Reply by email

Michalis Kamburelis
to Sven Barth: compiler directives: is there a way to tell Lazarus to use these directives in every new…
Show quoted text 11 lines
> I even expect a bit further. These {$MODE OBJFPC}, {$H+}, and {$J-} > directives should be the *default* directives for every new FPC > programs/units. We're now using Free Pascal compiler on 2016. Why do we need > to explicitly declare Free Pascal mode in a Free Pascal program? In 21st > century, our string should not be limited to 255 chars anymore. And what the > hell is "writable constant"? It's contradictio in terminis. :) We have a strong focus on backwards compatibility, so the default mode stays "fpc" and changing a modes' default settings would also affect backwards compatibility.

Maintaining compatibility is usually a compromise. I feel that in this case, maintaining such compatibility hurts more than it helps. It is of course my opinion, biased by the kind of code I write, and by the programmers I talk with (many of whom don't know Pascal, but know Java, C# or other OOP languages).

Current FPC defaults:

- Help people who except the {$mode fpc} to be default (so they write code without classes and a lot of other new features),
- Or people who expect that string is by default ShortString (limited to 255 chars).

I think that the majority of people use now suitable command-line options, or directives, to change FPC mode to something more modern ({$mode objfpc} or {$mode delphi}, and {$H+}). So changing the defaults will not hurt them. Sure, I don't have any hard data to back it up, I don't know how much is "majority". But this applies at least to all Lazarus users that have these settings "by default".

Again, this is just my opinion, but I would say that breaking compatibility in this case is warranted. Making objfpc the default mode, and making $H+ the default in objfpc mode, before the fpc.cfg is read (so it applies to everyone, and can be overridden by fpc.cfg or command-line later) would be a nice thing.

(Making {$J-} would be a cool bonus, but I don't dream about it, as it could admittedly break more recent code.)

In http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html I decided to just write

  {$mode objfpc}{$H+}{$J-} // Just use this line in all modern sources

at the beginning of a first "hello world" example. And I never explain the reason for this line, I just repeat it in all examples (that are full programs/units). That's an ugly solution, but I just couldn't see a better one. It doesn't sound nice to explain that:

- otherwise, they don't have classes ("why are classes disabled?"),
- otherwise their stings are limited to 255 ("are you sure this is a modern language?"),
- and otherwise their constants are not necessarily constant ("what?") ...

It's not a good learning experience, if you have to learn about so many historical things when you learn to write a first Pascal program. And these things are already fixed -- just the defaults are old.

Regards,
Michalis

Reply by email

Michalis Kamburelis
to Marco van de Voort: In our previous episode, Michalis Kamburelis said: See also…

2016-06-21 12:14 GMT+02:00 Marco van de Voort :

Show quoted text 26 lines
In our previous episode, Michalis Kamburelis said: > > - A section about TPersistent.Assign. This is the "basic approach to > cloning" that should probably be shown first. See it here: > http://michalis.ii.uni.wroc.pl/~michalis/modern_pascal_introduction/modern_pascal_introduction.html#_cloning_tpersistent_assign See also http://stackoverflow.com/questions/4041760/correct-way-to-duplicate-delphi-object/4041906#4041906 That is for an own root class and pre class helpers, but you could do it also in or TPersistent helper: type tpersisthelp = class helper for TPersistent function Clone(t: TPersistentClass = nil): TPersistent; end; function tpersisthelp.Clone(t: TPersistentClass = nil): TPersistent; begin if Assigned(t) then Result := t.Create else Result := TPersistentClass(Self.ClassType).Create; Result.Assign(Self); end; Since TComponent declares a virtual destructor that might even be better.

I saw your post on stackoverflow before writing my article:)

But doing this on TPersistent means that you avoid calling the constructor of the actual class. If you use this helper on a class TMyClass, you will have an instance of TMyClass that "bypassed" the constructor of TMyClass. Only "TPersistent.Create" was called. I suspect that in real-world usage, a lot of classes will fail to work correctly then, since code inside TMyClass often assumes that TMyClass constructor was performed. I know that a lot of my own classes will fail because of this...

That's why I would limit this usage only to the cases when you have a virtual constructor on the base class. Only then the final class has a chance to execute it's proper constructor.

Regards,
Michalis

Reply by email

Mr Bee
to Sven Barth: compiler directives: is there a way to tell Lazarus to use these directives in every new…

Adding to Michalis Kamburelis argument… 
Keeping backwards compatibility [BC] is great. However, thinking about forwards compatibility [FC] is also necessary. Keeping BC too tight will also hold back our forward thinking. We will be stucked in the past forever. No matter how hard we keep the BC, we eventually will break it anyway. If we want FPC to be known as modern programming language, just let go off the past. Unless, we are happy to be still associated with the old 70's Pascal. So, we must plan the appropriate timing when we should break BC and let FC taking over. I think FPC v.3.2 would be appropriate enough. Besides, what's the release notes for? right? :)  –Mr Bee

Pada Selasa, 21 Juni 2016 16:30, Sven Barth menulis:

"Mr Bee" wrote
> Maybe a little bit offtopic, but I have a question regarding the compiler directives: is there a way to tell Lazarus to use these directives in every new unit?   I even expect a bit further. These {$MODE OBJFPC}, {$H+}, and {$J-} directives should be the *default* directives for every new FPC programs/units. We're now using Free Pascal compiler on 2016. Why do we need to explicitly declare Free Pascal mode in a Free Pascal program? In 21st century, our string should not be limited to 255 chars anymore. And what the hell is "writable constant"? It's contradictio in terminis. :)We have a strong focus on backwards compatibility, so the default mode stays "fpc" and changing a modes' default settings would also affect backwards compatibility.Regards,

Sven

Reply by email

Karoly Balogh (Charlie/SGR
to Mr Bee

Hi,

Mr Bee wrote 7 lines
Keeping backwards compatibility [BC] is great. However, thinking about forwards compatibility [FC] is also necessary. Keeping BC too tight will also hold back our forward thinking. We will be stucked in the past forever. No matter how hard we keep the BC, we eventually will break it anyway. If we want FPC to be known as modern programming language, just let go off the past. Unless, we are happy to be still associated with the old 70's Pascal.

Well, actually, ObjFPC and other modes still have plenty of legacy... Large chunks of the SysUtils unit are legacy. Not to mention the bunch of Windowsism coming from Delphi all over the RTL and Packages. Heck, Lazarus even reimplemented parts of the Windows API for better legacy Delphi code compatibility...

Either we care about compatibility and FPC remains what it is, or if we really want a *MODERN* language, just go the Oxygene path, and add a more modern syntax as well. For example, I dislike the interface vs. implementation separation, it's much better to mark the public stuff with public, like in Java, etc... Also, some of the syntax limitations also feel really archaic these days. Fix the dangling else. Add a better for/foreach loop. Also, lets drop write(), which is an exception to any Pascal language rule with its varargs syntax, etc... I could go on, and I didn't even touch the RTL legacies topic... These would be the important things IMO, not the name of the default stringtype (which is changed by whoever owns Delphi every 3 years anyway), or a single option in the config file, because that's so future...

My 2 c,
---
Charlie

Reply by email

Sven Barth
to Michalis Kamburelis: Maintaining compatibility is usually a compromise. I feel that in this case, maintaining…

Am 21.06.2016 12:31 schrieb "Michalis Kamburelis" <

Show quoted text 7 lines
: Current FPC defaults: - Help people who except the {$mode fpc} to be default (so they write code without classes and a lot of other new features), - Or people who expect that string is by default ShortString (limited to 255 chars).

One might argue about changing the default mode, but changing the default String type of mode ObjFPC will very likely result in compilation or runtime errors (probably even in the compiler itself) which is something we tend to avoid without good reasons. At the very least there will be performance differences which - depending on the code - might be noticeable as well.

Regards,
Sven

Reply by email

Michalis Kamburelis
to Sven Barth

2016-06-21 15:03 GMT+02:00 Sven Barth :

Show quoted text 15 lines
Am 21.06.2016 12:31 schrieb "Michalis Kamburelis" : > Current FPC defaults: > > - Help people who except the {$mode fpc} to be default (so they write > code without classes and a lot of other new features), > - Or people who expect that string is by default ShortString (limited > to 255 chars). One might argue about changing the default mode, but changing the default String type of mode ObjFPC will very likely result in compilation or runtime errors (probably even in the compiler itself) which is something we tend to avoid without good reasons. At the very least there will be performance differences which - depending on the code - might be noticeable as well.

These errors and differences will be only felt by projects that use {$mode objfpc} but assume that string = ShortString (and they don't use {$H-} explicitly). I don't think it would apply to too many projects?

And if we do it in some major version, with proper release notes, like Mr Bee proposes, these projects would have plenty of time to adjust their compilation scripts / config files. They could just add "-Sh-" or "{$H-}" and be OK, for both past and future FPC versions.

Regards,
Michalis

Reply by email

Sven Barth
to Michalis Kamburelis

Am 21.06.2016 15:21 schrieb "Michalis Kamburelis" <

Show quoted text 13 lines
: 2016-06-21 15:03 GMT+02:00 Sven Barth : > Am 21.06.2016 12:31 schrieb "Michalis Kamburelis" > : >> Current FPC defaults: >> >> - Help people who except the {$mode fpc} to be default (so they write >> code without classes and a lot of other new features), >> - Or people who expect that string is by default ShortString (limited >> to 255 chars). > > One might argue about changing the default mode, but changing the

default

> String type of mode ObjFPC will very likely result in compilation or

runtime

> errors (probably even in the compiler itself) which is something we

tend to

Show quoted text 8 lines
> avoid without good reasons. At the very least there will be performance > differences which - depending on the code - might be noticeable as well. > These errors and differences will be only felt by projects that use {$mode objfpc} but assume that string = ShortString (and they don't use {$H-} explicitly). I don't think it would apply to too many projects?

Compiler and RTL are two examples.

And if we do it in some major version, with proper release notes, like Mr Bee proposes, these projects would have plenty of time to adjust their compilation scripts / config files. They could just add "-Sh-" or "{$H-}" and be OK, for both past and future FPC versions.

It was decided some time ago when mode Delphi was switched to H+ (due to Delphi compatibility) that mode ObjFPC won't be switched, cause for that mode we value backwards compatibility higher than the user not having to write a switch.

Regards,
Sven

Reply by email

Jürgen Hestermann
to Sven Barth
Sven Barth wrote
It was decided some time ago when mode Delphi was switched to H+ (due to Delphi compatibility) that mode ObjFPC won't be switched, cause for that mode we value backwards compatibility higher than the user not having to write a switch.

This is quite short-sighted:

It's not only the work of writing a compiler switch. You also have to *know* (think) about it.
There are so many compiler switches and if we end up with the situation that all new users have to spend a day to make their program work as the grandious feature list of some FPC page told them then something is wrong.

Those who are already familiar with all the details have much less work to just add a compiler switch to their existing projects (if needed) and it would be necessary only once on a certain FPC version when this default changes.

Now we need to tell each new user that he has to change the (default) settings to get a "modern" Pascal compiler because "out of the box" it is a very old one.

Reply by email

Graeme Geldenhuys
to Dennis Poon
Dennis Poon wrote
can we do it in descending order without a user defined enumerator?

Not as far as I know - I believe it is a one directional iterator (or so the interface suggests). There are tons of limitations with the for..in construct.

Years back I implemented an iterator interface (based on Java definition of iterators) with multiple implementations for various container classes I use often. I can iterate forward, backwards, use a regex to filter (skip) what gets iterated etc. And using the factory method I can request an iterator instance with ease, and even register more iterators if needed. So much more flexible [personal opinion].

I've written an article about it some years back:
http://geldenhuys.co.uk/articles/

Look for the “Iterator Pattern” article and sample code.

Regards,
Graeme

Reply by email