Sign in Join

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

Mailing lists / fpc-devel / 2013-01

for-in-index loop

155 messages · 20 people · –

Reply by email Subscribe to this list Your subscription

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

vrt277

Hi FPC team,

There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if available
<http://wiki.freepascal.org/for-in_loop#Proposed_extensions>. From my point of view it's essential part of iterators. Especially for data structures which store pairs of key and value associated with key.

I want to implement this extension. Moreover I started implementation to explore fpc internals. Current /(not finished)/ result available on github. <https://github.com/vkevroletin/freepascal/tree/key-value-iterator>

My motivation is simple: I'm a student. My teacher is Alexander S. Klenin who should be well known to fp? developers. And I want to implement some feature of fpc as my graduate work. Through improvement of for-in loop is not enough for good graduate work but it is good initial step towards other big contribution.

So is get enumerator Position if available
<http://wiki.freepascal.org/for-in_loop#Proposed_extensions> good idea?

Thanks,
Vasiliy Kevroletin

P.S. links for people who dislike computer mouse:

proposed extension -
http://wiki.freepascal.org/for-in_loop#Proposed_extensions my branch on github -
https://github.com/vkevroletin/freepascal/tree/key-value-iterator

Reply by email

Michael Van Canneyt
to vrt277
vrt277 wrote
Hi FPC team, There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if available. From my point of view it's essential part of iterators. Especially for data structures which store pairs of key and value associated with key.

Enumerators are not iterators.

If you want a full-fledged iterator, you should use classes.

The for syntax is not meant for that.

Show quoted text 6 lines
I want to implement this extension. Moreover I started implementation to explore fpc internals. Current (not finished) result available on github. My motivation is simple: I'm a student. My teacher is Alexander S. Klenin who should be well known to fpс developers. And I want to implement some feature of fpc as my graduate work. Through improvement of for-in loop is not enough for good graduate work but it is good initial step towards other big contribution. So is get enumerator Position if available good idea?

No. I think it is a bad idea.

If you want full fledged iterators, use classes.

Michael.

Reply by email

Alexander Klenin
to Michael Van Canneyt
Michael Van Canneyt wrote
Enumerators are not iterators.

Eh... actually, they are? Why do you think otherwise?

If you want a full-fledged iterator, you should use classes.

Enumerators *are* classes, except for built-in ones.

The for syntax is not meant for that.

That's debatable.
There is no for-index support in Java, but there is in most (all?) other modern languages --
Python, PHP, Ruby, etc.
I suggest that Java is inferior in this regard.

If you want full fledged iterators, use classes.

Please provide example of your suggesion for the case in the wiki.

Alexander S. Klenin

Reply by email

Jeppe Græsdal Johansen
to vrt277: There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if…
vrt277 wrote 31 lines
Hi FPC team, There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if available <http://wiki.freepascal.org/for-in_loop#Proposed_extensions>. From my point of view it's essential part of iterators. Especially for data structures which store pairs of key and value associated with key. I want to implement this extension. Moreover I started implementation to explore fpc internals. Current /(not finished)/ result available on github. <https://github.com/vkevroletin/freepascal/tree/key-value-iterator> My motivation is simple: I'm a student. My teacher is Alexander S. Klenin who should be well known to fp? developers. And I want to implement some feature of fpc as my graduate work. Through improvement of for-in loop is not enough for good graduate work but it is good initial step towards other big contribution. So is get enumerator Position if available <http://wiki.freepascal.org/for-in_loop#Proposed_extensions> good idea? Thanks, Vasiliy Kevroletin P.S. links for people who dislike computer mouse: proposed extension - http://wiki.freepascal.org/for-in_loop#Proposed_extensions my branch on github - https://github.com/vkevroletin/freepascal/tree/key-value-iterator

I think the idea is good if the feature is implemented as "optional".

That way:
- If the enumerator class implements a CurrentIndex method then the for loop can have an index variable.
- If not then the for loop can only behave as current for in loops.

Reply by email

Alexander Klenin
to Florian Klämpfl: As long as there is only some few line idea, there cannot debated much. Just an example:…
Florian Klämpfl wrote
Am 24.01.2013 20:36, schrieb Alexander Klenin: > That's debatable. As long as there is only some few line idea, there cannot debated much.

It is more: an idea with implementation and tests ;)

Just an example: what happens with i if I start to delete from s during the for loop?

Exactly the same thing as in the current for-in loop: either a range check error of nothing, depending on what you delete.

Alexander S. Klenin

Reply by email

Florian Klämpfl
to Mattias Gaertner
Mattias Gaertner wrote 12 lines
On Thu, 24 Jan 2013 21:30:23 +0100 Florian Klämpfl wrote: > Am 24.01.2013 20:36, schrieb Alexander Klenin: >> That's debatable. > > As long as there is only some few line idea, there cannot debated much. > Just an example: what happens with i if I start to delete from s during > the for loop? Do you mean like the TList enumerator? Deletion during loop results in skips.

No, if I delete a char already processed. Then the index is just useless but the loop will continue to run.

Reply by email

Florian Klämpfl
to Alexander Klenin: It is more: an idea with implementation and tests ;) Exactly the same thing as in the…
Alexander Klenin wrote 13 lines
On Fri, Jan 25, 2013 at 7:30 AM, Florian Klämpfl wrote: > Am 24.01.2013 20:36, schrieb Alexander Klenin: >> That's debatable. > > As long as there is only some few line idea, there cannot debated much. It is more: an idea with implementation and tests ;) > Just an example: what happens with i if I start to delete from s during > the for loop? Exactly the same thing as in the current for-in loop: either a range check error of nothing, depending on what you delete.

How do you ensure this if I delete a char already processed? Will i be adjusted? Or will the loop continue to run with an invalid i?

Reply by email

Alexander Klenin
to Florian Klämpfl
Florian Klämpfl wrote 8 lines
>> Just an example: what happens with i if I start to delete from s during >> the for loop? > > Exactly the same thing as in the current for-in loop: either a range check error > of nothing, depending on what you delete. How do you ensure this if I delete a char already processed? Will i be adjusted? Or will the loop continue to run with an invalid i?

Depends on whom you mean by "you". If you mean the programmer who uses the feature,
then the answer is the usual one -- "by thinking". If you mean the compiler, then the answer is also
the usual one -- "you can not". Consider these examples:

for i := 1 to Length(s) do begin
  Writeln(i, ' ', s[i]);
  DeleteSomePartOfS;
end;
i := 1;
for c in s do begin
  Writeln(i, ' ', c);
  DeleteSomePartOfS;
  i += 1;
end;
for c in s index i do begin
  Writeln(i, ' ', c);
  DeleteSomePartOfS;
end;

in all three cases, the effect will be more-or-less the same. (Actually, my testing demonstrated that for-in loop does NOT cause an exception here,
because s is copied by the loop. Paul, why did you code it that way?)

Alexander S. Klenin

Reply by email

Florian Klämpfl
to Alexander Klenin
Alexander Klenin wrote 11 lines
On Fri, Jan 25, 2013 at 7:56 AM, Florian Klämpfl wrote: >>> Just an example: what happens with i if I start to delete from s during >>> the for loop? >> >> Exactly the same thing as in the current for-in loop: either a range check error >> of nothing, depending on what you delete. > > How do you ensure this if I delete a char already processed? Will i be > adjusted? Or will the loop continue to run with an invalid i? Depends on whom you mean by "you".

"You": the designers of this extension.

If you mean the programmer who uses the feature, then the answer is the usual one -- "by thinking".

Or a good possibilty to create hard to find bugs.

Show quoted text 22 lines
If you mean the compiler, then the answer is also the usual one -- "you can not". Consider these examples: for i := 1 to Length(s) do begin Writeln(i, ' ', s[i]); DeleteSomePartOfS; end; i := 1; for c in s do begin Writeln(i, ' ', c); DeleteSomePartOfS; i += 1; end; for c in s index i do begin Writeln(i, ' ', c); DeleteSomePartOfS; end; in all three cases, the effect will be more-or-less the same.

In the first two cases the programmer knows that he does something strange, actually he can even adjust i if needed. In the last he might expect that i is always correct because it is a language construct and he has no change to fix i.

Reply by email

Florian Klämpfl
to Alexander Klenin: Yes, current discussion is based on that guideline. Alexander S. Klenin
Alexander Klenin wrote 7 lines
On Fri, Jan 25, 2013 at 7:34 AM, Marco van de Voort wrote: > In our previous episode, Florian Kl?mpfl said: >> As long as there is only some few line idea, there cannot debated much. > > http://www.freepascal.org/faq.var#extensionselect Yes, current discussion is based on that guideline.

... or based on that what this guideline does not cover.

Reply by email

Alexander Klenin
to Florian Klämpfl: "You": the designers of this extension. Or a good possibilty to create hard to find bugs.…
Florian Klämpfl wrote 7 lines
Am 24.01.2013 22:26, schrieb Alexander Klenin: > in all three cases, the effect will be more-or-less the same. In the first two cases the programmer knows that he does something strange, actually he can even adjust i if needed. In the last he might expect that i is always correct because it is a language construct and he has no change to fix i.

Well, it so happens that the current implementation does what you wish -- i.e. it guarantees that the loop will work regardless of the changes to s. However, in my opinion that it is an overkill, and careless changing the iterated object during the iteration *should* lead to exceptions, since it is a programmer error.
Anyway, this question should be discussed separately from the for-in-index extension,
since it affects the behaviour of existing code.

Alexander S. Klenin

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Fri, Jan 25, 2013 at 4:45 AM, Michael Van Canneyt Eh... actually, they are? Why do you…
Alexander Klenin wrote 17 lines
On Fri, Jan 25, 2013 at 4:45 AM, Michael Van Canneyt wrote: > Enumerators are not iterators. Eh... actually, they are? Why do you think otherwise? > If you want a full-fledged iterator, you should use classes. Enumerators *are* classes, except for built-in ones. > The for syntax is not meant for that. That's debatable. There is no for-index support in Java, but there is in most (all?) other modern languages -- Python, PHP, Ruby, etc. I suggest that Java is inferior in this regard. > If you want full fledged iterators, use classes. Please provide example of your suggesion for the case in the wiki.

You have your priorities wrong.

I don't need to provide *anything*.

Let's get something clear:

FPC is not the playground for every possible idea out there.

If someone wants to implement some weird syntax: please;
use FPC to try and test it, create your dissertation, whatnot.

But to expect that it is incorporated in the mainstream FPC distribution is a completely different thing.

Out in the real world, you'll need to prove that this actually is useful and will be used a lot.

"For in" is debatable by itself. It is syntactical sugar,
it provides nothing that for a:=b to c does not give.

Now you propose to extend this "sugar" syntax with something even more exotic, which I have not even encountered in other languages.

I can probably find plenty of use cases for the most weird syntaxes ever. That doesn't mean they
a) should be implemented at all,
b) should be included in FPC.

I do not want FPC to become Perl where every possible idea of every contributor that popped up on a blue monday was implemented and incorporated.

Go and propose your idea to the gcc team as an extension to C. let's see how far you get...

Michael.

Reply by email

Graeme Geldenhuys
to Alexander Klenin: On Fri, Jan 25, 2013 at 4:45 AM, Michael Van Canneyt Eh... actually, they are? Why do you…
Alexander Klenin wrote
> Enumerators are not iterators. Eh... actually, they are? Why do you think otherwise?

Enumerators are limited in functionality. Iterators are the full-blown thing. Common Iterator API is something like Next, Prev, Reset, HasNext, HasPrev etc. Enumerators normally just advance and only in one direction. This is how it is in many frameworks. Even Java's documentation describes it like that - see the bottom of the page for Iterator.

http://docs.oracle.com/javase/6/docs/technotes/guides/collections/reference.html

Regards,
- Graeme -

Reply by email

Alexander Klenin
to Michael Van Canneyt: You have your priorities wrong. I don't need to provide *anything*. Let's get something…
Michael Van Canneyt wrote 5 lines
>> If you want full fledged iterators, use classes. > > Please provide example of your suggestion for the case in the wiki. I don't need to provide *anything*.

Of course you do not, this is why I said "please" :) However, it is impossible to have a meaningful discussion without such an example,
so could you please indulge me?

Out in the real world, you'll need to prove that this actually is useful and will be used a lot. "For in" is debatable by itself. It is syntactical sugar, it provides nothing that for a:=b to c does not give.

The whole concept of high-level programming language is to add syntax sugar to the assembly/machine code.
So the question is, indeed, how often this particular sugar would be used. As an example, I have made a quick survey of TAChart code, since it is familiar for me and easily available
for everybody here.
TAChart (with demoes) contains about 410 "for" loops. Of those, 82 are already converted to "for-in". Of the rest, about 200 are iterating over whole containers --
others are partial iteration, coordinate iteration, etc. Of these 200, there are three reasons for not using for-in:
1) Oversight. I convert code are I work on it, so some loops just wait their turn.
2) Modifying the container (I have another extension proposal for these -- "for var i in a" syntax).
3) Requiring loop index -- those are the ones we are interested now. After a quick look, I estimate about 30 such places. So from the above study we can estimate that 5-7% of all "for" loops, and 20-30% of "for-in" loops would benefit from the proposed extension.

Now you propose to extend this "sugar" syntax with something even more exotic, which I have not even encountered in other languages.

PHP:
foreach($array as $index => $value)
...

Python:
for i, item in enumerate(seq):
...

Ruby:
set.each do |item,value|
...
end

Go:
for index, value := range someCollection {
...
}

Objective C:
[items enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) {
…
}];

JavaScript:
array.forEach(function(value, index) {
...
});

Java indeed does not have it.

Perl where every possible idea of every contributor that popped up on a blue monday was implemented and incorporated.

Why do you think so? Just look at the in perl-porters mail archive -- they are very far from "implement every possible idea", I assure you.

Go and propose your idea to the gcc team as an extension to C. let's see how far you get...

C is not a reasonable comparison, since it is much lower level language. I could also go and propose to include classes, sets, strings -- they all do not make sense in C.
Now, C++ is a much better comparison target.
Unfortunately, current pace of evolution for C++ language is incredibly slow. It only for for-in last year, in the latest version of the standard. I think it is reasonable to assume that next version of C++ might include "for-in-index" syntax.
Unfortunately, I also think it is reasonable to estimate the timeframe for that version as 5-7
Alexander S. Klenin

Reply by email

Alexander Klenin
to Graeme Geldenhuys: Enumerators are limited in functionality. Iterators are the full-blown thing. Common…
Graeme Geldenhuys wrote 12 lines
On 01/24/13 19:36, Alexander Klenin wrote: >> Enumerators are not iterators. > Eh... actually, they are? Why do you think otherwise? Enumerators are limited in functionality. Iterators are the full-blown thing. Common Iterator API is something like Next, Prev, Reset, HasNext, HasPrev etc. Enumerators normally just advance and only in one direction. This is how it is in many frameworks. Even Java's documentation describes it like that - see the bottom of the page for Iterator. http://docs.oracle.com/javase/6/docs/technotes/guides/collections/reference.html

I see. However, I also see:
http://docs.oracle.com/javase/6/docs/api/java/util/Enumeration.html "New implementations should consider using Iterator in preference to Enumeration."
So in Java, "enumerator" is basically just a deprecated term for older and weaker version of "iterator".

In the case of Pascal, I would rather say that enumerators are iterators implementing a special interface,
which allow them to be used with a specific syntax.

Alexander S. Klenin

Reply by email

Graeme Geldenhuys
to Alexander Klenin: On Fri, Jan 25, 2013 at 9:36 AM, Michael Van Canneyt Of course you do not, this is why I…
Alexander Klenin wrote 10 lines
>>> If you want full fledged iterators, use classes. >> >> Please provide example of your suggestion for the case in the wiki. > > I don't need to provide *anything*. Of course you do not, this is why I said "please" :) However, it is impossible to have a meaningful discussion without such an example, so could you please indulge me?

Do you want examples of Iterator classes? If so, I have a such implementations I have used for years, and can iterate just about any collection object without issue.

Getting such an Iterator instance is as single line of code.

If that is what you are talking about, I can email you a copy.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Alexander Klenin
to Graeme Geldenhuys: Do you want examples of Iterator classes? If so, I have a such implementations I have…
Graeme Geldenhuys wrote 15 lines
On 01/24/13 23:26, Alexander Klenin wrote: >>>> If you want full fledged iterators, use classes. >>> >>> Please provide example of your suggestion for the case in the wiki. >> >> I don't need to provide *anything*. > > Of course you do not, this is why I said "please" :) > However, it is impossible to have a meaningful discussion without such > an example, > so could you please indulge me? Do you want examples of Iterator classes? If so, I have a such implementations I have used for years, and can iterate just about any collection object without issue.

Not quite. I am aware of various iterator implementations, including yours. What I wanted is an example of implementation Michael suggested, because he said that his variant is better then mine, so a wanted to look at it to compare.

Do I understand correctly that you are speaking about this article: http://opensoft.homeip.net/articles/iterator_pattern.pdf ? As far as I understand, since iterators described in the article do not have the concept of a current item,
they also do not have concept of an index, and hence are not relevant in the context of this discussion.

Alexander S. Klenin

Reply by email

Paul Ishenin
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:18 AM, Jeppe Græsdal Johansen Of course. Alexander S. Klenin

25.01.2013 4:32, Alexander Klenin пишет:

Show quoted text 11 lines
On Fri, Jan 25, 2013 at 7:18 AM, Jeppe Græsdal Johansen wrote: > > I think the idea is good if the feature is implemented as "optional". > > That way: > - If the enumerator class implements a CurrentIndex method then the for loop > can have an index variable. > - If not then the for loop can only behave as current for in loops. > Of course.

Then I also have nothing against this feature. If it is controllable by enumrator to allow/reject this then it is ok.

Best regards,
Paul Ishenin

Reply by email

Василий Кевролетин
to Paul Ishenin

Hi all,

I want to clarify what *feature will be optional* and will not break compatibility. I suppose what back compatibility is required for all minor changes. *I was thinking it's always by default :)*

*Michael Van Canneyt*,

FPC is not the playground for every possible idea out there. If someone wants to implement some weird syntax: please; use FPC to try

and test it, create your dissertation, whatnot.
May be you understood what I'm from university in wrong way. It does *not*mean what I need to quickly do any changes anywhere. It means what I have
resources *(time, motivation, direct support of very good programmer) *to improve good open project. Work will not have any good value for me if results of work will not have any good value for other people.

"For in" is debatable by itself. It is syntactical sugar, it provides
nothing that for a:=b to c does not give.
Now you propose to extend this "sugar" syntax with something even more

exotic, which I have not even encountered in other languages.
1. Syntax is subject of discussion and can be changed.
2. Freepascal already have for-in syntax sugar. Why not to make it more flexible?

Request of this what for-in-index is on fpc wiki. Some other pascal programmers told in this thread what this is good feature. Evolution of other popular programming languages shows what for-in-index loop have real value *(describes by Alexander S. Klenin)*. Implementation of for-in-index will be basad on existing for-in loop. Thus feature will have almost same behavior as for-in loop. All implementation problems described in this thread relate to existing for-in loop. They are not relevant to discussion of for-in-index loop.

I understand why you don't want to support bad features. But I don't understand why reasonable extension of existing feature (which will not break compatibility and which exists in other languages) is bad ? :)

Best regards,
Vasiliy Kevroletin

2013/1/25 Paul Ishenin

Show quoted text 28 lines
25.01.2013 4:32, Alexander Klenin пишет: On Fri, Jan 25, 2013 at 7:18 AM, Jeppe Græsdal Johansen > wrote: > >> >> I think the idea is good if the feature is implemented as "optional". >> >> That way: >> - If the enumerator class implements a CurrentIndex method then the for >> loop >> can have an index variable. >> - If not then the for loop can only behave as current for in loops. >> >> Of course. > Then I also have nothing against this feature. If it is controllable by enumrator to allow/reject this then it is ok. Best regards, Paul Ishenin ______________________________**_________________ fpc-devel maillist - http://lists.freepascal.org/**mailman/listinfo/fpc-devel<http://lists.freepascal.org/mailman/listinfo/fpc-devel>

Reply by email

Paul Ishenin
to Василий Кевролетин

25.01.2013 11:47, Василий Кевролетин пишет:

Show quoted text 6 lines
May be you understood what I'm from university in wrong way. It does *not* mean what I need to quickly do any changes anywhere. It means what I have resources /(time, motivation, direct support of very good programmer) /to improve good open project. Work will not have any good value for me if results of work will not have any good value for other people.

That's good that you have resources and motivation. The question is where to apply them.

I understand why you don't want to support bad features. But I don't understand why reasonable extension of existing feature (which will not break compatibility and which exists in other languages) is bad ? :)

You need to look at another Michael mail where he claims that he was against for-in loop feature when it had going to be implemented. So no suprise that he is against extending it now.

Michael, please don't demotivate our potential compiler developers :)

Let's look how suggested feature makes compiler worse. Some answers I already know, some needs to be clarified:

1. Does it adds new (semi-)reserved words? No, index is already a semi-reserved word which is used for property declaration. So scanner will not be changed.

2. Does it influence other features than for-in loop? As I see, other parts of compiler will not be changed.

3. Will it add much code which is needs to be supported? I don't know but expect it will add not much. Vasiliy, can you put your patch somewhere to look at overall compiler change?

4. Jonas, can you tell about for-in loop for objective-pascal dialect? I know it implementation depends on some Objective-C classes. Do they support current index/key return? Do you against 'index' extension for ObjP dialect and in general?

Best regards,
Paul Ishenin

Reply by email

Michael Van Canneyt
to Paul Ishenin
Paul Ishenin wrote 21 lines
25.01.2013 11:47, Василий Кевролетин пишет: > May be you understood what I'm from university in wrong way. It does > *not* mean what I need to quickly do any changes anywhere. It means what > I have resources /(time, motivation, direct support of very good > programmer) /to improve good open project. Work will not have any good > value for me if results of work will not have any good value for other > people. That's good that you have resources and motivation. The question is where to apply them. > I understand why you don't want to support bad features. But I don't > understand why reasonable extension of existing feature (which will not > break compatibility and which exists in other languages) is bad ? :) You need to look at another Michael mail where he claims that he was against for-in loop feature when it had going to be implemented. So no suprise that he is against extending it now. Michael, please don't demotivate our potential compiler developers :)

Paul,

Sorry, but I most certainly will do this.

It is not because it is technically possible that it must be allowed or done. The use case presented is SO MARGINAL that it does NOT justify another language feature.

less is more:

WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE.

Borland/Inprise/Embarcadero is doing bad enough, we do not need to add it.

Delphi 7 object pascal could be learned very easily. Nowadays with all the "features" added you go, try and explain pascal to someone. Say it is 'nice and readable'.

Well:
It is simply no longer true. Java, Javascript and C have become more easy.

Simply because we are afraid to say 'No sorry, you are on the wrong path'.

If he wants to help, Alexander Klenin had better put his students to useful tasks.

There are plenty to choose from.
He said maybe he'd look after fcl-stl. The silence since was deafening. He said he needed a arbitrary precision math library: Well, get started ! Both should be perfectly within grasp of a student. If he has students, let them work on that.

If they must develop a 'language extension' for practice, using FPC: great. But that does not mean it should be added to FPC's distribution.

Pascal needs more useful libraries. More platforms. But definitely *not* even more shady language features.

Language features can of course be added, but PLEASE with a broader use case.

Once more: simple is beautiful.

Free pascal becomes less so with each of these "features".

Michael.

Reply by email

Graeme Geldenhuys
to Alexander Klenin: On Fri, Jan 25, 2013 at 10:38 AM, Graeme Geldenhuys Not quite. I am aware of various…
Alexander Klenin wrote
Do I understand correctly that you are speaking about this article: http://opensoft.homeip.net/articles/iterator_pattern.pdf ?

Yes.

As far as I understand, since iterators described in the article do not have the concept of a current item,

The current item is returned when you call Next or Previous on the iterator. You use HasNext and HasPrevious in the loop. As the article describes, my Iterator implementation is based on the Java-style where the pointer in the list sits between items - there is a graph of that in the article too.

they also do not have concept of an index, and hence are not relevant in the context of this discussion.

No need for an index value because Next and Previous returns what you need. Also the one Iterator I implemented can take a regular expression (regex), thus you can iterator a list but filtered results are returned. The article shows this somewhere near the end. So the traditional "index" value doesn't or can't apply, because it can skip many or all items in the list.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Fri, Jan 25, 2013 at 9:36 AM, Michael Van Canneyt Of course you do not, this is why I…
Alexander Klenin wrote 11 lines
On Fri, Jan 25, 2013 at 9:36 AM, Michael Van Canneyt wrote: >>> If you want full fledged iterators, use classes. >> >> Please provide example of your suggestion for the case in the wiki. > > I don't need to provide *anything*. Of course you do not, this is why I said "please" :) However, it is impossible to have a meaningful discussion without such an example, so could you please indulge me?

You are totally missing the point.

Finding a use case to justify a feature is not difficult. I could probably find some more use cases to justify other 'missing features'.

The point is: it is not because it can be done, that it must be done.

The point is that with every 'feature' added, the language becomes more and more ugly.

My main worry is that Object Pascal, which used to be a beautiful, easy to learn language is becoming a horrible, complicated, monster of a langauge.

In large part due to Borland/Inprise/Embarcadero going downhill after D7.

This proposal adds once more to the uglyness and complication.

As for the feature being present in some other languages, I stand corrected; Next time I will be more careful in my statements.

Michael.

Reply by email

Michael Van Canneyt
to Martin Schreiber: Agreed. I even would say it becomes more by removing some of the existing "features". ;-)…
Martin Schreiber wrote 8 lines
On Friday 25 January 2013 09:07:27 Michael Van Canneyt wrote: > > Once more: simple is beautiful. > > Free pascal becomes less so with each of these "features". > Agreed. I even would say it becomes more by removing some of the existing "features". ;-)

Hear, hear: Martin and I agree.

After so many years. It brings a tear to my eye ;-)

Michael.

Reply by email

Mattias Gaertner
to Michael Van Canneyt: You are totally missing the point. Finding a use case to justify a feature is not…

Michael Van Canneyt hat am 25. Januar 2013 um 09:26 geschrieben:

Show quoted text 14 lines
[...] You are totally missing the point. Finding a use case to justify a feature is not difficult. I could probably find some more use cases to justify other 'missing features'. The point is: it is not because it can be done, that it must be done. The point is that with every 'feature' added, the language becomes more and more ugly. My main worry is that Object Pascal, which used to be a beautiful, easy to learn language is becoming a horrible, complicated, monster of a langauge.

In general: +1

Even the common syntax highlighters have trouble. I don't know if Delphi's syntax highlighter understand their language fully.

But I must admit the for-in-loop makes code easier to read. I see it with beginners and people coming from other languages. They instantly understand it and use it.
Of course this is only about the loop itself, not how an enumerator is created/declared. That is difficult to understand.

Show quoted text 6 lines
In large part due to Borland/Inprise/Embarcadero going downhill after D7. This proposal adds once more to the uglyness and complication. As for the feature being present in some other languages, I stand corrected; Next time I will be more careful in my statements.

Please keep up the good work and question any new feature.

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 22 lines
Michael Van Canneyt hat am 25. Januar 2013 um 09:26 geschrieben: > [...] > You are totally missing the point. > > Finding a use case to justify a feature is not difficult. > I could probably find some more use cases to justify other 'missing features'. > > The point is: it is not because it can be done, that it must be done. > > The point is that with every 'feature' added, the language becomes > more and more ugly. > > My main worry is that Object Pascal, which used to be a beautiful, > easy to learn language is becoming a horrible, complicated, monster of a > langauge. In general: +1 Even the common syntax highlighters have trouble. I don't know if Delphi's syntax highlighter understand their language fully.

Bah. The Delphi IDE does not even understand include files.

But I must admit the for-in-loop makes code easier to read. I see it with beginners and people coming from other languages. They instantly understand it and use it.

I believe that. In it's simple form, it is indeed easy to understand and use.

Of course this is only about the loop itself, not how an enumerator is created/declared. That is difficult to understand.

I agree. What is more, the way Delphi introduced it is simply braindead.

In this case, I think that the FPC alternative (operator enumerator) is more easy and more pascal-ish.

Michael.

Reply by email

Michael Schnell
to vrt277: There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if…
vrt277 wrote 8 lines
Hi FPC team, There is good proposed extension of for-in loop on fpc wiki: get enumerator Position if available <http://wiki.freepascal.org/for-in_loop#Proposed_extensions>. From my point of view it's essential part of iterators. Especially for data structures which store pairs of key and value associated with key.

Is this (among other purposes) supposed to allow for working with UTF-8 strings in a per-character-index manner ?

-Michael

Reply by email

Marco van de Voort
to Martin Schreiber: Agreed. I even would say it becomes more by removing some of the existing "features". ;-)…

In our previous episode, Martin Schreiber said:

Show quoted text 6 lines
> Once more: simple is beautiful. > > Free pascal becomes less so with each of these "features". > Agreed. I even would say it becomes more by removing some of the existing "features". ;-)

Indeed. I went to look at the generic classes during the gtree discussion, and all FPC generics are in its own incompatible syntax.

This makes it hard for me to contribute anything.

Reply by email

Mattias Gaertner
to Michael Schnell: Is this (among other purposes) supposed to allow for working with UTF-8 strings in a…

Michael Schnell hat am 25. Januar 2013 um 10:35
geschrieben:

Show quoted text 9 lines
On 01/23/2013 12:54 AM, vrt277 wrote: > > Hi FPC team, > > There is good proposed extension of for-in loop on fpc wiki: get > enumerator Position if available > <http://wiki.freepascal.org/for-in_loop#Proposed_extensions> . From my point > of view it's essential part of iterators. E specially for data structures > which store pairs of key and value associated with key.

The above UTF8 example misses some points. Often you need the index and often you need the byte position.
This can be remedied with an enumerator using a record:

type
  TUTF8Enummy = record
    c: UTF8Char;
    ByteIndex: SizeInt;
    UTF8Index: SizeInt;
  end;
  TUTF8StringEnumerator = class
  ...
  public
    constructor Create(const A: UTF8String);
    function Current: TUTF8Enummy;
    function MoveNext: Boolean;
  end;
  ...
var
  s: UTF8String;
  ch: UTF8Char;
begin
  for ch in s do
    Writeln(ch.UTF8Index, ': ', ch.c,' at byte ',ch.ByteIndex);
end.

The compiler already supports such constructs.
It seems this is even more powerful and useful than the proposed 'index' extension.

Mattias

Reply by email

Mattias Gaertner
to Mattias Gaertner

Mattias Gaertner hat am 25. Januar 2013 um 10:52
geschrieben:

Show quoted text 37 lines
Michael Schnell hat am 25. Januar 2013 um 10:35 geschrieben: > On 01/23/2013 12:54 AM, vrt277 wrote: > > > > Hi FPC team, > > > > There is good proposed extension of for-in loop on fpc wiki: get > > enumerator Position if available > > <http://wiki.freepascal.org/for-in_loop#Proposed_extensions> . From my > > point > > of view it's essential part of iterators. E specially for data structures > > which store pairs of key and value associated with key. The above UTF8 example misses some points. Often you need the index and often you need the byte position. This can be remedied with an enumerator using a record: type TUTF8Enummy = record c: UTF8Char; ByteIndex: SizeInt; UTF8Index: SizeInt; end; TUTF8StringEnumerator = class ... public constructor Create(const A: UTF8String); function Current: TUTF8Enummy; function MoveNext: Boolean; end; ... var s: UTF8String;
ch: TUTF8Enummy;
Show quoted text 8 lines
begin for ch in s do Writeln(ch.UTF8Index, ': ', ch.c,' at byte ',ch.ByteIndex); end. The compiler already supports such constructs. It seems this is even more powerful and useful than the proposed 'index' extension.

Mattias

Reply by email

Michael Schnell
to Mattias Gaertner: Michael Schnell hat am 25. Januar 2013 um 10:35 geschrieben: The above UTF8 example…
Mattias Gaertner wrote
The above UTF8 example misses some points....

My question was about the want for a construct that allows for accessing the n'th printable character in an UTF-8 string

Finding the 100000 th and then independently the 100005 th printable character needs quite a lot of CPU time, so it would be nice to have a kind of "enumerator" that (e.g.) in a smart way remembers a set of (Byte_Position / printable_Character_position) pairs helping to quickly find the n'th printable character.

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell
Michael Schnell wrote 10 lines
On 01/25/2013 10:52 AM, Mattias Gaertner wrote: > The above UTF8 example misses some points.... My question was about the want for a construct that allows for accessing the n'th printable character in an UTF-8 string Finding the 100000 th and then independently the 100005 th printable character needs quite a lot of CPU time, so it would be nice to have a kind of "enumerator" that (e.g.) in a smart way remembers a set of (Byte_Position / printable_Character_position) pairs helping to quickly find the n'th printable character.

Pchar ?

Michael.

Reply by email

Michael Schnell
to Michael Van Canneyt
Michael Van Canneyt wrote
Pchar ?

You seem to miss my point: the n'th printable character in an utf-8 coded string (may same be stored as a pchar or a string) starts at the m'th byte (m>=n).

To find m for a given n you need to scan all bytes < m.

Thus a loop such as

for I = 1 to 100000 do begin
   n = Integer (random(100000));
   c = myString[n];
end;

Is rather fast with ANSI coded Strings.

When myString is coded in utf-8, it obviously provides silly code byte instead of printable characters, and replacing the term myString[n] by a straight forward function searching for the n'th printable character will be very slow.

-Michael

Reply by email

Mattias Gaertner
to Michael Schnell: My question was about the want for a construct that allows for accessing the n'th…

Michael Schnell hat am 25. Januar 2013 um 11:09
geschrieben:

On 01/25/2013 10:52 AM, Mattias Gaertner wrote: > The above UTF8 example misses some points.... My question was about the want for a construct that allows for accessing the n'th printable character in an UTF-8 string

Do you mean codepoint?
Printable depends on ligatures and other things.

Finding the 100000 th and then independently the 100005 th printable character needs quite a lot of CPU time

In UTF8, UTF16 and UTF32 it takes 5 steps.

, so it would be nice to have a kind of "enumerator" that (e.g.) in a smart way remembers a set of (Byte_Position / printable_Character_position) pairs helping to quickly find the n'th printable character.

There are plenty of functions for this. You can wrap them into enumerators as demonstrated.

Mattias

Reply by email

Michael Van Canneyt
to Michael Schnell: You seem to miss my point: the n'th printable character in an utf-8 coded string (may…
Michael Schnell wrote 7 lines
On 01/25/2013 11:12 AM, Michael Van Canneyt wrote: > > Pchar ? > You seem to miss my point: the n'th printable character in an utf-8 coded string (may same be stored as a pchar or a string) starts at the m'th byte (m>=n).

I know that.

To find m for a given n you need to scan all bytes < m.

I know that too.

Show quoted text 8 lines
Thus a loop such as for I = 1 to 100000 do begin n = Integer (random(100000)); c = myString[n]; end; Is rather fast with ANSI coded Strings.

Yes, but this is random access in a string.

Enumerators will not help you with random access, only with sequential access.

Michael.

Reply by email

Mattias Gaertner
to Michael Schnell: You seem to miss my point: the n'th printable character in an utf-8 coded string (may…

Michael Schnell hat am 25. Januar 2013 um 11:22
geschrieben:

Show quoted text 18 lines
On 01/25/2013 11:12 AM, Michael Van Canneyt wrote: > > Pchar ? > You seem to miss my point: the n'th printable character in an utf-8 coded string (may same be stored as a pchar or a string) starts at the m'th byte (m>=n). To find m for a given n you need to scan all bytes < m. Thus a loop such as for I = 1 to 100000 do begin n = Integer (random(100000)); c = myString[n]; end; Is rather fast with ANSI coded Strings.

Same silly loop in UTF8:

// find random characters in myString
for I := 1 to 100000 do begin
  n := Integer (random(100000));
  cp := UTF8FindNearestCharStart(PChar(myString),length(myString),n);
end;
When myString is coded in utf-8, it obviously provides silly code byte instead of printable characters, and replacing the term myString[n] by a straight forward function searching for the n'th printable character will be very slow.

Maybe real world examples would be better to prove a point.

Mattias

Reply by email

Daniël Mantione
to Michael Schnell: You seem to miss my point: the n'th printable character in an utf-8 coded string (may…

Op Fri, 25 Jan 2013, schreef Michael Schnell:

Show quoted text 23 lines
On 01/25/2013 11:12 AM, Michael Van Canneyt wrote: > > Pchar ? > You seem to miss my point: the n'th printable character in an utf-8 coded string (may same be stored as a pchar or a string) starts at the m'th byte (m>=n). To find m for a given n you need to scan all bytes < m. Thus a loop such as for I = 1 to 100000 do begin n = Integer (random(100000)); c = myString[n]; end; Is rather fast with ANSI coded Strings. When myString is coded in utf-8, it obviously provides silly code byte instead of printable characters, and replacing the term myString[n] by a straight forward function searching for the n'th printable character will be very slow.

Yes, it is a known fact that this is a weakness of UTF-8. Consider transforming the string to UTF-16, UTF-32 or even an internal datastructure before doing the random access.

Random access inside UTF-8 is an algorithmic time complexity issue. A language extension can only be a band-aid for that.

Daniël

Reply by email

Michael Schnell
to Michael Van Canneyt: I know that. I know that too. Yes, but this is random access in a string. Enumerators…
Michael Van Canneyt wrote 6 lines
Yes, but this is random access in a string. Enumerators will not help you with random access, only with sequential access.

This is why I put enumerator in "", and in this discussion you already said that the OP did not really meant to talk about plain enumerators.

Obviously he wants to have or provide some compiler magic support for non-standard indexing.

-Michael

Reply by email

Michael Van Canneyt
to Michael Schnell: This is why I put enumerator in "", and in this discussion you already said that the OP…
Michael Schnell wrote 9 lines
On 01/25/2013 11:27 AM, Michael Van Canneyt wrote: > > Yes, but this is random access in a string. > > Enumerators will not help you with random access, only with sequential > access. > This is why I put enumerator in "", and in this discussion you already said that the OP did not really meant to talk about plain enumerators.

I think you have me confused with someone else :-)

Michael.

Reply by email

Michael Schnell
to Daniël Mantione: Op Fri, 25 Jan 2013, schreef Michael Schnell: Yes, it is a known fact that this is a…
Daniël Mantione wrote
Yes, it is a known fact that this is a weakness of UTF-8.

Maybe you should say its a feature.

Consider transforming the string to UTF-16, UTF-32 or even an internal datastructure before doing the random access.

This has been already discussed here at any length, resulting in the knowledge that this also does not help in all cases (as all Unicode variants allow for extended codes).

Delphi XE and mse use UTF-16 by default as a (in most cases appropriate) compromise. I suppose, FPC and Lazarus will follow at some point in time, making these discussions less stringent.

A decent smart "indexer" class with appropriate enumerator/iterator-like compiler-magic syntax might help until then and is a lot nicer than the old-fashioned myString[i] notation anyway, on top of being compatible with any future string implementations.

-Michael

Reply by email

Michael Schnell
to Mattias Gaertner: Michael Schnell hat am 25. Januar 2013 um 11:09 geschrieben: Do you mean codepoint?…
Mattias Gaertner wrote
Do you mean codepoint? Printable depends on ligatures and other things.

Both might be desirable. I don't want to define that. This will depend ´on the implementation of the indexer class.

> Finding the 100000 th and then independently the 100005 th printable > character needs quite a lot of CPU time In UTF8, UTF16 and UTF32 it takes 5 steps.

What do you mean by "steps" ?

There are plenty of functions for this. You can wrap them into enumerators as demonstrated.

In fact I easily could do my own implementation of the functionality if I would have the need for it.

The question is whether it would make sens to provide a fast implementation of such a class in the RTL and offer some compiler magic to make it easily usable (e.g. for beginners) and compatible with possible future string types to prevent any porting effort of user code.

-Michael

Reply by email

Mattias Gaertner
to Michael Schnell

Michael Schnell hat am 25. Januar 2013 um 11:58
geschrieben:

Show quoted text 5 lines
On 01/25/2013 11:23 AM, Mattias Gaertner wrote: > Do you mean codepoint? Printable depends on ligatures and other things. Both might be desirable. I don't want to define that. This will depend ´on the implementation of the indexer class.

Ligatures depend on the font. This is outside the scope of the RTL and especially any compiler magic. A rendering library might implement such an enumerator.

>> Finding the 100000 th and then independently the 100005 th printable >> character needs quite a lot of CPU time > In UTF8, UTF16 and UTF32 it takes 5 steps. What do you mean by "steps" ?

I meant if you have the 100000th codepoint you can find the 100005th codepoint in 5 steps.
With current compiler magic you can write an enumerator for this task.

Show quoted text 10 lines
> There are plenty of functions for this. You can wrap them into > enumerators as demonstrated. In fact I easily could do my own implementation of the functionality if I would have the need for it. The question is whether it would make sens to provide a fast implementation of such a class in the RTL and offer some compiler magic to make it easily usable (e.g. for beginners) and compatible with possible future string types to prevent any porting effort of user code.

Please keep in mind that working with strings and working with Unicode are different things.
The old simplicity of 8-bit codepages is a thing of the past. It was an optimization that worked for a few small regions. Programmers must understand that printed characters can not be represented by single numbers.

Mattias

Reply by email

vrt277
to Michael Van Canneyt: Sorry, but I most certainly will do this. It is not because it is technically possible…
Michael Van Canneyt wrote
The use case presented is SO MARGINAL that it does NOT justify another language feature.

What will you do if you have to iterate through keys of hash table ? c++ stl library have own solution for this: iterator returns structure called "pair" which have 2 fields. First field contains key and second field contains value. (It's similar to situation when you have to return 2 values from function. You can define new type called pair and return 2 values. But I doubt someone likes to do it). Now lets compare c++stl-like solution and for-in-index loop solution: c++stl-like solution:
container ----> iterator ----> pair (structure stores key-value) -----> pair.key or pair.value
for-in-loop key solution
container ----> iterator ----> key or value

If he wants to help, Alexander Klenin had better put his students to useful tasks.

Actually you(and all other developers of fpc) should do it. I will describe. I found only one page which describes open issues: http://wiki.freepascal.org/Open_tasks. And you can *not* go to this page from main page of http://www.freepascal.org/. Looks not very contributors-friendly.

Should be you dislike Perl programming language. But visit http://www.perl.org/ and first thing that you will see "That's why we love Perl 5". They love Perl and they show it. If Freepascal is open project then show it. Describe to everyone how he can support fpc.

Best regards,
Vasiliy Kevroletin

Reply by email

Unknown author
to Michael Van Canneyt: Sorry, but I most certainly will do this. It is not because it is technically possible…

Hi,
though not a fpc developer, I strongly want to support Michaels opinion (not specifically addressing this feature).

For me Pascal is the language of choice because of its readability and strictness and simple / clean syntax.

IMO C++ actually evolved C in exactly this direction. Therefore it would be a great mistake to bloat / fragment Pascal with redundant "features" and go exactly the other way round.

IHMO even Delphi does "too much of a 'good' thing" in evolving the language
- and the best example how NOT to do it - is Perl, indeed.

Btw. from the users point of view - there are more urgent things to do. [NOTE that's NOT a hidden complaint/hint!].
d.l.i.w

P.S.:
I got to know Pascal with Turbo Pascal (in fact I'm younger than you might think :) )...
... but - honestly - I still don't understand why Borland introduced classes when there are objects, what the heck are advanced records for... etc. :) Ok, many features are really useful: generics, properties...

Reply by email

Graeme Geldenhuys
to Michael Schnell: You seem to miss my point: the n'th printable character in an utf-8 coded string (may…
Michael Schnell wrote
and replacing the term myString[n] by a straight forward function searching for the n'th printable character will be very slow.

And I am yet to see a real-world example where this is needed. ALL examples I have seen, the developer was already busy iterating the UTF-8 string, so index access wasn't needed.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

vrt277
to Paul Ishenin: 25.01.2013 11:47, Василий Кевролетин пишет: That's good that you…
Paul Ishenin wrote 32 lines
You need to look at another Michael mail where he claims that he was against for-in loop feature when it had going to be implemented. So no suprise that he is against extending it now. Michael, please don't demotivate our potential compiler developers :) Let's look how suggested feature makes compiler worse. Some answers I already know, some needs to be clarified: 1. Does it adds new (semi-)reserved words? No, index is already a semi-reserved word which is used for property declaration. So scanner will not be changed. 2. Does it influence other features than for-in loop? As I see, other parts of compiler will not be changed. 3. Will it add much code which is needs to be supported? I don't know but expect it will add not much. Vasiliy, can you put your patch somewhere to look at overall compiler change? 4. Jonas, can you tell about for-in loop for objective-pascal dialect? I know it implementation depends on some Objective-C classes. Do they support current index/key return? Do you against 'index' extension for ObjP dialect and in general? Best regards, Paul Ishenin _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Hi Paul,

1. scanner will not be changed.
2. It will not influence other features than for-in loop.
3. Link located at end of message. You also can visit https://github.com/vkevroletin/freepascal/compare/master...key-value-iterator in your browser.
4. - (yes there is difficulty with Objective-C, it skipped in my pilot implementation)

P.S.
patch: https://docs.google.com/file/d/0B36IYx_6MNY6bzY2Sm9Hc3o5QlE/edit

Reply by email

Michael Van Canneyt
to vrt277: What will you do if you have to iterate through keys of hash table ? c++ stl library have…
vrt277 wrote 15 lines
On 01/25/2013 07:07 PM, Michael Van Canneyt wrote: > The use case presented is SO MARGINAL that it does NOT justify another > language feature. What will you do if you have to iterate through keys of hash table ? c++ stl library have own solution for this: iterator returns structure called "pair" which have 2 fields. First field contains key and second field contains value. (It's similar to situation when you have to return 2 values from function. You can define new type called pair and return 2 values. But I doubt someone likes to do it). Now lets compare c++stl-like solution and for-in-index loop solution: c++stl-like solution: container ----> iterator ----> pair (structure stores key-value) -----> pair.key or pair.value for-in-loop key solution container ----> iterator ----> key or value

You can do this already. Mattias already showed you how.

Do not let the enumerator return the object, but let it return a record:

Type
   TMyKeyObject = record
     Key : TMyKey;
     Obj : TMyObj;
   end;
Var
  O : TMyKeyObject;
begin
   For O in MyContainer do
     begin
     Writeln(O.Key);
     Writeln(O.Object.ClassName);
     end;

I see nothing wrong with this. It does what you need: return key and value.

Show quoted text 9 lines
> If he wants to help, Alexander Klenin had better put his students to > useful tasks. Actually you(and all other developers of fpc) should do it. I will describe. I found only one page which describes open issues: http://wiki.freepascal.org/Open_tasks. And you can *not* go to this page from main page of http://www.freepascal.org/. Looks not very contributors-friendly.

That is funny :-)

You are new on the list, and so probably do not know this, but I hate wikis. Wikis are - by and large - a perfect example of what goes wrong in IT and in Open Source: Lots of things get started. Few are actually finished.

So anything you tell me about the wiki not being up-to-date is just funny to me :)

Should be you dislike Perl programming language. But visit http://www.perl.org/ and first thing that you will see "That's why we love Perl 5". They love Perl and they show it. If Freepascal is open project then show it. Describe to everyone how he can support fpc.

Well, I already did so in my other replies:

We do not need more language features.

We do need more code libraries.

If you need concrete examples:

- A native Arbitrary-Precision math library is on the list of Alexander Klenin.

From my personal wishlist:

- HTTPS support for fcl-web.
- A complete DBUS solution.
- XML/XSD -> Pascal types (xml mapper from Delphi)
- A PDF rendering engine that does not depend on a GUI.
- Reporting engine that does not depend on a GUI.
- Charting engine that does not depend on a GUI.
- A mechanism to translate Pascal to Javascript. Integrate with Lazarus.
- Lots of web & database tools.
- A way to design native Java bytecode Android apps in Lazarus.

For many things the start of the building blocks are there.

I'm sure there are many more things. Feel free to put them in the WIKI ;)

But they are all practical things you need in everyday programming to solve programming tasks you will get when you work in an IT company. But these are probably not very interesting from an academic point of view...

Michael.

Reply by email

Graeme Geldenhuys
to Michael Schnell: Maybe you should say its a feature. This has been already discussed here at any length,…
Michael Schnell wrote 5 lines
A decent smart "indexer" class with appropriate enumerator/iterator-like compiler-magic syntax might help until then and is a lot nicer than the old-fashioned myString[i] notation anyway, on top of being compatible with any future string implementations.

I think you got programming confused with a magic wand. ;-)

G.

Reply by email

vrt277
to Michael Van Canneyt: You can do this already. Mattias already showed you how. Do not let the enumerator return…
Michael Van Canneyt wrote 5 lines
You are new on the list, and so probably do not know this, but I hate wikis. Wikis are - by and large - a perfect example of what goes wrong in IT and in Open Source: Lots of things get started. Few are actually finished.

Probably you think what mailing list is better ? In mailing list new user will not see even things that was started. I also dislike poorly maintained wiki and poorly maintained software and poorly maintained anything.

We do not need more language features.

Your point of view is clear and immutable. I guess main reason for you to include for-in loop in language was delphi.

But they are all practical things you need in everyday programming to solve programming tasks you will get when you work in an IT company. But these are probably not very interesting from an academic point of view...

Why not? A mechanism to translate Pascal to Javascript is should be interesting even from academic point of view.
As for everyday programming in IT company then I have my own experience and will decide what is useful for me myself :)

You have good wishlist. May be it would be better to store it not in mailing list.

Vasiliy Kevroletin

Reply by email

Michael Van Canneyt
to vrt277
vrt277 wrote 10 lines
On 01/26/2013 12:27 AM, Michael Van Canneyt wrote: > You are new on the list, and so probably do not know this, but I hate > wikis. > Wikis are - by and large - a perfect example of what goes wrong in IT and > in Open Source: > Lots of things get started. Few are actually finished. Probably you think what mailing list is better ? In mailing list new user will not see even things that was started. I also dislike poorly maintained wiki and poorly maintained software and poorly maintained anything.

I am glad we agree.

I do not think that a mailing list is better for keeping lists. I use it for communication only.

> We do not need more language features. Your point of view is clear and immutable. I guess main reason for you to include for-in loop in language was delphi.

It was.

I want to stress that I am not against new language features.

But at the same time I do not think that all possible use cases must be translated to new language features.

The fight against "language bloat" is a difficult balance.

"For in" is there. It can be used in many wonderful ways. As such I do not see the need for an extension.

Show quoted text 5 lines
> But they are all practical things you need in everyday programming to solve > programming tasks you will get when you work in an IT company. But these > are probably not very interesting from an academic point of view... Why not? A mechanism to translate Pascal to Javascript is should be interesting even from academic point of view.

Well:
There are even different possible approaches. Last year a google summer of code proposal was made to achieve this in FPC. I was quite surprised to see that it was totally different from what I myself had in mind.

As for everyday programming in IT company then I have my own experience and will decide what is useful for me myself :)

Of course; I only presented what is on my personal wishlist...

You have good wishlist. May be it would be better to store it not in mailing list.

I can store the list in the WIKI if this is desirable. Although I am afraid it will get lost in the depths of Google anyway ;-)

Michael.

Reply by email

Alexander Klenin
to Michael Van Canneyt: Sorry, but I most certainly will do this. It is not because it is technically possible…
Michael Van Canneyt wrote
WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE.

Hm... Do not you think this is a bit of an overstatement?

There are plenty to choose from. He said maybe he'd look after fcl-stl. The silence since was deafening.

"for-in-index" extension was actually planned by me as a prerequisite for fcl-stl work.
I did some experiments with the current implementation, even discussed it at a conference
related to teaching of algorithmic programming to children. As I have already explained, main competition in this area now comes from Python and
other dynamic languages. While discussing container access in Pascal vs Python, lack of "for-in-index" was brought up by attendees as one of Pascal's weaknesses.

He said he needed a arbitrary precision math library: Well, get started !

I have chosen a good library, communicated with the author, and he agreed (on this list)
to allow its inclusion in FPC. Now somebody (not me, since I do not have commit rights)
should perform the addition.

Both should be perfectly within grasp of a student. If he has students, let them work on that.

Unfortunately there are specific requirements for this type of student work (it is approximately equivalent to bachelor's thesis). "A single large new feature" is much better suited to it then "polishing the library, with many small refactorings and improvements". Note that for Vasily, "for-in-index" if not actually this "large feature", it was chosen by me as a relatively minor and simple feature to introduce him to the code base and the community.
I am sorry that the community turned out not quite welcoming.

Pascal needs more useful libraries.

It is important to note that default libraries ARE part of the language, and from the user's POV language vs library distinction is an irrelevant detail. What is important is a clear, concise and easy-to-remember syntax.

With this in mind, consider a user who wants to iterate over the following array:

var
  a: array [1..5] of Integer = (1, 2, 9, 4, 5);
In my proposal, he should write:
var
  v, i: Integer;
begin
  for a in a index i do
    Writeln(i, ' ', v);
end.
In your proposal, he should write (suppose GIter is a unit
implementing the generic array iterator):
uses
  GIter;
type
  TArrayIntIterator = specialize TArrayIterator<Integer>;
  i: TArrayIntIterator.TElem;
begin
  for i in TArrayIntIterator.Create(a) do
    Writeln(i.Index + Low(a), ' ', i.Value);
end.

Now my point is that second variant is harder to learn and understand then the first one,
regardless of the fact that is uses "simpler" language. And yes, I have code for the second example in my working copy of improved fcl-stl.

Alexander S. Klenin

Reply by email

Sven Barth
to Michael Van Canneyt: I am glad we agree. I do not think that a mailing list is better for keeping lists. I use…
Michael Van Canneyt wrote 14 lines
>> But they are all practical things you need in everyday programming >> to solve programming tasks you will get when you work in an IT >> company. But these are probably not very interesting from an >> academic point of view... > Why not? A mechanism to translate Pascal to Javascript is should be > interesting even from academic point of view. Well: There are even different possible approaches. Last year a google summer of code proposal was made to achieve this in FPC. I was quite surprised to see that it was totally different from what I myself had in mind.

Do you have link for this?

Regards,
Sven

Reply by email

Florian Klämpfl
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt Hm... Do not you think this is a bit…
Alexander Klenin wrote 9 lines
On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt wrote: > WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE. Hm... Do not you think this is a bit of an overstatement? > There are plenty to choose from. He said maybe he'd look after fcl-stl. The > silence since was deafening. "for-in-index" extension was actually planned by me as a prerequisite for fcl-stl work.

Using indicies is against all principles of iterators.

Show quoted text 8 lines
I did some experiments with the current implementation, even discussed it at a conference related to teaching of algorithmic programming to children. As I have already explained, main competition in this area now comes from Python and other dynamic languages. While discussing container access in Pascal vs Python, lack of "for-in-index" was brought up by attendees as one of Pascal's weaknesses.

The idea of iterators is actually to replace and get rid of indicies because they e.g. fail as soon as the iterated container is changed during iteration. Depending on the iterated container, iterators might be still valid even if the container changes.

Show quoted text 10 lines
var a: array [1..5] of Integer = (1, 2, 9, 4, 5); In my proposal, he should write: var v, i: Integer; begin for a in a index i do Writeln(i, ' ', v); end.

In this case I just write

for i:=low(a) to high(a) do
  writeln(i,' ',a[i]);

Works afaik since TP 6.0.

Reply by email

Daniël Mantione
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt Hm... Do not you think this is a bit…

Op Sat, 26 Jan 2013, schreef Alexander Klenin:

Show quoted text 13 lines
With this in mind, consider a user who wants to iterate over the following array: var a: array [1..5] of Integer = (1, 2, 9, 4, 5); In my proposal, he should write: var v, i: Integer; begin for a in a index i do Writeln(i, ' ', v); end.

Well... I fail to see the improvement over old fashioned:

for i:=low(a) to high(a) do
   writeln(i,' ',a[i]);

Daniël

Reply by email

Sven Barth
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt Hm... Do not you think this is a bit…
Alexander Klenin wrote 7 lines
> He said he needed a arbitrary precision math library: Well, get started ! I have chosen a good library, communicated with the author, and he agreed (on this list) to allow its inclusion in FPC. Now somebody (not me, since I do not have commit rights) should perform the addition.

Do you have a link to the message? It could have been gotten lost in the usual mailing list traffic...

I am sorry that the community turned out not quite welcoming.

You should not generalize here. There were devs (e.g. Paul) and also users who didn't object. Others did indeed object. But we're humans after all... not every one has the same opinion. Take myself: I consider myself neutral in this topic. I'm neither really pro nor against this feature.

Regards,
Sven

Reply by email

Alexander Klenin
to Florian Klämpfl: Using indicies is against all principles of iterators. The idea of iterators is actually…
Florian Klämpfl wrote
> "for-in-index" extension was actually planned by me as a prerequisite > for fcl-stl work. Using indicies is against all principles of iterators.

I am not sure what princilpes you are talking about, but accessing the key of the current element is required quite often and provided by iterator implementations in many programming languages (except for Java, as discussed above).
I have already provided examples.

The idea of iterators is actually to replace and get rid of indicies because they e.g. fail as soon as the iterated container is changed during iteration. Depending on the iterated container, iterators might be still valid even if the container changes.

This is true, but was no relevance to the syntax extension discussed here. Note that there is no limitation on the type of index, and of course it is not required that the indices are monotonously increasing integers.

Show quoted text 15 lines
> var > a: array [1..5] of Integer = (1, 2, 9, 4, 5); > > In my proposal, he should write: > var > v, i: Integer; > begin > for v in a index i do > Writeln(i, ' ', v); > end. In this case I just write for i:=low(a) to high(a) do writeln(i,' ',a[i]);

Consider these arguments:
1) Even for simple arrays, depending on array element type, and optimizer implementation, for-in can be more efficient since it can avoid multiplication for element access.
2) If "a" is a function of another complex expression returning an array, then "for-in" may be much more efficient and compact
3) If "a" is an associative array (so i is a String), then the "traditional" form of loop is not even possible.
4) If there is no uniform method for iterating over containers, then each container will define its own method,
with the end result that the language will be *more* complex for the user, who will have to remember all these methods.

Alexander S. Klenin

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt Hm... Do not you think this is a bit…
Alexander Klenin wrote
On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt wrote: > WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE. Hm... Do not you think this is a bit of an overstatement?

No, not really.
I really feel that we are deviating a lot from what pascal stands for.

Show quoted text 11 lines
> There are plenty to choose from. He said maybe he'd look after fcl-stl. The > silence since was deafening. "for-in-index" extension was actually planned by me as a prerequisite for fcl-stl work. I did some experiments with the current implementation, even discussed it at a conference related to teaching of algorithmic programming to children. As I have already explained, main competition in this area now comes from Python and other dynamic languages. While discussing container access in Pascal vs Python, lack of "for-in-index" was brought up by attendees as one of Pascal's weaknesses.

You can always find things missing in any language.

I miss compilation, and other low-level things in Python.

It depends on what you value.

Show quoted text 6 lines
> He said he needed a arbitrary precision math library: Well, get started ! I have chosen a good library, communicated with the author, and he agreed (on this list) to allow its inclusion in FPC. Now somebody (not me, since I do not have commit rights) should perform the addition.

Great news !

Show quoted text 11 lines
> Both should be perfectly within grasp of a student. > If he has students, let them work on that. Unfortunately there are specific requirements for this type of student work (it is approximately equivalent to bachelor's thesis). "A single large new feature" is much better suited to it then "polishing the library, with many small refactorings and improvements". Note that for Vasily, "for-in-index" if not actually this "large feature", it was chosen by me as a relatively minor and simple feature to introduce him to the code base and the community. I am sorry that the community turned out not quite welcoming.

You could have asked in advance and be spared the disappointment.

> Pascal needs more useful libraries. It is important to note that default libraries ARE part of the language

You are wrong there.

I am talking about libraries that perform actual tasks. Not containers. PDF generating, https protocol and whatnot.
Those are definitely not part of the language.

and from the user's POV language vs library distinction is an irrelevant detail.

We have different ideas of what libraries are.
The STL is not what I have in mind when I speak about a library.

What is important is a clear, concise and easy-to-remember syntax.

Exactly. But we seem to have different ideas about what that is.

The student will have to remember 4 different syntaxes.

For a:=b to c do
for a:=b downto c do
for a in b do
for a in b index c do

Concise ? I don't think so.

And let us not forget that the last one is a highly abstract one, because you need a lot of concepts before you can explain why it is needed and how to use it.
The first one, by contrast, is so simple that any 12-year old can get it.

Michael.

Reply by email

Hans-Peter Diettrich
to Michael Schnell: My question was about the want for a construct that allows for accessing the n'th…
On 01/25/2013 10:52 AM, Mattias Gaertner wrote: > The above UTF8 example misses some points.... My question was about the want for a construct that allows for accessing the n'th printable character in an UTF-8 string

Everybody can write such a subroutine, when really needed. Or use what the RTL provides for such purpose...

Show quoted text 5 lines
Finding the 100000 th and then independently the 100005 th printable character needs quite a lot of CPU time, so it would be nice to have a kind of "enumerator" that (e.g.) in a smart way remembers a set of (Byte_Position / printable_Character_position) pairs helping to quickly find the n'th printable character.

I think that you are abusing strings for demonstration purposes only. I bet that you really wanted the 100001th character, because you made an mistake while counting characters, or that you missed to organize your super-long string into smaller pieces (lines, columns...).

DoDi

Reply by email

Daniël Mantione
to Alexander Klenin: I am not sure what princilpes you are talking about, but accessing the key of the current…

Op Sat, 26 Jan 2013, schreef Alexander Klenin:

Show quoted text 19 lines
>> var >> a: array [1..5] of Integer = (1, 2, 9, 4, 5); >> >> In my proposal, he should write: >> var >> v, i: Integer; >> begin >> for v in a index i do >> Writeln(i, ' ', v); >> end. > > In this case I just write > > for i:=low(a) to high(a) do > writeln(i,' ',a[i]); Consider these arguments: 1) Even for simple arrays, depending on array element type, and optimizer implementation, for-in can be more efficient since it can avoid multiplication for element access.

True, but it shouldn't. Loop induction is such a well documented optimization that implementation of that optimization (could be a nice job for a student) is by far preferable over mutilating the language.

2) If "a" is a function of another complex expression returning an array, then "for-in" may be much more efficient and compact

Again true, but again easy to avoid: temp variable, with statement, common subexpression elimination. Again these are all preferable over mutilating the language.

3) If "a" is an associative array (so i is a String), then the "traditional" form of loop is not even possible.

Disagree. You need to define a mapping between an ordinal type and the index type. This is always possible (otherwise for-in would be impossible to implement).

4) If there is no uniform method for iterating over containers, then each container will define its own method, with the end result that the language will be *more* complex for the user, who will have to remember all these methods.

This I consider a valid argument, and it affects the fundament of what a for loop is. A for loop iterates over the keys only, while the values are retrieved by [] syntax. This is perfectly possible even for non-numeric keys as we have properties that allow you to do a['elephant'].

The for-in syntax violates this fundamental property by returning values, which means there is a lack of a key. The fundamentalistic view then says we should not have for-in in Pascal, because it changes the fundamental property of a for-loop.

For pragmantic reasons the for-in syntax got supported. However, when using it you discover the lack of keys. So you want to repair something that's already broken by design.

The question becomes, which is worse? Further mutilation? Or stick to the basics?

Daniël

Reply by email

Sven Barth
to Alexander Klenin: On Fri, Jan 25, 2013 at 7:07 PM, Michael Van Canneyt Hm... Do not you think this is a bit…
Alexander Klenin wrote 25 lines
With this in mind, consider a user who wants to iterate over the following array: var a: array [1..5] of Integer = (1, 2, 9, 4, 5); In my proposal, he should write: var v, i: Integer; begin for a in a index i do Writeln(i, ' ', v); end. In your proposal, he should write (suppose GIter is a unit implementing the generic array iterator): uses GIter; type TArrayIntIterator = specialize TArrayIterator<Integer>; i: TArrayIntIterator.TElem; begin for i in TArrayIntIterator.Create(a) do Writeln(i.Index + Low(a), ' ', i.Value); end.

One could also do an alternative (though currently not with arrays, but with type helper support even that would be possible...):

=== code begin ===

type
   // let's assume we extend fgl.TFPGMap a bit
   TFPGMap<Key, Data> = class
   public type
     TIteratorProc = procedure(const aKey: Key; const aValue: Data);
   public
     procedure Iterate(aProc: TIteratorProc);
   end;
// skipping the implementation of TFPGMap.Iterate...
// somewhere else
   procedure Iterator(const aKey: String; const aValue: TObject);
   begin
     Writeln(aKey, ' => ', aValue.ClassName);
   end;
type
   TFPGMapStringTObject = specialize TFPGMap<String, TObject>;
var
   map: TFPGMapStringTObject;
begin
   // set up map
   map.Iterate(@Iterator);
end;

=== code end ===

With support for anonymous functions (and changing TIteratorProc to "reference to procedure(...)") it even becomes:

=== code begin ===

begin
   map.Iterate(procedure(const aKey: String; const aValue: TObject)
     begin
       Writeln(aKey, ' => ', aValue.ClassName);
     end;
   );
end;

=== code end ===

And for a given array type and type helper support you can do the following:

=== code begin ===

var
   t: TLongIntArray; // there exists a helper for this type that
implements a Iterate function
begin
   // set up t
   t.Iterate(@Iterator);
   // or
   t.Iterate(procedure(const aIndex, aData: LongInt)
     begin
       Writeln(aIndex, ' => ', aData);
     end;
   );
end;

=== code end ===

In all cases the iterate function would iterate the "container" type with a fitting algorithm and just call the given function with the necessary data. This is in my opinion a rather flexible way of dealing with iteration (by adding additional arguments you could for example influence the iteration direction).

Regards,
Sven

Reply by email

Florian Klämpfl
to Alexander Klenin: I am not sure what princilpes you are talking about, but accessing the key of the current…
Alexander Klenin wrote 6 lines
On Sat, Jan 26, 2013 at 3:30 AM, Florian Klämpfl wrote: >> "for-in-index" extension was actually planned by me as a prerequisite >> for fcl-stl work. > > Using indicies is against all principles of iterators. I am not sure what princilpes you are talking about,

The theory of iterators.

but accessing the key of the current element is required quite often and provided by iterator implementations in many programming languages

The approach to do so is to use a random access iterator in this case.

(except for Java, as discussed above). I have already provided examples.

Where? Concrete code of a serious language! Not some "oh, yes, this language has it and that as well"

Reply by email

Michael Van Canneyt
to Sven Barth: One could also do an alternative (though currently not with arrays, but with type helper…
Sven Barth wrote 29 lines
On 25.01.2013 17:18, Alexander Klenin wrote: > With this in mind, consider a user who wants to iterate over the > following array: > > var > a: array [1..5] of Integer = (1, 2, 9, 4, 5); > > In my proposal, he should write: > var > v, i: Integer; > begin > for a in a index i do > Writeln(i, ' ', v); > end. > > In your proposal, he should write (suppose GIter is a unit > implementing the generic array iterator): > uses > GIter; > type > TArrayIntIterator = specialize TArrayIterator<Integer>; > i: TArrayIntIterator.TElem; > begin > for i in TArrayIntIterator.Create(a) do > Writeln(i.Index + Low(a), ' ', i.Value); > end. One could also do an alternative (though currently not with arrays, but with type helper support even that would be possible...):

Talk about a choice between the plague and cholera...

If I must choose between the proposed extension of for in index do and having anonymous functions, then I choose for for in index :) (and most likely ending up with both monstrosities)

Pascal is an explicitly declarative language.
Anonymous functions go 100% against this.
It is the readability horror I associate with Javascript.

I often wonder: why do people who seem to think that Pascal misses so many - apparently essential - things, even bother to use it ?

If I thought Pascal was missing so many things, I would simply use something else instead of trying to turn it into something that it is not.

Michael.

Reply by email

Alexander Klenin
to Michael Van Canneyt: No, not really. I really feel that we are deviating a lot from what pascal stands for.…
Michael Van Canneyt wrote
>> WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE. > Hm... Do not you think this is a bit of an overstatement? No, not really. I really feel that we are deviating a lot from what pascal stands for.

If you mean the original Wirth's definition -- then yes, of course any change to the language
does move it away from the initial state.
However, I am strongly against such a "walled garden" approach to the language design.
The state of the art in programming languages has advanced considerably in the last 40 years,
and the set of features expected from modern language has become quite different too.
I disagree that freezing at Wirth's (or current, or any fixed) definition is a useful plan for
Pascal development.

You can always find things missing in any language. I miss compilation, and other low-level things in Python. It depends on what you value.

I certainly agree that Pascal has some advantages -- and they often outweigh disadvantages.
Otherwise, I would be in Python's mailing list now, arguing to add some of the Pascal's features :)
However, this does not mean that disadvantages should be just ignored.

>> Pascal needs more useful libraries. > It is important to note that default libraries ARE part of the language You are wrong there.

Well, this is a matter of opinion of course, but note that your opinion on this topic
is again different from the usual one:

Python: google "batteries included"
C++: http://stackoverflow.com/questions/5460541/is-the-c-standard-library-part-of-the-c-language Java: for example, a string literal is defined as an instance of the java.lang.String class
PHP: it is of course bad design, but for a long time there was not even a notion of "library", all standard methods were accessible directly at language level
Pascal: note that both the original definition and the ISO standard include a set of input/output and mathematical functions, which comprise the standard library. It is a poor library, but nevertheless included in the language definition.
... etc.

I am talking about libraries that perform actual tasks. Not containers. PDF generating, https protocol and whatnot. Those are definitely not part of the language.

Yes, and even those. For example, lack of network support in C++ standard library is
widely considered a disadvantage for the language. Conversely, presence of such support in Go and Python is hailed as good language feature.
Note that technically, of course, the distinction exist -- what I am talking about is that
from user's POV they are the same.

Show quoted text 8 lines
The student will have to remember 4 different syntaxes. For a:=b to c do for a:=b downto c do for a in b do for a in b index c do Concise ? I don't think so.

Compared to the 10 methods of iterating over container just in the current FPC+Lazarus code? Yes, I think this *is* concise and clear.

And let us not forget that the last one is a highly abstract one, because you need a lot of concepts before you can explain why it is needed and how to use it. The first one, by contrast, is so simple that any 12-year old can get it.

Actually, I do teach young students (12 years old is somewhat too young, but 13-14 is usual).
I can tell you they have *more* trouble with Pascal style of loop with indexing as compared to Python's for-each with index.

Alexander S. Klenin

Reply by email

waldo kitty
to Florian Klämpfl: Using indicies is against all principles of iterators. The idea of iterators is actually…
Florian Klämpfl wrote 16 lines
Am 25.01.2013 17:18, schrieb Alexander Klenin: > var > a: array [1..5] of Integer = (1, 2, 9, 4, 5); > > In my proposal, he should write: > var > v, i: Integer; > begin > for a in a index i do > Writeln(i, ' ', v); > end. In this case I just write for i:=low(a) to high(a) do writeln(i,' ',a[i]);

that's *exactly* what i was going to write in reply but i'm glad i read on and saw that someone else had already done so...

Works afaik since TP 6.0.

yep! at least that far back... i use it daily, even today as i try to move more and more to FPC... the above is also perfect pascal syntax... a simple and easy to read and understand flow :)

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Sat, Jan 26, 2013 at 4:38 AM, Michael Van Canneyt If you mean the original Wirth's…
Alexander Klenin wrote 16 lines
On Sat, Jan 26, 2013 at 4:38 AM, Michael Van Canneyt wrote: >>> WITH EACH ADDITIONAL "FEATURE" WE ARE BUTCHERING PASCAL MORE AND MORE. >> Hm... Do not you think this is a bit of an overstatement? > No, not really. I really feel that we are deviating a lot from what pascal stands for. If you mean the original Wirth's definition -- then yes, of course any change to the language does move it away from the initial state. However, I am strongly against such a "walled garden" approach to the language design. The state of the art in programming languages has advanced considerably in the last 40 years, and the set of features expected from modern language has become quite different too. I disagree that freezing at Wirth's (or current, or any fixed) definition is a useful plan for Pascal development.

I don't see it like that. Donald Knuth declared TeX as finished. Despite that, it has been doing just fine for its intended purpose.

Show quoted text 8 lines
> You can always find things missing in any language. > I miss compilation, and other low-level things in Python. > It depends on what you value. I certainly agree that Pascal has some advantages -- and they often outweigh disadvantages. Otherwise, I would be in Python's mailing list now, arguing to add some of the Pascal's features :) However, this does not mean that disadvantages should be just ignored.

I didn't say that.

Like I said, I am not against new language features per se. I just don't think that this one is one that should be added.

Show quoted text 5 lines
>>> Pascal needs more useful libraries. >> It is important to note that default libraries ARE part of the language > You are wrong there. Well, this is a matter of opinion of course, but note that your opinion on this topic is again different from the usual one:

If I cared about 'usual opinion', I would be using C#.

Show quoted text 23 lines
> I am talking about libraries that perform actual tasks. Not containers. > PDF generating, https protocol and whatnot. Those are definitely not part of > the language. Yes, and even those. For example, lack of network support in C++ standard library is widely considered a disadvantage for the language. Conversely, presence of such support in Go and Python is hailed as good language feature. Note that technically, of course, the distinction exist -- what I am talking about is that from user's POV they are the same. > The student will have to remember 4 different syntaxes. > > For a:=b to c do > for a:=b downto c do > for a in b do > for a in b index c do > > Concise ? I don't think so. Compared to the 10 methods of iterating over container just in the current FPC+Lazarus code? Yes, I think this *is* concise and clear.

There is only 1 method:

for i:=0 to I.Count-1.
Show quoted text 9 lines
> And let us not forget that the last one is a highly abstract one, because > you need a lot of concepts before you can explain why it is needed and how > to use it. The first one, by contrast, is so simple that any 12-year old can > get it. Actually, I do teach young students (12 years old is somewhat too young, but 13-14 is usual). I can tell you they have *more* trouble with Pascal style of loop with indexing as compared to Python's for-each with index.

You want to tell me that

for i:=1 to 10 do
   Writeln(i);

is less clear than

for i in range(1,10)
printf(i) # or whatever python uses.

For someone versed in Python, I can imagine that probably is so.

But I learned from BASIC, and had absolutely no problem understanding it.

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt: Talk about a choice between the plague and cholera... If I must choose between the…
Michael Van Canneyt wrote 36 lines
On Fri, 25 Jan 2013, Sven Barth wrote: > On 25.01.2013 17:18, Alexander Klenin wrote: >> With this in mind, consider a user who wants to iterate over the >> following array: >> >> var >> a: array [1..5] of Integer = (1, 2, 9, 4, 5); >> >> In my proposal, he should write: >> var >> v, i: Integer; >> begin >> for a in a index i do >> Writeln(i, ' ', v); >> end. >> >> In your proposal, he should write (suppose GIter is a unit >> implementing the generic array iterator): >> uses >> GIter; >> type >> TArrayIntIterator = specialize TArrayIterator<Integer>; >> i: TArrayIntIterator.TElem; >> begin >> for i in TArrayIntIterator.Create(a) do >> Writeln(i.Index + Low(a), ' ', i.Value); >> end. > > One could also do an alternative (though currently not with arrays, > but with type helper support even that would be possible...): Talk about a choice between the plague and cholera...

I know why I first added the example with a normal (nested) procedure.

If I must choose between the proposed extension of for in index do and having anonymous functions, then I choose for for in index :) (and most likely ending up with both monstrosities)

Though it might be easier to "fight" against the "for-in-index" as anonymous functions are supported by Delphi... ;)

Show quoted text 5 lines
Pascal is an explicitly declarative language. Anonymous functions go 100% against this. It is the readability horror I associate with Javascript.

The syntax is indeed very ugly. I personally would prefer real lambda expressions(!) more. To use the example from my previous mail:

=== example begin ===

map.Iterate(lambda TFPGMapLongInt.TIteratorProc(aKey, aData) as
Writeln(aKey, ' => ', aData.ClassName));

=== example end ===

I'm in so far in favor of anonymous methods (or lamda expressions) as they allow you to keep the logic together (in the example the fact of iterating with what the iteration does). Another example which would apply to TThread (I'll use my lamdba syntax again):

=== example begin ===

Queue(lamda TProc as fSomeReferencedMemo.Lines.Add(fSomeText));

=== example end ===

I think this is more understandable/readable than having to add a "AddTextToMemo" method and a "fTextToAdd" field and then Synchronize/Queue that method...

I often wonder: why do people who seem to think that Pascal misses so many - apparently essential - things, even bother to use it ?

I personally wouldn't call many of these features essential, this includes anonymous functions and helper types equally. You can achieve what they provide yourself, but if the compiler aids you with this, you can move a part of the responsibility for correct code to the compiler (which should be considered a good think from the POV of a user) and it can also increase the readability.

If I thought Pascal was missing so many things, I would simply use something else instead of trying to turn it into something that it is not.

Languages evolve. Natural languages as well as programming languages. We might not agree with every change (e.g. in German there has been established the nasty habit of saying "that makes sense" ("das macht Sinn") while the correct equivalent would be "that has sense" ("das hat Sinn") or "that is sensful" ("das ist sinnvoll")), but we can not stop this evolution. Languages that don't evolve are dead, because noone speaks them anymore (as everyone will always add his one character to the language, though granted this is not as easy for programming languages as you need to work in the compiler/interpreter). Hadn't Borland decided to bring out Delphi and thus the completely different object model (which I personally think is in most points superior to TP style objects, to those have their pros, too), but instead kept e.g. Turbo Pascal for Windows we might not be talking together here today.

Regards,
Sven

Reply by email

Alexander Klenin
to Daniël Mantione: Op Sat, 26 Jan 2013, schreef Alexander Klenin: True, but it shouldn't. Loop induction is…
Daniël Mantione wrote 7 lines
> Consider these arguments: > 1) Even for simple arrays, depending on array element type, > and optimizer implementation, for-in can be more efficient since it > can avoid multiplication for element access. True, but it shouldn't. Loop induction is such a well documented optimization that implementation of that optimization (could be a nice job for a student) is by far preferable over mutilating the language.

I argee. Still, for the general container such an optimization is hard-to-impossible to implement.

Show quoted text 5 lines
> 2) If "a" is a function of another complex expression returning an > array, then "for-in" may be much more efficient and compact Again true, but again easy to avoid: temp variable, with statement, common subexpression elimination. Again these are all preferable over mutilating the language.

"with" statement of of course not help (try it).
CSE might help, but is tricky across function boundaries -- function must be first proven to be pure,
which is non-trivial in Pascal.
temp variable is, of course, always a solution -- but so is using while loop or even labels and goto. I am tying to make Pascal higher-level language, as opposed to, e.g. C, which is determined to stay at low level.

Show quoted text 5 lines
> 3) If "a" is an associative array (so i is a String), then the > "traditional" form of loop is not even possible. Disagree. You need to define a mapping between an ordinal type and the index type. This is always possible (otherwise for-in would be impossible to implement).

Please try to define a mapping between String and Integer :)

Show quoted text 9 lines
> 4) If there is no uniform method for iterating over containers, then > each container will define its own method, > with the end result that the language will be *more* complex for the > user, who will have to remember all these methods. This I consider a valid argument, and it affects the fundament of what a for loop is. A for loop iterates over the keys only, while the values are retrieved by [] syntax. This is perfectly possible even for non-numeric keys as we have properties that allow you to do a['elephant'].

First, for-in loop is not a for-loop. It is unfortunate that due to the need to avoid new reserved words, "for" war chosen instead of more logical "foreach" or even "for each".
But nevertheless, they should not be confused.
Similarly, I have chosen "index" instead of more logical "key", which tricked some developers into thinking that I am talking about indeger indexes only.
Second, accessing the associative array element via key has non-trivial cost, which is avoided by using foreach-type loops.

The for-in syntax violates this fundamental property by returning values, which means there is a lack of a key. The fundamentalistic view then says we should not have for-in in Pascal, because it changes the fundamental property of a for-loop.

"fundamentalistic" is a right word here.

For pragmantic reasons the for-in syntax got supported. However, when using it you discover the lack of keys. So you want to repair something that's already broken by design.

I do not see why it is broken -- only because it is contrary to the fundamentalist view?

Alexander S. Klenin

Reply by email

Sven Barth
to Michael Van Canneyt: I don't see it like that. Donald Knuth declared TeX as finished. Despite that, it has…
Michael Van Canneyt wrote 11 lines
On Sat, 26 Jan 2013, Alexander Klenin wrote: >>>> Pascal needs more useful libraries. >>> It is important to note that default libraries ARE part of the language >> You are wrong there. > Well, this is a matter of opinion of course, but note that your > opinion on this topic is again different from the usual one: If I cared about 'usual opinion', I would be using C#.

Or Java ^^

Show quoted text 16 lines
>> The student will have to remember 4 different syntaxes. >> >> For a:=b to c do >> for a:=b downto c do >> for a in b do >> for a in b index c do >> >> Concise ? I don't think so. > > Compared to the 10 methods of iterating over container just in the > current > FPC+Lazarus code? Yes, I think this *is* concise and clear. There is only 1 method: for i:=0 to I.Count-1.

I think he also means things like (without critizing):

MyDataSet.First;
while not MyDataset.Eof do begin
   // ...
   MyDataSet.Next;
end;
// on a sidenote: what about a TDataSet enumerator? :)
for i := 0 to MyWinControl.ChildCount - 1 do
   // ...
for i := 0 to MyWinControl.ControlCount - 1 do
   // ...

There might be more, but I don't remember them currently... :(

Regards,
Sven

Reply by email

Alexander Klenin
to Sven Barth
Sven Barth wrote
I think he also means things like (without critizing):

Yes, thank for a dose of sanity :)

Few more examples, taken from just one standard package:

while Node.NextBrothernil do begin
  ...
  Node:=Node.NextBrother;
end;
while Nodenil do begin
  ...
  Node:=Node.Next;
end;
while Nodenil do begin
  ...
  Node:=Node.NextSibling;
end;
while Resultnil do begin
  ...
  Result:=Result.NextError;
end;
Show quoted text 6 lines
MyDataSet.First; while not MyDataset.Eof do begin // ... MyDataSet.Next; end; // on a sidenote: what about a TDataSet enumerator? :)

It is not clear what should loop variable contain: for v in MyDataSet do ... -- what is v?

Alexander S. Klenin

Reply by email

Daniël Mantione
to Alexander Klenin: On Sat, Jan 26, 2013 at 5:12 AM, Daniël Mantione I argee. Still, for the general…

Op Sat, 26 Jan 2013, schreef Alexander Klenin:

Show quoted text 11 lines
On Sat, Jan 26, 2013 at 5:12 AM, Daniël Mantione wrote: >> Consider these arguments: >> 1) Even for simple arrays, depending on array element type, >> and optimizer implementation, for-in can be more efficient since it >> can avoid multiplication for element access. > True, but it shouldn't. Loop induction is such a well documented > optimization that implementation of that optimization (could be a nice job > for a student) is by far preferable over mutilating the language. I argee. Still, for the general container such an optimization is hard-to-impossible to implement.

?? For the general container figher['ninja'] would not be implemented by multiplication.

Show quoted text 6 lines
>> 2) If "a" is a function of another complex expression returning an >> array, then "for-in" may be much more efficient and compact > Again true, but again easy to avoid: temp variable, with statement, common > subexpression elimination. Again these are all preferable over mutilating > the language. "with" statement of of course not help (try it).

If you cannot use with directly, wrap the array inside a record.

Show quoted text 6 lines
CSE might help, but is tricky across function boundaries -- function must be first proven to be pure, which is non-trivial in Pascal. temp variable is, of course, always a solution -- but so is using while loop or even labels and goto. I am tying to make Pascal higher-level language, as opposed to, e.g. C, which is determined to stay at low level.

I understand your goal, which is commendable. The challenge is to do it in a way that doesn't turn Pascal in something it is not.

Please try to define a mapping between String and Integer :)
const integer2fighter:array[0..3] of string=('knight','ninja','samurai','swordman');
function fighter2integer(const s:string):integer;
begin
   {implement binary search}
end;
Show quoted text 24 lines
>> 4) If there is no uniform method for iterating over containers, then >> each container will define its own method, >> with the end result that the language will be *more* complex for the >> user, who will have to remember all these methods. > > This I consider a valid argument, and it affects the fundament of what a for > loop is. A for loop iterates over the keys only, while the values are > retrieved by [] syntax. This is perfectly possible even for non-numeric keys > as we have properties that allow you to do a['elephant']. First, for-in loop is not a for-loop. It is unfortunate that due to the need to avoid new reserved words, "for" war chosen instead of more logical "foreach" or even "for each". But nevertheless, they should not be confused. Similarly, I have chosen "index" instead of more logical "key", which tricked some developers into thinking that I am talking about indeger indexes only. Second, accessing the associative array element via key has non-trivial cost, which is avoided by using foreach-type loops. > The for-in syntax violates this fundamental property by returning values, > which means there is a lack of a key. The fundamentalistic view then says we > should not have for-in in Pascal, because it changes the fundamental > property of a for-loop. "fundamentalistic" is a right word here.

Yes... because it's wrong to always stick to principles if practical problems are to be solved. But it's also wrong to add too much pragmatic exceptions: With software it becomes hard to maintain, with programmings languages it becomes unelegant and hard to learn.

Pascal was such a breakthough in the 1970's because of its elegance. That should always be kept in mind when extending the language. (And has been forgotten too often unfortunately.)

Show quoted text 5 lines
> For pragmantic reasons the for-in syntax got supported. However, when using > it you discover the lack of keys. So you want to repair something that's > already broken by design. I do not see why it is broken -- only because it is contrary to the fundamentalist view?

Bottom line: yes. Language design is a lot about esthetics. Having many syntaxes for things as simple as a for loop is bad tasted. The amount of syntax is getting out of hand.

Daniël

Reply by email

Alexander Klenin
to Florian Klämpfl: The theory of iterators. The approach to do so is to use a random access iterator in this…
Florian Klämpfl wrote 5 lines
Am 25.01.2013 18:17, schrieb Alexander Klenin: >> Using indicies is against all principles of iterators. > I am not sure what princilpes you are talking about, The theory of iterators.

You mean Alexander Stepanov's ideas which served as a basis for STL? If so, you may notice that STL does include the concept of <key, value> pair which is returned by iterators on maps.
Also note that Pascal and C++ is are quite different designs -- C++ usually sacrifices readability for the sake of reducing the number of language features,
while Pascal traditionally followed an opposite direction. (E.g. built-in String vs, std::string).
So while with the latest improvements to the generics it is almost possible to replicate C++ STL design, I think that it is not correct way. I would prefer the approach of Go language, which does include direct syntax support for
the most often used constructs even if they can be simulated using libraries. For example, I do think that despite existence of fcl-stl, Pascal would benefit from direct
inclusion of simple associative arrays:
var a: array [String] of Integer;
Yes, it is a duplication of concepts, but it would make a life of a programmer simpler.

> I have already provided examples. Where? Concrete code of a serious language! Not some "oh, yes, this language has it and that as well"

I am afraid that it is very hard for me to discuss against such statements. Do you consider Java "serious" while Python, Ruby, PHP, Objective C etc "not serious"?
What is "concrete code"? The code I provided only missed loop bodies. I can provide that too, but I do not think it will add anything to the discussion.

Alexander S. Klenin

Reply by email

Sven Barth
to Alexander Klenin
Alexander Klenin wrote 10 lines
>> I have already provided examples. > > Where? Concrete code of a serious language! Not some "oh, yes, this > language has it and that as well" I am afraid that it is very hard for me to discuss against such statements. Do you consider Java "serious" while Python, Ruby, PHP, Objective C etc "not serious"? What is "concrete code"? The code I provided only missed loop bodies. I can provide that too, but I do not think it will add anything to the discussion.

I believe he wants to have real world examples (of other languages) where this feature is used. E.g. in some well respected software, library, etc.

Regards,
Sven

Reply by email

Mark Morgan Lloyd
to Sven Barth: I know why I first added the example with a normal (nested) procedure. Though it might be…
Sven Barth wrote 13 lines
Languages evolve. Natural languages as well as programming languages. We might not agree with every change (e.g. in German there has been established the nasty habit of saying "that makes sense" ("das macht Sinn") while the correct equivalent would be "that has sense" ("das hat Sinn") or "that is sensful" ("das ist sinnvoll")), but we can not stop this evolution. Languages that don't evolve are dead, because noone speaks them anymore (as everyone will always add his one character to the language, though granted this is not as easy for programming languages as you need to work in the compiler/interpreter). Hadn't Borland decided to bring out Delphi and thus the completely different object model (which I personally think is in most points superior to TP style objects, to those have their pros, too), but instead kept e.g. Turbo Pascal for Windows we might not be talking together here today.

I'm not sure that I should venture an opinion, since my ability to implement something- to "practice what I preach"- is limited due to my position on the learning curve.

However, I'd suggest that there are two possible category of extension: those that implement a clearly-delimited first-class object with interesting properties, and those that don't.

Something like a <generic>, or a /regular expression/ (borrowing from Perl), or a [list of elements] fall into the first category, and should be comparatively easy to add to a language- and for a user to ignore if he doesn't like them.

Something like

>>> for a in a index i do

falls squarely into the latter category: it's messy to parse, worse to read, and is completely unlike any existing language idioms.

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

Alexander Klenin
to Sven Barth: I believe he wants to have real world examples (of other languages) where this feature is…
Sven Barth wrote 6 lines
> What is "concrete code"? The code I provided only missed loop bodies. > I can provide that too, but I do not think it will add anything to the > discussion. I believe he wants to have real world examples (of other languages) where this feature is used. E.g. in some well respected software, library, etc.

Thank you, I understand now.
Python:
https://www.google.com/search?q=site%3Agithub.com+for+%22in+enumerate%22 PHP:
https://www.google.com/search?q=site%3Agithub.com+foreach(%24a+as+%24k+%3D%3E+%24v) Objective C:
https://www.google.com/search?q=site%3Agithub.com+enumerateObjectsUsingBlock JavaScript:
https://www.google.com/search?q=site%3Agithub.com+%22forEach(function(value%2C+index%22

Note that I restricted search to a single repository site to avoid catching various manuals and discussions.
I had also fix parameter names for some languages, because Google does not support regexp search.
Even with those limitations, you may notice that each search returns thousands of results.
I do not wish to enter an argument about how "respected" those languages and projects are --
but I hope it demonstrates unambiguously the popularity of the feature.

Alexander S. Klenin

Reply by email

Florian Klämpfl
to Alexander Klenin
Alexander Klenin wrote 9 lines
On Sat, Jan 26, 2013 at 6:59 AM, Sven Barth wrote: >> What is "concrete code"? The code I provided only missed loop bodies. >> I can provide that too, but I do not think it will add anything to the >> discussion. > > I believe he wants to have real world examples (of other languages) where > this feature is used. E.g. in some well respected software, library, etc. Thank you, I understand now.

No. I want to see a language which provides something like the explicit index keyword and not some tupel returning enumerator like python which can be done already.

Reply by email

Alexander Klenin
to Mark Morgan Lloyd: I'm not sure that I should venture an opinion, since my ability to implement something-…
Mark Morgan Lloyd wrote 8 lines
However, I'd suggest that there are two possible category of extension: those that implement a clearly-delimited first-class object with interesting properties, and those that don't. Something like a <generic>, or a /regular expression/ (borrowing from Perl), or a [list of elements] fall into the first category, and should be comparatively easy to add to a language- and for a user to ignore if he doesn't like them.

I disagree with the statement that generics are easy to add. I disagree with a statement that adding Perl's first-class regexp syntax is a good idea at all --
talk about messy parsing :)
I agree that [list of elements] is a good feature, but it is already present. So, unfortunately, I can not accept your list as an example of "good" extensions.

Something like >>>> for v in a index i do falls squarely into the latter category: it's messy to parse, worse to read,

I disagree with the statement that "for-in-index" loop is "messy to parse". You can look at the code provided by Vasily: there is no problem in question of readabllity is indeed subjective, and I am quite open for altervative proposals here.
The current syntax was chosen based on the requirements to avoid new keywords and traditional
Pascal preference for keywords over punctuation.
However, I may consider variants below (v = value, i = index, a = array): for v, i in a do
for i, v in a do // most similar to Python
for (v, i) in a do
for v[i] in a do
for v index i in a do // perhaps this is really better -- I am not sure for index i in a do // we may allow to omit the value and loop only over the index -- this could be useful for STL sets for v key i in a do // new keyword = bad

and is completely unlike any existing language idioms.

Do you mean idioms existing in Pascal, or general language idioms?

Alexander S. Klenin

Reply by email

Sven Barth
to Mark Morgan Lloyd: I'm not sure that I should venture an opinion, since my ability to implement something-…
Mark Morgan Lloyd wrote 7 lines
Something like >>>> for a in a index i do falls squarely into the latter category: it's messy to parse, worse to read, and is completely unlike any existing language idioms.

I definitely have to disagree here (while still not having an opinion on the topic "for-in-index" itself): once you've worked on Delphi style generics you know what messy parsing is... and I already get nightmares thinking about what I still need to add for Delphi's generics support... This for-in-index is a peace of cake to parse in comparison.

Regards,
Sven

Reply by email

Alexander Klenin
to Florian Klämpfl: No. I want to see a language which provides something like the explicit index keyword…
Florian Klämpfl wrote
Where? Concrete code of a serious language! Not some "oh, yes, this language has it and that as well"
Florian Klämpfl wrote
No. I want to see a language which provides something like the explicit index keyword and not some tupel returning enumerator like python which can be done already.

Oh, I see. Please, state your questions more clearly -- there is no way I could infer
the second question from the first one!
There are two answers here:
1) If you would look at the examples I provided, you would notice that while Python
(and C++ which I did not list) do use the concept of tuple, other listed languages do not.

2) Indeed, introducing tuples to Pascal might be an alternative solution. Below is a proposal:
2.1) Tuple definition. Tuple is an anonymous list of values, possibly of different types. It is impossible to explicitly declare tuple type, or store a tuple in a variable.
2.2) Tuple construction: Tuple may be constructed by listing its elements in as a semicolon-separated list in parenthesis: (a; b; c). Also, any value of record or array type can be converted to a tuple by using built-in pseudo-function Tuple (or other some name, perhaps even a special character like ~ or @@). Semicolon is chosen to underline similarity with the record constants -- but perhaps comma is better.
Alternatively, a square brackets may be used since they already represent similar semantics for "array of const" parameters. 2.3) Tuple assignment. Tuple may be assigned to a record, provided field types match. Most important, tuples may be used in deconstructing assignment by listing variables in the same syntax on the left side of assignment:

  (a; b) := (x; y);

If the left side contains less variables then the tuple has values, extra values are ignored.
If the right side contains more variables, it is an error. 2.4) Tuples as procedure arguments. Tuple may be passed to a procedure or function.
In this case, deconstructing assignment is performed from the tuple to the actual arguments,
as if they were listed on the left side of assignment in the previous point. Also, a tuple may be present inside square brackets representing "array of const" argument.
In this case, it works as if tuple elements were listed instead.

2.5) for-in loop accepts a list of variables after "for" keyword. In this case, it tries to convert the Current value to a tuple and perform tuple assignment.

With this proposal, following benefits are gained:

1) Group assignment:
(x; y; z) := (0; 0; 0);
(a; b) := (b; a);
(first; second) := Tuple(SomeFunctionReturningArray());
2) Record literals without constructor functions:
  ARectangle.TopLeft := (100; 200);
3) Formatting complex values:
  s := Format('%d-%d', [Tuple(CenterPoint(ARectangle))]);
4) Collecting default values for procedures:
In some library:
procedure WithManyParams(A, B, C, D, E, F: Integer);
In user code:
var
  p: record A, B, C, D, E, F: Integer; end;
p := (default; values; for; params);
...
p.E := 5;
WithManyParams(Tuple(p));

5) Finally, for-in:
for (v; i) in a do ...
Compiler code for built-in types mostly the same as for-in-index -- syntax difference only.
User-defined iterators may return records with fields (value, key). In the case of
for v in a
v may now be either a record or just a value, depending on the type.

Alexander S. Klenin

Reply by email

Florian Klämpfl
to Alexander Klenin
Alexander Klenin wrote 10 lines
On Sat, Jan 26, 2013 at 5:30 AM, Florian Klämpfl wrote: > Where? Concrete code of a serious language! Not some "oh, yes, this > language has it and that as well" On Sat, Jan 26, 2013 at 7:34 AM, Florian Klämpfl wrote: > No. I want to see a language which provides something like the explicit > index keyword and not some tupel returning enumerator like python which > can be done already. Oh, I see. Please, state your questions more clearly --

Maybe I wouldn't have to ask if there would be a clear proposal what shall be implemented, what are alternatives, what do other languages, why is a so strange approach chosen etc.

Reply by email

waldo kitty
to Michael Van Canneyt: I don't see it like that. Donald Knuth declared TeX as finished. Despite that, it has…
Michael Van Canneyt wrote 11 lines
On Sat, 26 Jan 2013, Alexander Klenin wrote: > I certainly agree that Pascal has some advantages -- and they often > outweigh disadvantages. > Otherwise, I would be in Python's mailing list now, arguing to add > some of the Pascal's features :) > However, this does not mean that disadvantages should be just ignored. I didn't say that. Like I said, I am not against new language features per se. I just don't think that this one is one that should be added.

FWIW (littlest pup in the pack): i agree with this... the discussion looks to me like something one would find in their own local library code... but then again, i'm a little pup here... very little...

/me looks at all his library files of routines and functions and considers how many routines there are in there and how long it took to work them out...

Reply by email

Alexander Klenin
to Florian Klämpfl: Maybe I wouldn't have to ask if there would be a clear proposal what shall be…
Florian Klämpfl wrote
Maybe I wouldn't have to ask if there would be a clear proposal what shall be implemented, what are alternatives, what do other languages, why is a so strange approach chosen etc.

I agree that the quality of initial proposal could be better. In my defense I could say that it is still better than for (almost?) any other feature implemented in the last couple of years.

Alexander S. Klenin

Reply by email

Mark Morgan Lloyd
to Sven Barth: I definitely have to disagree here (while still not having an opinion on the topic…
Sven Barth wrote 14 lines
On 25.01.2013 21:10, Mark Morgan Lloyd wrote: > Something like > > >>>> for a in a index i do > > falls squarely into the latter category: it's messy to parse, worse to > read, and is completely unlike any existing language idioms. > I definitely have to disagree here (while still not having an opinion on the topic "for-in-index" itself): once you've worked on Delphi style generics you know what messy parsing is... and I already get nightmares thinking about what I still need to add for Delphi's generics support... This for-in-index is a peace of cake to parse in comparison.

I wasn't trying to say that it was easy so much as it would have been worse if it weren't for the unambiguous delimiters.

In fact I bet that with what you know now you'd be able to move generic support into a run-time library loaded when the idiom was recognised.

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 Alexander Klenin: Oh, I see. Please, state your questions more clearly -- there is no way I could infer the…
Alexander Klenin wrote 20 lines
On Sat, Jan 26, 2013 at 5:30 AM, Florian Klämpfl wrote: > Where? Concrete code of a serious language! Not some "oh, yes, this > language has it and that as well" On Sat, Jan 26, 2013 at 7:34 AM, Florian Klämpfl wrote: > No. I want to see a language which provides something like the explicit > index keyword and not some tupel returning enumerator like python which > can be done already. Oh, I see. Please, state your questions more clearly -- there is no way I could infer the second question from the first one! There are two answers here: 1) If you would look at the examples I provided, you would notice that while Python (and C++ which I did not list) do use the concept of tuple, other listed languages do not. 2) Indeed, introducing tuples to Pascal might be an alternative solution. Below is a proposal:

Regarding tuples:
http://wiki.oxygenelanguage.com/en/Tuples

Regards,
Sven

Reply by email

Sven Barth
to Mark Morgan Lloyd: I wasn't trying to say that it was easy so much as it would have been worse if it weren't…
Mark Morgan Lloyd wrote 20 lines
Sven Barth wrote: > On 25.01.2013 21:10, Mark Morgan Lloyd wrote: >> Something like >> >> >>>> for a in a index i do >> >> falls squarely into the latter category: it's messy to parse, worse to >> read, and is completely unlike any existing language idioms. >> > > I definitely have to disagree here (while still not having an opinion > on the topic "for-in-index" itself): once you've worked on Delphi > style generics you know what messy parsing is... and I already get > nightmares thinking about what I still need to add for Delphi's > generics support... This for-in-index is a peace of cake to parse in > comparison. I wasn't trying to say that it was easy so much as it would have been worse if it weren't for the unambiguous delimiters.

After implementing support for Delphi style generics I came to the conclusion that I would have preferred the following syntax:

type
   TFPGListLongInt = specialize TFPGList as (Integer);

or

type
   TFPGListLongInt = specialize TFPGList with (Integer);

This could also have appeared inline without to many headaches. For the first one the "specialize" keyword would have definitely been necessary, but for second syntax idea it would have worked without the "specialize" keyword as well...

In fact I bet that with what you know now you'd be able to move generic support into a run-time library loaded when the idiom was recognised.

No, I wouldn't. This would make the code in no way more maintainable or even more understandable. Quite the contrary.

Regards,
Sven

Reply by email

Alexander Klenin
to Sven Barth: Regarding tuples: http://wiki.oxygenelanguage.com/en/Tuples Sven
Sven Barth wrote

I know, but I consider this particular implementation an unpleasant example of "no need to change the language -- lets do it in the library" philosophy. Just look:

The Tuple type is a set of generic types with 1 up to 7 generic parameter types for the value types. There also is an 8th Tuple type of which the 8th parameter type has to be another tuple.

Also, the feature set is rather weak compared to my proposal, to the point of not worthing it.
Still, if my proposal would be implemented, it is will also become possible in FPC to allow
anonymous records as return types -- the user will have to use tuples to deconstruct them.

Alexander S. Klenin

Reply by email

Alexander Klenin
to Sven Barth: After implementing support for Delphi style generics I came to the conclusion that I…
Sven Barth wrote 11 lines
After implementing support for Delphi style generics I came to the conclusion that I would have preferred the following syntax: type TFPGListLongInt = specialize TFPGList as (Integer); or type TFPGListLongInt = specialize TFPGList with (Integer);

Whatever the particular syntax, I do agree that the decision to use angular brackets
was unnecessarily copied from C++ -- round ones (or, at least, square ones) would be much better.

Alexander S. Klenin

Reply by email

Marco van de Voort
to Alexander Klenin

In our previous episode, Alexander Klenin said:

Show quoted text 8 lines
On Sat, Jan 26, 2013 at 9:31 AM, Sven Barth wrote: > TFPGListLongInt = specialize TFPGList with (Integer); > Whatever the particular syntax, I do agree that the decision to use angular brackets was unnecessarily copied from C++ -- round ones (or, at least, square ones) would be much better.

Delphi got its generics from .NET. The .NET compiler got it one version earlier. (D2007, native D2009)

Probably the main reason for generics was access the 2.0 framework which was new (and used generics) going from D2006 to D2007

Reply by email

Alexander Klenin
to Marco van de Voort
Marco van de Voort wrote 10 lines
> Whatever the particular syntax, I do agree that the decision to use > angular brackets > was unnecessarily copied from C++ -- round ones (or, at least, square > ones) would be much better. Delphi got its generics from .NET. The .NET compiler got it one version earlier. (D2007, native D2009) Probably the main reason for generics was access the 2.0 framework which was new (and used generics) going from D2006 to D2007

Quite probably, but that is still no reason for angular brackets :)

Alexander S. Klenin

Reply by email

Marco van de Voort
to Alexander Klenin

In our previous episode, Alexander Klenin said:

> Probably the main reason for generics was access the 2.0 framework which was > new (and used generics) going from D2006 to D2007 Quite probably, but that is still no reason for angular brackets :)

Maybe. But like many extensions, multiple distinct ways to do stuff is even worse.

Reply by email

Paul Ishenin
to Michael Van Canneyt: Talk about a choice between the plague and cholera... If I must choose between the…

26.01.13, 2:32, Michael Van Canneyt пишет:

Pascal is an explicitly declarative language. Anonymous functions go 100% against this. It is the readability horror I associate with Javascript.

I wonder where you were when Operators feature has been added to pascal? Or generics?

I think now when operators for simple types are present in the language it is too late to care about explicitly declarative language. It is simple not explicit anymore.

And index (or better to call it key) extension for for-in loop will not make it less explicit for sure.

Best regards,
Paul Ishenin

Reply by email

Paul Ishenin
to Sven Barth: I definitely have to disagree here (while still not having an opinion on the topic…

26.01.13, 4:47, Sven Barth пишет:

Show quoted text 5 lines
I definitely have to disagree here (while still not having an opinion on the topic "for-in-index" itself): once you've worked on Delphi style generics you know what messy parsing is... and I already get nightmares thinking about what I still need to add for Delphi's generics support... This for-in-index is a peace of cake to parse in comparison.

I confirm. When I tried think how to add delphi like generic parse to language I also had this nightnares. As result I simple stoped to work on them.

Best regards,
Paul Ishenin

Reply by email

Michael Van Canneyt
to Paul Ishenin: 26.01.13, 2:32, Michael Van Canneyt пишет: I wonder where you were when Operators…
Paul Ishenin wrote 8 lines
26.01.13, 2:32, Michael Van Canneyt пишет: > Pascal is an explicitly declarative language. Anonymous functions go > 100% against this. It is the readability horror I associate with > Javascript. I wonder where you were when Operators feature has been added to pascal? Or generics?

Generics was implemented without my knowledge. I only found out when suddenly the classes unit had been changed to use them. After a horrible discussion, this was reversed, because of the drop in speed you got when using generics.

Operators are a natural thing:
Pascal defines some basic types and operations on them. Pascal allows you to define extra types, so it is natural that it allows you to define these operations on them.

Show quoted text 6 lines
I think now when operators for simple types are present in the language it is too late to care about explicitly declarative language. It is simple not explicit anymore. And index (or better to call it key) extension for for-in loop will not make it less explicit for sure.

Personally, I think the tuple approach proposal is more general, and therefor better.

Once more, I do not think that language extensions are bad. I judge them on a case by case basis.

But if I must choose between

for a,b in c do

(with C a tuple enumerator/iterator) or

for a in c index b do

Then the former is ten times (well, a lot) better.

So if someone were to introduce that to solve the original poster's problem, you will not hear me protesting, it will have been well worth the energy I put in this discussion.

Michael.

Reply by email

Sven Barth
to Michael Van Canneyt
Michael Van Canneyt wrote 18 lines
On Sat, 26 Jan 2013, Paul Ishenin wrote: > 26.01.13, 2:32, Michael Van Canneyt пишет: > >> Pascal is an explicitly declarative language. Anonymous functions go >> 100% against this. It is the readability horror I associate with >> Javascript. > > I wonder where you were when Operators feature has been added to > pascal? Or generics? Generics was implemented without my knowledge. I only found out when suddenly the classes unit had been changed to use them. After a horrible discussion, this was reversed, because of the drop in speed you got when using generics.

Ah! So that is where those ifdefs in classes come from :) I always wondered...

Regards,
Sven

Reply by email

Alexander Klenin
to Sven Barth
Sven Barth wrote 9 lines
> Generics was implemented without my knowledge. I only found out when > suddenly > the classes unit had been changed to use them. After a horrible > discussion, this was reversed, because of the drop in speed you got when > using generics. Ah! So that is where those ifdefs in classes come from :) I always wondered...

Is the drop still present/essential? Perhaps optimizer is now good enough to drop those ifdefs?

Alexander S. Klenin

Reply by email

Marco van de Voort
to Sven Barth: Ah! So that is where those ifdefs in classes come from :) I always wondered... Sven

In our previous episode, Sven Barth said:

Show quoted text 11 lines
>> I wonder where you were when Operators feature has been added to >> pascal? Or generics? > > Generics was implemented without my knowledge. I only found out when > suddenly > the classes unit had been changed to use them. After a horrible > discussion, this was reversed, because of the drop in speed you got when > using generics. Ah! So that is where those ifdefs in classes come from :) I always wondered...

Moreover, Delphi's generic TList is in generics.collections, not in classes.

There is no tstringlist, they went with a Dictionary instead.

Reply by email

Sven Barth
to Alexander Klenin: I know, but I consider this particular implementation an unpleasant example of "no need…
Alexander Klenin wrote 9 lines
On Sat, Jan 26, 2013 at 9:27 AM, Sven Barth wrote: > > Regarding tuples: > http://wiki.oxygenelanguage.com/en/Tuples I know, but I consider this particular implementation an unpleasant example of "no need to change the language -- lets do it in the library" philosophy. Just look: > The Tuple type is a set of generic types with 1 up to 7 generic parameter types for the value types. > There also is an 8th Tuple type of which the 8th parameter type has to be another tuple.

I mean less the implementation specific details, but more the syntax they chose:

=== example begin ===

TTestTuple = tuple of (Integer, String, TObject);
var
   t: TTestTuple;
   i: Integer;
   s: String;
   o: TObject;
begin
   t := (42, 'Hello World', TObject.Create); // ok, this can be
considered nightmarish syntax again... (see below)
   (i, s, o) := t;
   // and yes this could also provide the possibility for multiassignments
   (i, s, o) := (42, 'Hello World', TObject.Create);
end;

=== example end ===

The only thing I have a problem with is to use "(...)" as the syntax element for tuples... e.g. is "(42)" an integer or a "tuple of (Integer)"? We'd need to either enforce that "tuple of (...)" needs an element count > 1 or that "tuple of (SomeType)" is assignment compatible to just "SomeType" (we'd need something like this, because of backwards compatibility).

Regards,
Sven

Reply by email

Sven Barth
to Alexander Klenin: On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth Is the drop still present/essential? Perhaps…
Alexander Klenin wrote 13 lines
On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth wrote: >> Generics was implemented without my knowledge. I only found out when >> suddenly >> the classes unit had been changed to use them. After a horrible >> discussion, this was reversed, because of the drop in speed you got when >> using generics. > > Ah! So that is where those ifdefs in classes come from :) I always > wondered... > Is the drop still present/essential? Perhaps optimizer is now good enough to drop those ifdefs?

Someone would need to test this. It could be that the generic variant is less optimal, because the generic list is built upon a list that handles pointers...

Regards,
Sven

Reply by email

Alexander Klenin
to Michael Van Canneyt: Generics was implemented without my knowledge. I only found out when suddenly the classes…
Michael Van Canneyt wrote 14 lines
But if I must choose between for a,b in c do (with C a tuple enumerator/iterator) or for a in c index b do Then the former is ten times (well, a lot) better. So if someone were to introduce that to solve the original poster's problem, you will not hear me protesting, it will have been well worth the energy I put in this discussion.

There are two reasons I proposed latter instead of former:
1) I think using keyword is more explicit and readable
2) I thought that smaller feature is easier to argue for than a large one -- apparently, I was mistaken on that :)

So, amended "for-in-index" proposal:
1) The syntax is
for value, key in container do ...
2) The enumerator interface is extended with optional property CurrentWithKey: TValueKey;
where TValueKey must be a record with two fields.
This property will be called in the case of two-argument for-in, while the case of single-argument for-in continues to work as-is for both compatibility and efficiency.
3) When/if the full tuple proposal gets implemented, "for-in-index", now aka "for-key-in", will became a proper subset of it.

What do you think?

Alexander S. Klenin

Reply by email

Sven Barth
to Marco van de Voort: In our previous episode, Sven Barth said: Moreover, Delphi's generic TList is in…
Marco van de Voort wrote 15 lines
In our previous episode, Sven Barth said: >>> I wonder where you were when Operators feature has been added to >>> pascal? Or generics? >> >> Generics was implemented without my knowledge. I only found out when >> suddenly >> the classes unit had been changed to use them. After a horrible >> discussion, this was reversed, because of the drop in speed you got when >> using generics. > > Ah! So that is where those ifdefs in classes come from :) I always > wondered... Moreover, Delphi's generic TList is in generics.collections, not in classes.

Luckily we don't have a generic TList at all yet ^^

There is no tstringlist, they went with a Dictionary instead.

Which reminds me that I wanted to port Python's dictionary implementation which is said to be the fastest around :)

Regards,
Sven

Reply by email

Alexander Klenin
to Sven Barth: I mean less the implementation specific details, but more the syntax they chose: ===…
Sven Barth wrote 29 lines
I mean less the implementation specific details, but more the syntax they chose: === example begin === TTestTuple = tuple of (Integer, String, TObject); var t: TTestTuple; i: Integer; s: String; o: TObject; begin t := (42, 'Hello World', TObject.Create); // ok, this can be considered nightmarish syntax again... (see below) (i, s, o) := t; // and yes this could also provide the possibility for multiassignments (i, s, o) := (42, 'Hello World', TObject.Create); end; === example end === The only thing I have a problem with is to use "(...)" as the syntax element for tuples... e.g. is "(42)" an integer or a "tuple of (Integer)"? We'd need to either enforce that "tuple of (...)" needs an element count > 1 or that "tuple of (SomeType)" is assignment compatible to just "SomeType" (we'd need something like this, because of backwards compatibility).

Note that my proposal specifically forbids to create "named tuples", because named tuples are just records :)
As for syntax ambiguity -- I agree it is a problem. Perhaps a symbol to denote tuple could be chosen
(e.g. @@), and is required in front of *all* tuples: @@(a, b) = @@(b, c);
@@(first, second) = @@FunctionReturningArray;
ProcWithmanyParams(@@p);
... etc
unfortunately, this will also require
for @@(v, i) in a do
which is not nice.

Another possibility is to resolve single element in brackets in favor of a simple value, and require explicit call to Tuple to disambiguate -- single-element tuples are useless anyway, so will be rare.

Alexander S. Klenin

Reply by email

Alexander Klenin
to Hans-Peter Diettrich: OPL: array of Variant. Also: Open Array. Where both are slow and clumsy to use, violating…
Hans-Peter Diettrich wrote 12 lines
Alexander Klenin schrieb: > 2) Indeed, introducing tuples to Pascal might be an alternative > solution. Below is a proposal: > 2.1) Tuple definition. Tuple is an anonymous list of values, possibly > of different types. OPL: array of Variant. Also: Open Array. Where both are slow and clumsy to use, violating the principle of strictly typed languages.

I think you meant "array of const" instead of "open array", since open array is just a method to pass arbitrary-sized array (of a single element type, of course).

As for array of Vaiant and array of const -- they are very different from the tuples proposal.
Note that tuples proposal is carefully constructed in such a way that tuples are statically (but implicitly)
typed, so no run-time overhead is involved, and all type errors are

Alexander S. Klenin

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth Is the drop still present/essential? Perhaps…
Alexander Klenin wrote 13 lines
On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth wrote: >> Generics was implemented without my knowledge. I only found out when >> suddenly >> the classes unit had been changed to use them. After a horrible >> discussion, this was reversed, because of the drop in speed you got when >> using generics. > > Ah! So that is where those ifdefs in classes come from :) I always > wondered... > Is the drop still present/essential? Perhaps optimizer is now good enough to drop those ifdefs?

No.

You never can replace a direct pointer assignment a:=B with a call to Move()
and expect the same speed.

Michael.

Reply by email

Sven Barth
to Alexander Klenin: Oh, I see. Please, state your questions more clearly -- there is no way I could infer the…

Rereading your mail now with what I wrote about tuples in mind:

Alexander Klenin wrote 5 lines
2) Indeed, introducing tuples to Pascal might be an alternative solution. Below is a proposal: 2.1) Tuple definition. Tuple is an anonymous list of values, possibly of different types. It is impossible to explicitly declare tuple type, or store a tuple in a variable.

As Michael said Pascal is a declarative language (though this has been forgotten some times) so I'd allow the declaration of tuple types using something like "tuple of (type1, type2, etc.)"

Show quoted text 9 lines
2.2) Tuple construction: Tuple may be constructed by listing its elements in as a semicolon-separated list in parenthesis: (a; b; c). Also, any value of record or array type can be converted to a tuple by using built-in pseudo-function Tuple (or other some name, perhaps even a special character like ~ or @@). Semicolon is chosen to underline similarity with the record constants -- but perhaps comma is better. Alternatively, a square brackets may be used since they already represent similar semantics for "array of const" parameters.

As I said in my other mail I'm still not sure whether "(...)" is a good idea, because there can be code like "i := (42)" (it's not forbidden and thus it needs to be allowed with such an extension as well). Nevertheless I'd prefer "," as a seperator.

Also I'd definitely prefer NOT to use special characters. Instead I'd prefer the use of an instrinsic like "Tuple" (though - together with my declaration proposal - one needs to pay special attention to the difference of "Tuple(...)" and "tuple of (...)" in the parser)

Show quoted text 8 lines
2.3) Tuple assignment. Tuple may be assigned to a record, provided field types match. Most important, tuples may be used in deconstructing assignment by listing variables in the same syntax on the left side of assignment: (a; b) := (x; y); If the left side contains less variables then the tuple has values, extra values are ignored. If the right side contains more variables, it is an error.

I don't know whether we should use this "value ignoring". Maybe always an error if the count differs is better... (and in the case of a Tuple returned by the Tuple intrinsic we'd also need a new RunError and Exception type)

Show quoted text 9 lines
2.4) Tuples as procedure arguments. Tuple may be passed to a procedure or function. In this case, deconstructing assignment is performed from the tuple to the actual arguments, as if they were listed on the left side of assignment in the previous point. Also, a tuple may be present inside square brackets representing "array of const" argument. In this case, it works as if tuple elements were listed instead.

Together with my "declaration" proposal this is a bad idea. So no deconstructive assignments on procedure calls. Things like this can be allowed though:

=== code begin ===

type
   TTestTuple = (Integer, String);
procedure Test(aArg1: String; aArg2: TTestTuple; aArg3: Integer);
// somewhere else
Test('Foobar', (42, s), i);

=== code end ===

2.5) for-in loop accepts a list of variables after "for" keyword. In this case, it tries to convert the Current value to a tuple and perform tuple assignment.

It should not only be a list of variables, but a "tuple deconstructor":

=== code begin ===

for (key, data) in SomeContainer do
   ...

=== code end ===

The enumerator then of course needs to return a fitting tuple type.

This way one can keep the current enumerators (maybe except build in ones): they just don't return a tuple type, but a "scalar" and thus you'd continue to write

=== code begin ===

for data in SomeContainer do
   ...

=== code end ===

Show quoted text 8 lines
With this proposal, following benefits are gained: 1) Group assignment: (x; y; z) := (0; 0; 0); (a; b) := (b; a); (first; second) := Tuple(SomeFunctionReturningArray());

Agreed.

2) Record literals without constructor functions: ARectangle.TopLeft := (100; 200);

I don't know whether this should be possible without an approbiate intrinsic (the inverse of "Tuple"), but I'm open here...

3) Formatting complex values: s := Format('%d-%d', [Tuple(CenterPoint(ARectangle))]);

Format would need to be adjusted to support Tuple types, but ok...

Show quoted text 12 lines
4) Collecting default values for procedures: In some library: procedure WithManyParams(A, B, C, D, E, F: Integer); In user code: var p: record A, B, C, D, E, F: Integer; end; p := (default; values; for; params); ... p.E := 5; WithManyParams(Tuple(p));

As said above this is a no in my opinion.

Show quoted text 9 lines
5) Finally, for-in: for (v; i) in a do ... Compiler code for built-in types mostly the same as for-in-index -- syntax difference only. User-defined iterators may return records with fields (value, key). In the case of for v in a v may now be either a record or just a value, depending on the type.

Basically agreed.

Regards,
Sven

Reply by email

Sven Barth
to Michael Van Canneyt: Generics was implemented without my knowledge. I only found out when suddenly the classes…
Michael Van Canneyt wrote 26 lines
> I think now when operators for simple types are present in the > language it is too late to care about explicitly declarative language. > It is simple not explicit anymore. > > And index (or better to call it key) extension for for-in loop will > not make it less explicit for sure. Personally, I think the tuple approach proposal is more general, and therefor better. Once more, I do not think that language extensions are bad. I judge them on a case by case basis. But if I must choose between for a,b in c do (with C a tuple enumerator/iterator) or for a in c index b do Then the former is ten times (well, a lot) better. So if someone were to introduce that to solve the original poster's problem, you will not hear me protesting, it will have been well worth the energy I put in this discussion.

Then let's better concentrate our energy to implementing tuples in a good way and (more or less) everyone will be happy :D

I'd suggest to start a new thread for that if we want to discuss proposals for syntax, semantics, corner cases, etc.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Alexander Klenin: On Sat, Jan 26, 2013 at 10:34 PM, Michael Van Canneyt There are two reasons I proposed…
Alexander Klenin wrote 21 lines
On Sat, Jan 26, 2013 at 10:34 PM, Michael Van Canneyt wrote: > But if I must choose between > > for a,b in c do > > (with C a tuple enumerator/iterator) or > > for a in c index b do > > Then the former is ten times (well, a lot) better. > > So if someone were to introduce that to solve the original poster's problem, > you will not hear me protesting, it will have been well worth the energy I > put in this discussion. > There are two reasons I proposed latter instead of former: 1) I think using keyword is more explicit and readable 2) I thought that smaller feature is easier to argue for than a large one -- apparently, I was mistaken on that :)

Well, a tuple is simply a new fundamental type.

Just like generics, BTW.

Show quoted text 6 lines
So, amended "for-in-index" proposal: 1) The syntax is for value, key in container do ... 2) The enumerator interface is extended with optional property CurrentWithKey: TValueKey; where TValueKey must be a record with two fields.

I don't think we need a record.

Lets first see about how to implement general tuple values before you start restricting it. I see Sven is already working on some ideas.

It may be more work up front, but it will be a more fundamental solution.

To be clear, the "for in index" syntax with 'index' keyword will not be recuperated.

No temporary workarounds/hacks. Decent solutions.

Michael.

Reply by email

Michael Van Canneyt
to Sven Barth: Then let's better concentrate our energy to implementing tuples in a good way and (more…
Sven Barth wrote 30 lines
On 26.01.2013 12:34, Michael Van Canneyt wrote: >> I think now when operators for simple types are present in the >> language it is too late to care about explicitly declarative language. >> It is simple not explicit anymore. >> >> And index (or better to call it key) extension for for-in loop will >> not make it less explicit for sure. > > Personally, I think the tuple approach proposal is more general, and > therefor better. > > Once more, I do not think that language extensions are bad. I judge them > on a case by case basis. > > But if I must choose between > > for a,b in c do > > (with C a tuple enumerator/iterator) or > > for a in c index b do > > Then the former is ten times (well, a lot) better. > > So if someone were to introduce that to solve the original poster's > problem, you will not hear me protesting, it will have been well worth > the energy I put in this discussion. Then let's better concentrate our energy to implementing tuples in a good way and (more or less) everyone will be happy :D

100% agreed.

The way may be hobbly, but at least we go forward...

Michael.

Reply by email

Mark Morgan Lloyd
to Sven Barth: Rereading your mail now with what I wrote about tuples in mind: As Michael said Pascal is…
Sven Barth wrote
As Michael said Pascal is a declarative language (though this has been forgotten some times) so I'd allow the declaration of tuple types using something like "tuple of (type1, type2, etc.)"

etc. Yes, I like it. This also sorts out the lack of multiple assignment that somebody was complaining about in the fpc-pascal ML a few days ago.

Some way of extending a single value to fill a tuple where all the elements are of the same type would be useful, note that I'm not suggesting any other relaxation of type checking.

(x, y, z) := (0, 0, 0);		// OK
(x, y, z) := Tuple(0);		// OK
(x, y, z) := (0, 0);		// Not OK
(x, y, z) := Tuple(0, 0);	// Not OK

So if I understand things correctly, brackets [] are used where the number of contained elements is indeterminate (sets, multidimensional array indices, arrays of const) and parentheses where it's determinate (tuples, record initialisation etc.).

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

Hans-Peter Diettrich
to Alexander Klenin: On Sat, Jan 26, 2013 at 3:14 PM, Hans-Peter Diettrich I think you meant "array of const"…
I think you meant "array of const" instead of "open array", since open array is just a method to pass arbitrary-sized array (of a single element type, of course).

Yes, indeed. I missed that you already mentioned "array of const" as a possible syntax/implementation.

Show quoted text 6 lines
As for array of Vaiant and array of const -- they are very different from the tuples proposal. Note that tuples proposal is carefully constructed in such a way that tuples are statically (but implicitly) typed, so no run-time overhead is involved, and all type errors are doubt that this is possible in OPL without much additional (type,

name) information in source code. Consider how many number types exist, so that "[1]" can be a 1-tuple of almost any numeric type. Depending on what exact type the compiler chooses, the type may be too big or too small for subsequent assignments of other values, or to records. A practical implementation IMO will ressemble a record definition with explicit types added to every element. Otherwise "array of const" could be used, with included type information, and (automatic) type conversion when a tuple is used as a parameter list or operand.

The use as an argument list replacement will hardly match the signature of the subroutine, which expects exact types, modifiers (const/var) and calling convention (register/stack usage).

I don't see how tuples can be used without a new variable type. Without such an container the assignment of one tuple to another one will have no useful effect, because the result is lost.

Can you give more practical examples on your idea of using tuples in OPL?

I only could find an obvious use in record constructors, where the target record provides the tuple type as in

   ARectangle.TopLeft := (100; 200);

or better

   ARectangle.TopLeft := [100, 200];

This would be nice, indeed, but hardly worth to introduce tuples for only this purpose.

DoDi

Reply by email

Alexander Klenin
to Mark Morgan Lloyd: etc. Yes, I like it. This also sorts out the lack of multiple assignment that somebody…
Mark Morgan Lloyd wrote 15 lines
Sven Barth wrote: Some way of extending a single value to fill a tuple where all the elements are of the same type would be useful, note that I'm not suggesting any other relaxation of type checking. (x, y, z) := (0, 0, 0); // OK (x, y, z) := Tuple(0); // OK (x, y, z) := (0, 0); // Not OK (x, y, z) := Tuple(0, 0); // Not OK So if I understand things correctly, brackets [] are used where the number of contained elements is indeterminate (sets, multidimensional array indices, arrays of const) and parentheses where it's determinate (tuples, record initialisation etc.).

Note that in my proposal I suggested to allow array deconstruction and ignoring extra elements on the right side,
so mass initialization may be implemnted by something like this: const

  ZEROES: array [1..10] of Integer = (0, 0, ..., 0);

...
(x, y, z) := Tuple(ZEROES);
alternatively:
function Repeat(AValue: Integer; ACount: Integer = 10): TIndegerDynArray; ...
(x, y, z) := Tuple(Repeat(777));

Anyway, I do not think mass-assignment of the same value is particularly important
compared to the general case of mass-assignment of arbitrary values.

Alexander S. Klenin

Reply by email

luiz americo pereira camara
to Sven Barth: Someone would need to test this. It could be that the generic variant is less optimal,…

2013/1/26 Sven Barth :

Show quoted text 23 lines
On 26.01.2013 12:52, Alexander Klenin wrote: > > On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth > wrote: >>> >>> Generics was implemented without my knowledge. I only found out when >>> suddenly >>> the classes unit had been changed to use them. After a horrible >>> discussion, this was reversed, because of the drop in speed you got when >>> using generics. >> >> >> Ah! So that is where those ifdefs in classes come from :) I always >> wondered... >> > Is the drop still present/essential? Perhaps optimizer is now good > enough to drop those ifdefs? Someone would need to test this. It could be that the generic variant is less optimal, because the generic list is built upon a list that handles pointers...

I did some test with generics last year:
http://lazarusroad.blogspot.com.br/2012/06/cost-of-using-generics.html

I would not use in classes unit

Luiz

Reply by email

Sven Barth
to luiz americo pereira camara
luiz americo pereira camara wrote 29 lines
2013/1/26 Sven Barth : > On 26.01.2013 12:52, Alexander Klenin wrote: >> >> On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth >> wrote: >>>> >>>> Generics was implemented without my knowledge. I only found out when >>>> suddenly >>>> the classes unit had been changed to use them. After a horrible >>>> discussion, this was reversed, because of the drop in speed you got when >>>> using generics. >>> >>> >>> Ah! So that is where those ifdefs in classes come from :) I always >>> wondered... >>> >> Is the drop still present/essential? Perhaps optimizer is now good >> enough to drop those ifdefs? > > > Someone would need to test this. It could be that the generic variant is > less optimal, because the generic list is built upon a list that handles > pointers... > I did some test with generics last year: http://lazarusroad.blogspot.com.br/2012/06/cost-of-using-generics.html I would not use in classes unit

That's mostly about the "duplication" problem, which is known (maybe I'll try to improve the situation some time). What would have been more interesting is the performance of the generated code compared with e.g. a TStringList or a TObjectList.

Regards,
Sven

Reply by email

Michael Van Canneyt
to Sven Barth
Sven Barth wrote 36 lines
On 27.01.2013 16:27, luiz americo pereira camara wrote: > 2013/1/26 Sven Barth : >> On 26.01.2013 12:52, Alexander Klenin wrote: >>> >>> On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth >>> wrote: >>>>> >>>>> Generics was implemented without my knowledge. I only found out when >>>>> suddenly >>>>> the classes unit had been changed to use them. After a horrible >>>>> discussion, this was reversed, because of the drop in speed you got >>>>> when >>>>> using generics. >>>> >>>> >>>> Ah! So that is where those ifdefs in classes come from :) I always >>>> wondered... >>>> >>> Is the drop still present/essential? Perhaps optimizer is now good >>> enough to drop those ifdefs? >> >> >> Someone would need to test this. It could be that the generic variant is >> less optimal, because the generic list is built upon a list that handles >> pointers... >> > > I did some test with generics last year: > http://lazarusroad.blogspot.com.br/2012/06/cost-of-using-generics.html > > I would not use in classes unit That's mostly about the "duplication" problem, which is known (maybe I'll try to improve the situation some time). What would have been more interesting is the performance of the generated code compared with e.g. a TStringList or a TObjectList.

When I tested it, there was a 10% slowdown.
It is the difference between a direct pointer assignment vs. calling Move() for each assignment.

Regardless, I don't see the need of replacing proven code with generics just as a showcase for generics. If it ain't broken, don't fix it.

Michael.

Reply by email

luiz americo pereira camara
to Sven Barth: That's mostly about the "duplication" problem, which is known (maybe I'll try to improve…

2013/1/27 Sven Barth :

Show quoted text 11 lines
On 27.01.2013 16:27, luiz americo pereira camara wrote: > > > I did some test with generics last year: > http://lazarusroad.blogspot.com.br/2012/06/cost-of-using-generics.html > > I would not use in classes unit That's mostly about the "duplication" problem, which is known (maybe I'll try to improve the situation some time).

OK

What would have been more interesting is the performance of the generated code compared with e.g. a TStringList or a TObjectList.

Independent of the performance, what's the benefit of replacing the current implementation by one based in generic?

AFAIK none. It would just require more work, resulting in bigger and slower code

BTW: i use generic myself but mostly in application code. I avoid in components / libraries

Luiz

Reply by email

Sven Barth
to luiz americo pereira camara
luiz americo pereira camara wrote 8 lines
> What would have been more > interesting is the performance of the generated code compared with e.g. a > TStringList or a TObjectList. Independent of the performance, what's the benefit of replacing the current implementation by one based in generic? AFAIK none. It would just require more work, resulting in bigger and slower code

I'm not saying that we should replace the code in Classes by generics. I'm just interested in how generics perform compared to non-generic "generic" classes.

Regards,
Sven

Reply by email

Sven Barth
to Michael Van Canneyt: When I tested it, there was a 10% slowdown. It is the difference between a direct pointer…
Michael Van Canneyt wrote 46 lines
On Sun, 27 Jan 2013, Sven Barth wrote: > On 27.01.2013 16:27, luiz americo pereira camara wrote: >> 2013/1/26 Sven Barth : >>> On 26.01.2013 12:52, Alexander Klenin wrote: >>>> >>>> On Sat, Jan 26, 2013 at 10:50 PM, Sven Barth >>>> wrote: >>>>>> >>>>>> Generics was implemented without my knowledge. I only found out when >>>>>> suddenly >>>>>> the classes unit had been changed to use them. After a horrible >>>>>> discussion, this was reversed, because of the drop in speed you >>>>>> got when >>>>>> using generics. >>>>> >>>>> >>>>> Ah! So that is where those ifdefs in classes come from :) I always >>>>> wondered... >>>>> >>>> Is the drop still present/essential? Perhaps optimizer is now good >>>> enough to drop those ifdefs? >>> >>> >>> Someone would need to test this. It could be that the generic >>> variant is >>> less optimal, because the generic list is built upon a list that >>> handles >>> pointers... >>> >> >> I did some test with generics last year: >> http://lazarusroad.blogspot.com.br/2012/06/cost-of-using-generics.html >> >> I would not use in classes unit > > That's mostly about the "duplication" problem, which is known (maybe > I'll try to improve the situation some time). What would have been > more interesting is the performance of the generated code compared > with e.g. a TStringList or a TObjectList. When I tested it, there was a 10% slowdown. It is the difference between a direct pointer assignment vs. calling Move() for each assignment.

I just checked the code of TFPGList. It does not use Move if you look at it correctly:

TFPGList.Add calls TFPSList.Add with the address of the argument. TFPSList.Add in turn (basically) calls TFPSList.CopyItem which (in so far you are right) is implemented using Move. But this method is virtual and overridden in TFPGList where it's an assignment between dereferenced pointers to the generic type T.

But maybe it would still be faster if TFPGList would not be derived from TFPSList, but completely implement the list handling itself with an "array of T" and using just assignments. It could be that all those virtual method calls are the "problem" here...

Regardless, I don't see the need of replacing proven code with generics just as a showcase for generics. If it ain't broken, don't fix it.

As I just wrote to luiz: I'm not suggesting to change anything in Classes regarding usage of generics. I'm just curious regarding their performance behavior.

Regards,
Sven

Reply by email

luiz americo pereira camara
to Sven Barth: I'm not saying that we should replace the code in Classes by generics. I'm just…

2013/1/27 Sven Barth :

Show quoted text 18 lines
On 27.01.2013 20:46, luiz americo pereira camara wrote: >> >> What would have been more >> interesting is the performance of the generated code compared with e.g. a >> TStringList or a TObjectList. > > > Independent of the performance, what's the benefit of replacing the > current implementation by one based in generic? > > AFAIK none. It would just require more work, resulting in bigger and > slower code I'm not saying that we should replace the code in Classes by generics. I'm just interested in how generics perform compared to non-generic "generic" classes.

OK.

Just to be clear, i'm no against having even added a bugreport requesting a feature and would be happy of having the Delphi generic classes (TList, TDictionary) implemented

Luiz

Reply by email

Sven Barth
to Michael Schnell
Michael Schnell wrote 6 lines
On 01/25/2013 09:39 PM, Alexander Klenin wrote: > > I disagree with the statement that generics are easy to add. I ANSI C1 I use macros to do what might be done with Generics. (In fact I'm not really sure that Syntax-based Generics Pascal are more handy (supposedly they are when debugging) )

I've written a macro based list type for a C based project in university... I'm definitely in favor of a real generic syntax like it's implemented in FPC.

Regards,
Sven

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: Sorry, but I most certainly will do this. It is not because it is technically possible…
Michael Van Canneyt wrote
Delphi 7 object pascal could be learned very easily. Nowadays with all the "features" added you go, try and explain pascal to someone. Say it is 'nice and readable'.

+1

Generics, for-in loops, anonymous methods, classes defined inside classes etc... I have and see no need for them, and they simply complicate the beautiful Object Pascal language (at least from the D7 days).

Regards,
- Graeme -

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: Sorry, but I most certainly will do this. It is not because it is technically possible…
Michael Van Canneyt wrote 7 lines
If he wants to help, Alexander Klenin had better put his students to useful tasks. There are plenty to choose from. He said maybe he'd look after fcl-stl. The silence since was deafening. He said he needed a arbitrary precision math library: Well, get started ! Both should be perfectly within grasp of a student. If he has students, let them work on that.

+1

To add to that list... a native Free Pascal Debugger. I'm already working on this in my [very limited] spare time. Progress is slow, but progress is being made. The debugger is based on reading the DWARF debug information that FPC generates.

Regards,
- Graeme -

Reply by email

Graeme Geldenhuys
to Alexander Klenin: I am not sure what princilpes you are talking about, but accessing the key of the current…
Alexander Klenin wrote
> Using indicies is against all principles of iterators. I am not sure what princilpes you are talking about,

The theory. Read any Design Patterns book or technical papers.

but accessing the key of the current element is required quite often

On the contrary. You should be interested in the current element, not the index value it represents. ALL my iterators in all my application code don't use or need the index value. I simply ask for the Next or Previous object or value.

This also hides the implementation details of the container object, thus the container can change its internal implementation, and my Iterator code in my applications will still continue to function without change.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/

Reply by email

Paul Ishenin
to Graeme Geldenhuys: +1 Generics, for-in loops, anonymous methods, classes defined inside classes etc... I…

28.01.13, 20:33, Graeme Geldenhuys пишет:

Show quoted text 9 lines
On 01/25/13 08:07, Michael Van Canneyt wrote: > Delphi 7 object pascal could be learned very easily. Nowadays with all the "features" added > you go, try and explain pascal to someone. Say it is 'nice and readable'. +1 Generics, for-in loops, anonymous methods, classes defined inside classes etc... I have and see no need for them, and they simply complicate the beautiful Object Pascal language (at least from the D7 days).

Different people see different needs in language. There is nothing bad not to use and not understand some of the language features.

I used for-in loop many times in my applications simple because it reduce the code and therefore makes it more readable.

I also used types inside classes - this is a great feature. I don't need to polute global namespace with internal types.

I would use anonymouse methods in pascal - I use them in javascript when I need to perform something asynchronosly.

I use avanced record syntax because it makes code more understandable.

I scarry to use generics but that simple because they have many bugs.

Best regards,
Paul Ishenin

Reply by email

Michael Van Canneyt
to Paul Ishenin
Paul Ishenin wrote 15 lines
28.01.13, 20:33, Graeme Geldenhuys пишет: > On 01/25/13 08:07, Michael Van Canneyt wrote: >> Delphi 7 object pascal could be learned very easily. Nowadays with all the >> "features" added >> you go, try and explain pascal to someone. Say it is 'nice and readable'. > > +1 > > Generics, for-in loops, anonymous methods, classes defined inside > classes etc... I have and see no need for them, and they simply > complicate the beautiful Object Pascal language (at least from the D7 > days). Different people see different needs in language. There is nothing bad not to use and not understand some of the language features.

tatata, you should always understand everything :)

Show quoted text 9 lines
I used for-in loop many times in my applications simple because it reduce the code and therefore makes it more readable. I also used types inside classes - this is a great feature. I don't need to polute global namespace with internal types. I would use anonymouse methods in pascal - I use them in javascript when I need to perform something asynchronosly.

Since you can do the same with simple named methods too, I see no need for creating the readibility horror that results of it.

I use avanced record syntax because it makes code more understandable.

It offers nothing that objects didn't already have.

Just trying to say that this is one of these things where Delphi could simply have re-instated the TP-style objects. The compiler compiled them anyway already. There was no need to burden records with methods in an attempt to make them 'object-like'.

Michael.

Reply by email

Marco van de Voort
to Michael Van Canneyt

In our previous episode, Michael Van Canneyt said:

Show quoted text 7 lines
> I use avanced record syntax because it makes code more understandable. It offers nothing that objects didn't already have. Just trying to say that this is one of these things where Delphi could simply have re-instated the TP-style objects. The compiler compiled them anyway already. There was no need to burden records with methods in an attempt to make them 'object-like'.

I think it works the other way around, creating room to deprecate TP objects in time.

Reply by email

Mattias Gaertner
to Paul Ishenin: 28.01.13, 20:33, Graeme Geldenhuys пишет: Different people see different needs in…
Show quoted text 13 lines
28.01.13, 20:33, Graeme Geldenhuys пишет: > On 01/25/13 08:07, Michael Van Canneyt wrote: >> Delphi 7 object pascal could be learned very easily. Nowadays with all the "features" added >> you go, try and explain pascal to someone. Say it is 'nice and readable'. > > +1 > > Generics, for-in loops, anonymous methods, classes defined inside > classes etc... I have and see no need for them, and they simply > complicate the beautiful Object Pascal language (at least from the D7 days). Different people see different needs in language. There is nothing bad not to use and not understand some of the language features.

You are free to not use a feature, but you must understand all when using third party code. And the new features are neither easy to understand nor to remember.

I used for-in loop many times in my applications simple because it reduce the code and therefore makes it more readable.

True.
But it adds quite a lot of stuff and a simple loop can become much slower.

I also used types inside classes - this is a great feature. I don't need to polute global namespace with internal types.

True. What about nested classes?

I would use anonymouse methods in pascal - I use them in javascript when I need to perform something asynchronosly.

Correct me if I'm wrong, but all the alternatives in javascript have some drawbacks, you don't write big programs in
javascript and the anonymous methods easily confuse the javascript debuggers.

I use avanced record syntax because it makes code more understandable.

This feature made records more consistent with objects and classes, so I would say they indeed made Pascal easier to understand.

I scarry to use generics but that simple because they have many bugs.

Mattias

Reply by email

Graeme Geldenhuys
to Michael Van Canneyt: tatata, you should always understand everything :) Since you can do the same with simple…
Michael Van Canneyt wrote
tatata, you should always understand everything :)

:-)

Since you can do the same with simple named methods too, I see no need for creating the readibility horror that results of it.

Yup. I have also seen sample Delphi code where they used Generics. It was on the Code of Horror website if I remember correctly. It was ridiculously complex, unreadable, and probably a nightmare to debug. I regard simplicity and readability very high in my code. It makes working in a team so much easier too. That is what the Pascal language was all about.

> I use avanced record syntax because it makes code more understandable. It offers nothing that objects didn't already have.

Yeah, what was that all about... "advanced records". They are nothing more than the Objects introduced in Turbo Pascal days - and then Embarcadero has the audacity to call it a "new language feature". LOL.

BTW: I still find it useful using Objects instead of Classes in some places in my code.

Regards,
- Graeme -

Reply by email

Paul Ishenin
to Michael Van Canneyt: tatata, you should always understand everything :) Since you can do the same with simple…
Michael Van Canneyt wrote
> Different people see different needs in language. There is nothing bad > not to use and not understand some of the language features. tatata, you should always understand everything :)

Very weak argument :) In your work you use system APIs and other frameworks which are made in C, C++ or assembler. I believe you don't understand everything and if you don't - you use the reference if needed. The same way with pascal - if you don't want to learn new features then use libraries as black boxes but if you need then use a reference.

Show quoted text 5 lines
> I would use anonymouse methods in pascal - I use them in javascript > when I need to perform something asynchronosly. Since you can do the same with simple named methods too, I see no need for creating the readibility horror that results of it.

It is a readability horror when for injecting a small piece of code as anonymouse method in place where it is needed you *must* declare a new named method (which will no be used anywhere else) few screens up or down.

It offers nothing that objects didn't already have.

It offers understandable memory layout without VMT.

Show quoted text 5 lines
Just trying to say that this is one of these things where Delphi could simply have re-instated the TP-style objects. The compiler compiled them anyway already. There was no need to burden records with methods in an attempt to make them 'object-like'.

Best regards,
Paul Ishenin

Reply by email

Paul Ishenin
to Mattias Gaertner: On Mon, 28 Jan 2013 21:02:23 +0800 You are free to not use a feature, but you must…

28.01.13, 21:27, Mattias Gaertner пишет:

You are free to not use a feature, but you must understand all when using third party code. And the new features are neither easy to understand nor to remember.

Already replied to Michael. You don't need to understand third-party code the same way as you don't need to understand API sources. For winapi and cocoa you don't even have the sources to understand something.

True. But it adds quite a lot of stuff and a simple loop can become much slower.

True. Classes adds quite a lot of stuff and simple procedures can become much slower. Let's don't use them.

> I also used types inside classes - this is a great feature. I don't need > to polute global namespace with internal types. True. What about nested classes?

Class is just one of the types pascal have. If for some reason you need to use internal class - use it. But in my practive I mostly need some enumerations.

Show quoted text 7 lines
> I would use anonymouse methods in pascal - I use them in javascript when > I need to perform something asynchronosly. Correct me if I'm wrong, but all the alternatives in javascript have some drawbacks, you don't write big programs in javascript and the anonymous methods easily confuse the javascript debuggers.

You can use named methods too wihout drawbacks. Of course one of the benefits of anonymouse methods is javascript is access to local variables. And I don't notice that chrome debugger is confused much by them.

Best regards,
Paul Ishenin

Reply by email

Michael Van Canneyt
to Paul Ishenin: Very weak argument :) In your work you use system APIs and other frameworks which are…
Paul Ishenin wrote 12 lines
28.01.13, 21:20, Michael Van Canneyt wrote: >> Different people see different needs in language. There is nothing bad >> not to use and not understand some of the language features. > > tatata, you should always understand everything :) Very weak argument :) In your work you use system APIs and other frameworks which are made in C, C++ or assembler. I believe you don't understand everything and if you don't - you use the reference if needed. The same way with pascal - if you don't want to learn new features then use libraries as black boxes but if you need then use a reference.

I can understand the argument for libraries, but not for the programming language itself.

Show quoted text 9 lines
>> I would use anonymouse methods in pascal - I use them in javascript >> when I need to perform something asynchronosly. > > Since you can do the same with simple named methods too, I see no need > for creating the readibility horror that results of it. It is a readability horror when for injecting a small piece of code as anonymouse method in place where it is needed you *must* declare a new named method (which will no be used anywhere else) few screens up or down.

Absolutely. You have local procedures for exactly this reason. That is what Pascal stands for.

I use Anonymous methods in Javascript too, but in the majority of cases I end up naming them anyway.

So I do not think the use case justifies the mutilation.

> It offers nothing that objects didn't already have. It offers understandable memory layout without VMT.

That could have been solved with a simple "novmt' keyword just like the existing 'packed'. There, I could have saved Embarcadero lots of valuable time with that :-)

Enough bickering; it is useless. We will not agree, no matter how many arguments are presented: simply because the arguments are of a metaphysical/human/whatever nature, and not technical.

Michael.

Reply by email

Paul Ishenin
to Michael Van Canneyt

28.01.13, 21:51, Michael Van Canneyt пишет:

Enough bickering; it is useless. We will not agree, no matter how many arguments are presented: simply because the arguments are of a metaphysical/human/whatever nature, and not technical.

Agreed.

Best regards,
Paul Ishenin

Reply by email

Sven Barth
to Paul Ishenin: Very weak argument :) In your work you use system APIs and other frameworks which are…
Paul Ishenin wrote 11 lines
>> I would use anonymouse methods in pascal - I use them in javascript >> when I need to perform something asynchronosly. > > Since you can do the same with simple named methods too, I see no need > for creating the readibility horror that results of it. It is a readability horror when for injecting a small piece of code as anonymouse method in place where it is needed you *must* declare a new named method (which will no be used anywhere else) few screens up or down.

I agree here. Also think about e.g. Synchronize. You must create a parameterless method + fields for each method you want to execute in the main thread. Here I definitely prefer anonymous methods. And an also important aspect of them is that they can "capture" variable state from outside it's body. You can't do the exact same with nested procedures...

Regards,
Sven

Reply by email

Sven Barth
to Paul Ishenin: 28.01.13, 21:27, Mattias Gaertner пишет: Already replied to Michael. You don't need…
Paul Ishenin wrote 9 lines
28.01.13, 21:27, Mattias Gaertner пишет: > You are free to not use a feature, but you must understand all when > using third party code. And the new features are neither easy to > understand nor to remember. Already replied to Michael. You don't need to understand third-party code the same way as you don't need to understand API sources. For winapi and cocoa you don't even have the sources to understand something.

For WinAPI: Wine/ReactOS
For Cocoa: GNUStep

:)

Regards,
Sven

Reply by email

Alexander Klenin
to Paul Ishenin: Very weak argument :) In your work you use system APIs and other frameworks which are…
Paul Ishenin wrote 11 lines
>> I would use anonymouse methods in pascal - I use them in javascript >> when I need to perform something asynchronosly. > > > Since you can do the same with simple named methods too, I see no need > for creating the readibility horror that results of it. It is a readability horror when for injecting a small piece of code as anonymouse method in place where it is needed you *must* declare a new named method (which will no be used anywhere else) few screens up or down.

Note that readability troubles of anonymous functions in Pascal are largely due to unfortunate syntax.
In a parallel thread, I have offered some suggestions to make them much more readable.

> It offers nothing that objects didn't already have. It offers understandable memory layout without VMT.

Oops... so, FPC "object" type always creates VMT -- even if there is no virtual methods?

Alexander S. Klenin

Reply by email

Jonas Maebe
to Alexander Klenin
Alexander Klenin wrote 5 lines
On Tue, Jan 29, 2013 at 12:39 AM, Paul Ishenin wrote: >> It offers nothing that objects didn't already have. > It offers understandable memory layout without VMT. Oops... so, FPC "object" type always creates VMT -- even if there is no virtual methods?

Not always, but there are other conditions when a VMT is generated for objects, just like in Delphi/TP: when a constructor or destructor exists. In general, I'd also strongly recommend to treat them as opaque types, especially because this VMT may be inserted in the middle of the object, and be subject to special alignment requirements because of the target (regardless of the current {$packrecords x} or packed setting).

Jonas

Reply by email

Hans-Peter Diettrich
to Paul Ishenin: Very weak argument :) In your work you use system APIs and other frameworks which are…
Show quoted text 13 lines
28.01.13, 21:20, Michael Van Canneyt wrote: >> Different people see different needs in language. There is nothing bad >> not to use and not understand some of the language features. > > tatata, you should always understand everything :) Very weak argument :) In your work you use system APIs and other frameworks which are made in C, C++ or assembler. I believe you don't understand everything and if you don't - you use the reference if needed. The same way with pascal - if you don't want to learn new features then use libraries as black boxes but if you need then use a reference.

As a strong argument: you *must* understand everything when you want to read other people's code, which use the new language features :-(

IMO most of the new features had been added *only* for .NET compatibility. But since Delphi.NET is dead, I see no need to introduce them into FPC, where .NET never was on topic. But I understand that the compiler developers need something to put their hands on, so that the new language features come in at the right time. The Delphi developers had a goal (.NET) and limited time, while the FPC developers have time and look out for new goals. At least it's more fun to implement something very new, instead of working on incomplete parts (loadable libraries, targets) which had been delayed due to problems. The same situation in Lazarus and in many open source projects BTW.

DoDi

Reply by email

Paul Ishenin
to Hans-Peter Diettrich
Hans-Peter Diettrich wrote
As a strong argument: you *must* understand everything when you want to read other people's code, which use the new language features :-(

Only if you want this. And if you want a new feature will not stop you. Your brains learn something every day anyway. And I believe that the majority of features which you touch below are easy to learn and understand. At least it must be much easier to learn and understand than code from fpc\rtl\i386 which nobody complains about.

Show quoted text 12 lines
IMO most of the new features had been added *only* for .NET compatibility. But since Delphi.NET is dead, I see no need to introduce them into FPC, where .NET never was on topic. But I understand that the compiler developers need something to put their hands on, so that the new language features come in at the right time. The Delphi developers had a goal (.NET) and limited time, while the FPC developers have time and look out for new goals. At least it's more fun to implement something very new, instead of working on incomplete parts (loadable libraries, targets) which had been delayed due to problems. The same situation in Lazarus and in many open source projects BTW.

Where are your patches for loadable libraries and new targets?

Best regards,
Paul Ishenin

Reply by email

Hans-Peter Diettrich
to Paul Ishenin
Show quoted text 6 lines
> At least it's more fun to implement > something very new, instead of working on incomplete parts (loadable > libraries, targets) which had been delayed due to problems. The same > situation in Lazarus and in many open source projects BTW. Where are your patches for loadable libraries and new targets?

Where are the bugs to fix?

DoDi

Reply by email

Paul Ishenin
to Hans-Peter Diettrich

29.01.13, 17:23, Hans-Peter Diettrich пишет:

Show quoted text 10 lines
Paul Ishenin schrieb: >> At least it's more fun to implement >> something very new, instead of working on incomplete parts (loadable >> libraries, targets) which had been delayed due to problems. The same >> situation in Lazarus and in many open source projects BTW. > > Where are your patches for loadable libraries and new targets? Where are the bugs to fix?

I don't know. I thought you know that since you wrote about them.

Best regards,
Paul Ishenin

Reply by email

Hans-Peter Diettrich
to Paul Ishenin
Show quoted text 13 lines
29.01.13, 17:23, Hans-Peter Diettrich пишет: > Paul Ishenin schrieb: > >>> At least it's more fun to implement >>> something very new, instead of working on incomplete parts (loadable >>> libraries, targets) which had been delayed due to problems. The same >>> situation in Lazarus and in many open source projects BTW. >> >> Where are your patches for loadable libraries and new targets? > > Where are the bugs to fix? I don't know. I thought you know that since you wrote about them.

I wrote about FPC developers, and incomplete implementations. The ability to read an ToDo file doesn't require any knowledge about the matter, nor the ability to provide patches.

DoDi

Reply by email