Fed up

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

Fed up

ducasse
Hi

I’m fed up. Why?
Because I see lousy code in Pharo and that such lousy code in Pharo is slower, and sure that writing a type inferencer
for pharo will be more complex, and probably will make sista more complex too.

I asked the pharo consortium to take a clear position because I want a better Pharo not the inverse.
So what is it.

You can write in your code but not in Pharo.

        aCol do: #store

in Pharo we should write
       
        aCol do: [ :each | each store ]

Block argument should be blocks else any static analyser will have to check it is a block, it is a symbol, is
it a RANDOM object that answer value.

Seriously can be not make the life of people doing program analysis simpler?

So now if I’m wrong then I will shut up and I’m really pissed that we do that without paying attention
to the consequence.

I asked the consortium to take position and to take action.
We should have a better code review for REAL.

S.



Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Aliaksei Syrel
Hi 

Indeed, iterating over a collection using symbols is somewhat ~20% slower :)

Here are some numbers:

aCol := (1 to: 100000000). 

[ 10 timesRepeat: [ aCol do: #yourself ] ] timeToRunWithoutGC / 10.0. "1110.8"
[ 10 timesRepeat: [ aCol do: [ :each | each yourself ] ] ] timeToRunWithoutGC / 10.0. "898.1". 

(1110.8 - 898.1) / 1110.8 * 100 "19.14836154123154"

Cheers,
Alex

On Tue, 21 Jan 2020 at 21:11, ducasse <[hidden email]> wrote:
Hi

I’m fed up. Why?
Because I see lousy code in Pharo and that such lousy code in Pharo is slower, and sure that writing a type inferencer
for pharo will be more complex, and probably will make sista more complex too.

I asked the pharo consortium to take a clear position because I want a better Pharo not the inverse.
So what is it.

You can write in your code but not in Pharo.

        aCol do: #store

in Pharo we should write

        aCol do: [ :each | each store ]

Block argument should be blocks else any static analyser will have to check it is a block, it is a symbol, is
it a RANDOM object that answer value.

Seriously can be not make the life of people doing program analysis simpler?

So now if I’m wrong then I will shut up and I’m really pissed that we do that without paying attention
to the consequence.

I asked the consortium to take position and to take action.
We should have a better code review for REAL.

S.



Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Sean P. DeNigris
Administrator
In reply to this post by ducasse
ducasse wrote
> in Pharo we should write
> aCol do: [ :each | each store ]

I always enjoyed the Symbol/Block polymorphism because I thought it was such
a clever and visible example of the power of Smalltalk, and, let's face it,
I'm lazy and enjoyed saving a few key strokes!

That said, I had no idea that there was a dramatic performance cost. Also,
the issues you raise about analysis seem important.

Since people are free to still use it in their own projects, it doesn't seem
to controversial. Can/should we add a lint rule? Can/should it be scoped to
Pharo core?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Esteban A. Maringolo
I also like the polymorphism of the #value: message, not only with Symbols but also with MADescriptions and many other uses.

If that feds you up, and others too, maybe that "convention" (to use blocks only) might be scoped to Pharo core (whatever that is) methods.

Regards,

El mar., 21 de enero de 2020 19:35, Sean P. DeNigris <[hidden email]> escribió:
ducasse wrote
> in Pharo we should write     
>       aCol do: [ :each | each store ]

I always enjoyed the Symbol/Block polymorphism because I thought it was such
a clever and visible example of the power of Smalltalk, and, let's face it,
I'm lazy and enjoyed saving a few key strokes!

That said, I had no idea that there was a dramatic performance cost. Also,
the issues you raise about analysis seem important.

Since people are free to still use it in their own projects, it doesn't seem
to controversial. Can/should we add a lint rule? Can/should it be scoped to
Pharo core?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html

Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Sven Van Caekenberghe-2
In reply to this post by Sean P. DeNigris
I also like the use of symbols but more for casual code.

I know using blocks can be faster, but the difference is not massive.

What I don't understand is why it is so super bad. Polymorphism will always be there, that is really powerful, when used wisely. I can't immediately see why one or the other would make analysis easier or better. Can you explain ?

> On 21 Jan 2020, at 23:37, Sean P. DeNigris <[hidden email]> wrote:
>
> ducasse wrote
>> in Pharo we should write
>> aCol do: [ :each | each store ]
>
> I always enjoyed the Symbol/Block polymorphism because I thought it was such
> a clever and visible example of the power of Smalltalk, and, let's face it,
> I'm lazy and enjoyed saving a few key strokes!
>
> That said, I had no idea that there was a dramatic performance cost. Also,
> the issues you raise about analysis seem important.
>
> Since people are free to still use it in their own projects, it doesn't seem
> to controversial. Can/should we add a lint rule? Can/should it be scoped to
> Pharo core?
>
>
>
> -----
> Cheers,
> Sean
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>


Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Ronie Salgado
That performance regression looks more like a language implementation bug that a problem of the language itself. If we assume that #do: and some other selectors (e.g. #select, #reject) should always receive a block instead of a symbol, then the compiler could perfectly replace the symbol literal for an already instantiated block literal transparently from the user perspective. If the compiler does that we can save the bytecode for instantiating the block closure, which can save a potential roundtrip to the garbage collector. I guess (I am just speculating) that this performance overhead must be in the implementation of the #perform: primitive, which I guess has to:
1) go through the JIT stack into the C stack transition (saving/restoring interpreter/JIT state, additional pressure, and primitive activation overhead.
2) the lack of inline caches for #perform: (again, I am just guessing in this case).

Note that the OpalCompiler is currently inlining some methods such as #ifTrue:ifFalse: ,  #ifNil:ifNotNil: #and: #or: and there are not actual message sends, so adding an additional list of selector where literal symbol arguments are synthesized as blocks is not different to the cheating that the current compiler is doing. If an user wants to disable this inlining, there is currently a pragma for telling the compiler.

Do you want me to propose an experimental patch for testing this infrastructure?

Best regards,
Ronie

El mar., 21 ene. 2020 a las 19:56, Sven Van Caekenberghe (<[hidden email]>) escribió:
I also like the use of symbols but more for casual code.

I know using blocks can be faster, but the difference is not massive.

What I don't understand is why it is so super bad. Polymorphism will always be there, that is really powerful, when used wisely. I can't immediately see why one or the other would make analysis easier or better. Can you explain ?

> On 21 Jan 2020, at 23:37, Sean P. DeNigris <[hidden email]> wrote:
>
> ducasse wrote
>> in Pharo we should write     
>>      aCol do: [ :each | each store ]
>
> I always enjoyed the Symbol/Block polymorphism because I thought it was such
> a clever and visible example of the power of Smalltalk, and, let's face it,
> I'm lazy and enjoyed saving a few key strokes!
>
> That said, I had no idea that there was a dramatic performance cost. Also,
> the issues you raise about analysis seem important.
>
> Since people are free to still use it in their own projects, it doesn't seem
> to controversial. Can/should we add a lint rule? Can/should it be scoped to
> Pharo core?
>
>
>
> -----
> Cheers,
> Sean
> --
> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>


Reply | Threaded
Open this post in threaded view
|

Re: Fed up

ducasse


> On 22 Jan 2020, at 01:43, Ronie Salgado <[hidden email]> wrote:
>
> That performance regression looks more like a language implementation bug that a problem of the language itself.

Probably but you see it via an optimisation prism. The problem is not just an optimisation of perform: which should be done
in any way and orthogonally to this problem.

Now what if we want to build static analysers.
We put the burden on tool maker.
If I have a write a type inferencer or a call graph then I will have to consider that the arg is
        - a block and do block analysis
        - a symbol and do a special treatment

This is slightly not relayed but since any object understands value…..
we just dropped the possibility to use the code representation to gain some information about the program.

This exactly for this reason that the classDefinition is a good move because sending a message to a class
is a bad idea (easy and sweet at the beginning) but you cannot build nice tools, you cannot easily build remote code browser
and perform dependency analyses (oh yes we can we build ring for it and many more).


> If we assume that #do: and some other selectors (e.g. #select, #reject) should always receive a block instead of a symbol, then the compiler could perfectly replace the symbol literal for an already instantiated block literal transparently from the user perspective.

Yes this is the optimisation I mention.

> If the compiler does that we can save the bytecode for instantiating the block closure, which can save a potential roundtrip to the garbage collector. I guess (I am just speculating) that this performance overhead must be in the implementation of the #perform: primitive, which I guess has to:
> 1) go through the JIT stack into the C stack transition (saving/restoring interpreter/JIT state, additional pressure, and primitive activation overhead.
> 2) the lack of inline caches for #perform: (again, I am just guessing in this case).
>
> Note that the OpalCompiler is currently inlining some methods such as #ifTrue:ifFalse: ,  #ifNil:ifNotNil: #and: #or: and there are not actual message sends, so adding an additional list of selector where literal symbol arguments are synthesized as blocks is not different to the cheating that the current compiler is doing. If an user wants to disable this inlining, there is currently a pragma for telling the compiler.
>
> Do you want me to propose an experimental patch for testing this infrastructure?

It would be nice but to me it is not exactly my point.
After we should also see what is the impact on the decompiler, debugger, ….


Now there is no such closed list of selectors that accept a block and now get a symbol.

At the end what I would like in Pharo is a scientific process:
        Where we
                propose
                measure
                evaluate and
                decide once we have the data

and not just oh this is easy let us make it.

Pharo will not be a nice language by just adding tricks on top of tricks.

S.





Reply | Threaded
Open this post in threaded view
|

Re: Fed up

ducasse
In reply to this post by Esteban A. Maringolo


On 21 Jan 2020, at 23:46, Esteban Maringolo <[hidden email]> wrote:

I also like the polymorphism of the #value: message, not only with Symbols but also with MADescriptions and many other uses.


Thanks this is exactly my point and I do not like it because this is cheap and put the hell on tools. 
Of course the alternative is a bit more verbose because if you want to have 

aCol do: MADescription new

then 
you would have to have 

myDomain >> do: anObject

…. …. anObject value: ….


But this means that a type inferencer could see that your code is calling this domain >> do: with a MADescription

Now we destroy all the knowledge because do: has as argument anything on earth.
What a gain. 
We went from

any do: argument is a block and your do: has a MA 

to any do: implementation can get any object. 

So forget do build nice tools. 

After we can all program with perform: everywhere, but the trade we make is lame. 

Symbol >> value: anObject 
^anObject perform: self.


I have no problem that libraries break the possibility to have better tools applied to them. 
To me having value in Object is bad. 

I’m fed up of our attitude.
We are lame because we do not look further than our little nose. 

S. 


If that feds you up, and others too, maybe that "convention" (to use blocks only) might be scoped to Pharo core (whatever that is) methods.

Regards,

El mar., 21 de enero de 2020 19:35, Sean P. DeNigris <[hidden email]> escribió:
ducasse wrote
> in Pharo we should write     
>       aCol do: [ :each | each store ]

I always enjoyed the Symbol/Block polymorphism because I thought it was such
a clever and visible example of the power of Smalltalk, and, let's face it,
I'm lazy and enjoyed saving a few key strokes!

That said, I had no idea that there was a dramatic performance cost. Also,
the issues you raise about analysis seem important.

Since people are free to still use it in their own projects, it doesn't seem
to controversial. Can/should we add a lint rule? Can/should it be scoped to
Pharo core?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html


Reply | Threaded
Open this post in threaded view
|

Re: Fed up

ducasse
In reply to this post by Sven Van Caekenberghe-2


> On 21 Jan 2020, at 23:56, Sven Van Caekenberghe <[hidden email]> wrote:
>
> I also like the use of symbols but more for casual code.
>
> I know using blocks can be faster, but the difference is not massive.

The difference is not only in speed.
And it is exactly why I do not like value in Object.

> What I don't understand is why it is so super bad. Polymorphism will always be there, that is really powerful, when used wisely. I can't immediately see why one or the other would make analysis easier or better. Can you explain ?

See my reply to esteban.


>> On 21 Jan 2020, at 23:37, Sean P. DeNigris <[hidden email]> wrote:
>>
>> ducasse wrote
>>> in Pharo we should write
>>> aCol do: [ :each | each store ]
>>
>> I always enjoyed the Symbol/Block polymorphism because I thought it was such
>> a clever and visible example of the power of Smalltalk, and, let's face it,
>> I'm lazy and enjoyed saving a few key strokes!
>>
>> That said, I had no idea that there was a dramatic performance cost. Also,
>> the issues you raise about analysis seem important.
>>
>> Since people are free to still use it in their own projects, it doesn't seem
>> to controversial. Can/should we add a lint rule? Can/should it be scoped to
>> Pharo core?
>>
>>
>>
>> -----
>> Cheers,
>> Sean
>> --
>> Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html
>>
>
>




Reply | Threaded
Open this post in threaded view
|

Re: Fed up

Pharo Smalltalk Developers mailing list
In reply to this post by ducasse
+1000

I'm with you 110% on this one!

Who, in their right mind, would code like that? Is it a trend among
younger Smalltalkers while dinosaurs like me just "naturally" still use
the "old way" and blocks? And do we have statistics about how often that
"syntax" is used in the current image? In the past, I've complained a
gazillion times about portability between Pharo and other Smalltalks
and/or legacy code so you pretty much know my position on this kind of
semantic twist!  Okay, one might argue that using a symbol instead of a
Block in your example saves you a big 16 characters to type.  But who
spends all their day mostly iterating over a collection so that it
becomes an issue to save 16 characters ???  And then, once we open that
door, what's next?

aCol do: [:eachItem | eachItem calculateProvincialTax. eachItem
calculateFederalTax. eachItem calculateRebates. eachItem calculateTotal]

Then, are we going to end up with "keystroke-savers" like:

aCol do: #calculateProvincialTax and: #calculateFederalTax and:
#calculateRebates and: calculateTotal

Yeah, polymorphism is cool. But "coolness" has never been a reason in
itself alone to use cool features just because they do exist!

</rant>

;)


On 2020-01-21 15:10, ducasse wrote:

> Hi
>
> I’m fed up. Why?
> Because I see lousy code in Pharo and that such lousy code in Pharo is slower, and sure that writing a type inferencer
> for pharo will be more complex, and probably will make sista more complex too.
>
> I asked the pharo consortium to take a clear position because I want a better Pharo not the inverse.
> So what is it.
>
> You can write in your code but not in Pharo.
>
> aCol do: #store
>
> in Pharo we should write
>
> aCol do: [ :each | each store ]
>
> Block argument should be blocks else any static analyser will have to check it is a block, it is a symbol, is
> it a RANDOM object that answer value.
>
> Seriously can be not make the life of people doing program analysis simpler?
>
> So now if I’m wrong then I will shut up and I’m really pissed that we do that without paying attention
> to the consequence.
>
> I asked the consortium to take position and to take action.
> We should have a better code review for REAL.
>
> S.
>
>
>
--
-----------------
Benoît St-Jean
Yahoo! Messenger: bstjean
Twitter: @BenLeChialeux
Pinterest: benoitstjean
Instagram: Chef_Benito
IRC: lamneth
GitHub: bstjean
Blogue: endormitoire.wordpress.com
"A standpoint is an intellectual horizon of radius zero".  (A. Einstein)


Reply | Threaded
Open this post in threaded view
|

Re: Fed up

gcotelli
In reply to this post by ducasse
Hi!

I see no problem in replacing the symbol usage with blocks. It's a nice shortcut for scripting but not a game changer.
And I'm also in favor of being cautious before introducing new things without analyzing it's impact.

However, I see use cases for using objects polymorphic with blocks. A common case is to use some reification for a condition instead of a block evaluating to true/false. We have many of this in our systems where the end user needs to filter some kind of collection, and the filtering options are based on some other objects that the user creates in the system, and the user also wants to save his filter configuration so the next login this options are preserved. If you try to use blocks to model this conditions is more complex than using a proper abstraction, and more if you end up needing to persist this preferences in a relational database.

I don't know how this kind of scenario impacts the analyzer but for sure it has to cope with the reality that the people will be using things polymorphic with blocks. And if the analysis is static sometimes the object will be a block, but will come in an argument of the method and you don't know that doing static analysis.



On Wed, Jan 22, 2020 at 5:09 AM ducasse <[hidden email]> wrote:


On 21 Jan 2020, at 23:46, Esteban Maringolo <[hidden email]> wrote:

I also like the polymorphism of the #value: message, not only with Symbols but also with MADescriptions and many other uses.


Thanks this is exactly my point and I do not like it because this is cheap and put the hell on tools. 
Of course the alternative is a bit more verbose because if you want to have 

aCol do: MADescription new

then 
you would have to have 

myDomain >> do: anObject

…. …. anObject value: ….


But this means that a type inferencer could see that your code is calling this domain >> do: with a MADescription

Now we destroy all the knowledge because do: has as argument anything on earth.
What a gain. 
We went from

any do: argument is a block and your do: has a MA 

to any do: implementation can get any object. 

So forget do build nice tools. 

After we can all program with perform: everywhere, but the trade we make is lame. 

Symbol >> value: anObject 
^anObject perform: self.


I have no problem that libraries break the possibility to have better tools applied to them. 
To me having value in Object is bad. 

I’m fed up of our attitude.
We are lame because we do not look further than our little nose. 

S. 


If that feds you up, and others too, maybe that "convention" (to use blocks only) might be scoped to Pharo core (whatever that is) methods.

Regards,

El mar., 21 de enero de 2020 19:35, Sean P. DeNigris <[hidden email]> escribió:
ducasse wrote
> in Pharo we should write     
>       aCol do: [ :each | each store ]

I always enjoyed the Symbol/Block polymorphism because I thought it was such
a clever and visible example of the power of Smalltalk, and, let's face it,
I'm lazy and enjoyed saving a few key strokes!

That said, I had no idea that there was a dramatic performance cost. Also,
the issues you raise about analysis seem important.

Since people are free to still use it in their own projects, it doesn't seem
to controversial. Can/should we add a lint rule? Can/should it be scoped to
Pharo core?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html


Reply | Threaded
Open this post in threaded view
|

Re: Fed up

ducasse


On 22 Jan 2020, at 13:10, Gabriel Cotelli <[hidden email]> wrote:

Hi!

I see no problem in replacing the symbol usage with blocks. It's a nice shortcut for scripting but not a game changer.
And I'm also in favor of being cautious before introducing new things without analyzing it's impact.

this is my point. 

However, I see use cases for using objects polymorphic with blocks. A common case is to use some reification for a condition instead of a block evaluating to true/false. We have many of this in our systems where the end user needs to filter some kind of collection, and the filtering options are based on some other objects that the user creates in the system, and the user also wants to save his filter configuration so the next login this options are preserved. If you try to use blocks to model this conditions is more complex than using a proper abstraction, and more if you end up needing to persist this preferences in a relational database.

Indeed now we found cool to be able to do it. 
But what is the cost because nothing prevent you to have your own vocabulary. 
This is what RBCondition is doing for example. 


I don't know how this kind of scenario impacts the analyzer but for sure it has to cope with the reality that the people will be using things polymorphic with blocks. And if the analysis is static sometimes the object will be a block, but will come in an argument of the method and you don't know that doing static analysis.



On Wed, Jan 22, 2020 at 5:09 AM ducasse <[hidden email]> wrote:


On 21 Jan 2020, at 23:46, Esteban Maringolo <[hidden email]> wrote:

I also like the polymorphism of the #value: message, not only with Symbols but also with MADescriptions and many other uses.


Thanks this is exactly my point and I do not like it because this is cheap and put the hell on tools. 
Of course the alternative is a bit more verbose because if you want to have 

aCol do: MADescription new

then 
you would have to have 

myDomain >> do: anObject

…. …. anObject value: ….


But this means that a type inferencer could see that your code is calling this domain >> do: with a MADescription

Now we destroy all the knowledge because do: has as argument anything on earth.
What a gain. 
We went from

any do: argument is a block and your do: has a MA 

to any do: implementation can get any object. 

So forget do build nice tools. 

After we can all program with perform: everywhere, but the trade we make is lame. 

Symbol >> value: anObject 
^anObject perform: self.


I have no problem that libraries break the possibility to have better tools applied to them. 
To me having value in Object is bad. 

I’m fed up of our attitude.
We are lame because we do not look further than our little nose. 

S. 


If that feds you up, and others too, maybe that "convention" (to use blocks only) might be scoped to Pharo core (whatever that is) methods.

Regards,

El mar., 21 de enero de 2020 19:35, Sean P. DeNigris <[hidden email]> escribió:
ducasse wrote
> in Pharo we should write     
>       aCol do: [ :each | each store ]

I always enjoyed the Symbol/Block polymorphism because I thought it was such
a clever and visible example of the power of Smalltalk, and, let's face it,
I'm lazy and enjoyed saving a few key strokes!

That said, I had no idea that there was a dramatic performance cost. Also,
the issues you raise about analysis seem important.

Since people are free to still use it in their own projects, it doesn't seem
to controversial. Can/should we add a lint rule? Can/should it be scoped to
Pharo core?



-----
Cheers,
Sean
--
Sent from: http://forum.world.st/Pharo-Smalltalk-Developers-f1294837.html



Reply | Threaded
Open this post in threaded view
|

Re: Fed up

John Brant-2
In reply to this post by Pharo Smalltalk Developers mailing list
On Jan 22, 2020, at 5:20 AM, Benoit St-Jean via Pharo-dev <[hidden email]> wrote:
>
> Who, in their right mind, would code like that? Is it a trend among younger Smalltalkers while dinosaurs like me just "naturally" still use the "old way" and blocks?

Using symbols for blocks has been around for quite some time. I heard about it from Ward Cunningham about 25 years ago. Early Smalltalk images were limited by the number of objects that could exist. If you used a block, then you needed to create an object for that block, but if you used a symbol, you didn’t need any additional objects as the symbol already existed. When I heard about this, I didn’t know of any Smalltalk’s that implemented Symbol>>value: in their base classes. I think it was a couple years later before I started seeing it used.

As for whether Symbol>>value: should exist in the base Pharo image, I don’t have a strong opinion. There are a bunch of methods/classes that could be removed from the base image and put into add-on packages. As for whether Pharo should allow someone to create such a method, I think it should. It really isn’t any different from allowing me to add any method to any other class. As for the readability of the code, once you know the symbol as block “trick”, I find that they are both almost equally readable. In fact, the symbol version may be a little more readable as when you scan the block, you must check the receiver is “each” and not something else like “self” (which is the same length as “each”). Finally, as for making a type inferencer more complex, dealing with dynamically typed Smalltalk is already a complex job so if you can handle it without symbol blocks, I doubt that it would take much more to add support for them.

BTW, there are other objects that implement #value:, and can be used instead of blocks. For example, to get a collection of the first 256 characters:
        (0 to: 255) collect: Character


John Brant
Reply | Threaded
Open this post in threaded view
|

Re: Fed up

ducasse


> On 22 Jan 2020, at 18:29, John Brant <[hidden email]> wrote:
>
> On Jan 22, 2020, at 5:20 AM, Benoit St-Jean via Pharo-dev <[hidden email]> wrote:
>>
>> Who, in their right mind, would code like that? Is it a trend among younger Smalltalkers while dinosaurs like me just "naturally" still use the "old way" and blocks?
>
> Using symbols for blocks has been around for quite some time. I heard about it from Ward Cunningham about 25 years ago. Early Smalltalk images were limited by the number of objects that could exist. If you used a block, then you needed to create an object for that block, but if you used a symbol, you didn’t need any additional objects as the symbol already existed. When I heard about this, I didn’t know of any Smalltalk’s that implemented Symbol>>value: in their base classes. I think it was a couple years later before I started seeing it used.

This is a fun perspective.

To me this is do we want to have a language that is super permissive instead of permissive and at which costs.
Not measuring costs is not a good way to take decision.

> As for whether Symbol>>value: should exist in the base Pharo image, I don’t have a strong opinion. There are a bunch of methods/classes that could be removed from the base image and put into add-on packages. As for whether Pharo should allow someone to create such a method, I think it should. It really isn’t any different from allowing me to add any method to any other class. As for the readability of the code, once you know the symbol as block “trick”, I find that they are both almost equally readable. In fact, the symbol version may be a little more readable as when you scan the block, you must check the receiver is “each” and not something else like “self” (which is the same length as “each”). Finally, as for making a type inferencer more complex, dealing with dynamically typed Smalltalk is already a complex job so if you can handle it without symbol blocks, I doubt that it would take much more to add support for them.

I will discuss it next week with Pablo because he wrote one.

>
> BTW, there are other objects that implement #value:, and can be used instead of blocks. For example, to get a collection of the first 256 characters:
> (0 to: 255) collect: Character

To me this is not needed. Again my point is does it bring something for real or this is just a nice hack.
And what is the impact.

>
>
> John Brant