[Pharo-project] ('a' == 'a') == true ?
I convinced the teacher who will be taking over my Smalltalk courses at UCLouvain (starting this week) to use Pharo :-) One of the introductory exercises in these courses shows the difference between '==' and '='. However, in Pharo (&Squeak) the following goes wrong imho: 'a' == 'a' -> true $a asString == $a asString -> false It seems that when you evaluate the expression, the (semantically identical) strings are represented as the same literal in the compiled block. For example, try to evaluate the following code by evaluating each statement in a separate doit. Then do it again as a single block... |a b| a := 'a'. b := 'a'. a == b inspect Do I make it an issue? Is there already an issue? (did not find one) Am I wrong? Johan
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal) Johan
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not. Also keep in mind that #== optimized by compiler. So , even if you override it in some class, it won't behave differently. And #=, of course, can be implemented in any way you like. One of interesting example: = anObject ^ false saying 'i am not equal to anything' :)
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate: a := #foobar. b := #foobar. a == b. a := 'foobar'. b := 'foobar'. a == b The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw). Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email. I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-) cheers Johan
On 27 September 2010 12:51, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
Why waiting for sprint? Implement String>>literalEqueal: anObject ^ self == anObject and then you have 'aaa' == 'aaa' -> false :)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On 27 September 2010 13:34, Igor Stasenko <siguctua@gmail.com> wrote:
On 27 September 2010 12:51, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
Why waiting for sprint?
Implement
String>>literalEqueal: anObject
oops. sorry for typo , a right selector is #literalEqual:
 ^ self == anObject
and then you have 'aaa' == 'aaa' Â -> false
:)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
-- Best regards, Igor Stasenko AKA sig.
Hi all! This issue is listed as a "newbie trap" on this page, search for "newbie trap": http://wiki.squeak.org/squeak/3644 ...and there is another cool one just above, which goes like this: "This one actually is borrowed from Leandro Caniglia. He challenged me yesterday to figure out why the method SmallInteger>>gcd: actually works. The challenge can also be expressed like this: Evaluate this code below and figure out why n=5. One could ask oneself if the assignment (m := n) is performed after or before the evaluation of the expression? If it is done before - then n should become 4 right? (2 + 2) And if it is done after then it should become 6... (3 + 3) Gurus: don't spoil it for the newbies ok? Let them chew on it for a while... :-)" | m n | n := 2. m := 3. n := m + (m := n)
On 27 Sep 2010, at 12:34, Igor Stasenko wrote:
Why waiting for sprint?
I guess I thought the solution was more intricate than that :-)
Implement
String>>literalEqueal: anObject
^ self == anObject
and then you have 'aaa' == 'aaa' -> false
Thanks for pointing that out to me, Igor! I created an issue for it (3006) and will see later this week if it is a good idea to change the implementation of #literalEqual: to be less liberal. Johan
On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
If you evaluate it line by line, it will work as you expected. So you can even show how the compiler optimization works by evaluating it both ways. Levente
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Non-literal strings should do what you want. Bill ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Levente Uzonyi [leves@elte.hu] Sent: Monday, September 27, 2010 8:03 AM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] ('a' == 'a') == true ? On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
If you evaluate it line by line, it will work as you expected. So you can even show how the compiler optimization works by evaluating it both ways. Levente
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal. Inversely, I have never run into that issue myself either, until I was just testing those little snippets for the students. Or... at least, I think I never have :-) Johan
On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method. Levente
Inversely, I have never run into that issue myself either, until I was just testing those little snippets for the students. Or... at least, I think I never have :-)
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Wow! Thanks Levente for sharing this with us. Alexandre -- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
On 27 September 2010 22:10, Levente Uzonyi <leves@elte.hu> wrote:
On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Â Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Well, you can save a bit more, if you scan a whole image literals and unify them. This could be userful for tidying up the image size.
Levente
Inversely, I have never run into that issue myself either, until I was just testing those little snippets for the students. Or... at least, I think I never have :-)
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On Mon, 27 Sep 2010, Igor Stasenko wrote:
On 27 September 2010 22:10, Levente Uzonyi <leves@elte.hu> wrote: On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Â Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Well, you can save a bit more, if you scan a whole image literals and unify them. This could be userful for tidying up the image size. Probably yes, but that's not the point I guess. I just wanted to show that the current method doesn't really save much. Unifying the literals in the image is dangerous, because literal strings are not immutable (and they shouldn't be IMHO). So that could lead to random errors if a method is modifying a shared string literal. Levente
Levente
Inversely, I have never run into that issue myself either, until I was just testing those little snippets for the students. Or... at least, I think I never have :-)
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig. _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 27.09.2010 23:05, Levente Uzonyi wrote:
On Mon, 27 Sep 2010, Igor Stasenko wrote:
On 27 September 2010 22:10, Levente Uzonyi <leves@elte.hu> wrote: On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Well, you can save a bit more, if you scan a whole image literals and unify them. This could be userful for tidying up the image size.
Probably yes, but that's not the point I guess. I just wanted to show that the current method doesn't really save much. Unifying the literals in the image is dangerous, because literal strings are not immutable (and they shouldn't be IMHO). So that could lead to random errors if a method is modifying a shared string literal.
Levente
ByteString allInstances asBag sortedCounts Guess who the biggest waster in Core12147 is, at nearly 60KB duplicate strings for three top 5 finishes? :) Starting in VW post the immutable string literals change that was done there, I don't really mind it. Personally, I feel the gains are too low to even justify it for space efficiency reasons though, and the immutable string literal discussion, which would be needed, is a big one. I vaguely remember reading something like that in CompiledMethods, access is faster for literal slots 1-n, where n is a rather low number. Even if that would turn out to be true, I doubt it warrants the compiler optimizations for equivalent literal strings anymore though. Spacewise you've at least already debunked that it's needed :) Cheers, Henry
On 28 September 2010 00:29, Henrik Sperre Johansen <henrik.s.johansen@veloxit.no> wrote:
 On 27.09.2010 23:05, Levente Uzonyi wrote:
On Mon, 27 Sep 2010, Igor Stasenko wrote:
On 27 September 2010 22:10, Levente Uzonyi <leves@elte.hu> wrote: On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could also argue that VW lacks a useful optimization of literals. Â Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Well, you can save a bit more, if you scan a whole image literals and unify them. This could be userful for tidying up the image size.
Probably yes, but that's not the point I guess. I just wanted to show that the current method doesn't really save much. Unifying the literals in the image is dangerous, because literal strings are not immutable (and they shouldn't be IMHO). So that could lead to random errors if a method is modifying a shared string literal.
Levente
ByteString allInstances asBag sortedCounts Guess who the biggest waster in Core12147 is, at nearly 60KB Â duplicate strings for three top 5 finishes? :)
Starting in VW post the immutable string literals change that was done there, I don't really mind it. Personally, I feel the gains are too low to even justify it for space efficiency reasons though, and the immutable string literal discussion, which would be needed, is a big one.
I vaguely remember reading something like that in CompiledMethods, access is faster for literal slots 1-n, where n is a rather low number. Even if that would turn out to be true, I doubt it warrants the compiler optimizations for equivalent literal strings anymore though. Spacewise you've at least already debunked that it's needed :)
Well, unifying for space is one thing. Another is search for a literal in image. It could be much quicker if all literals are unified. Its not an invitation to do it, just to consider options which opening for us, if we do that :)
Cheers, Henry
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
On Mon, Sep 27, 2010 at 3:31 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 28 September 2010 00:29, Henrik Sperre Johansen <henrik.s.johansen@veloxit.no> wrote:
On 27.09.2010 23:05, Levente Uzonyi wrote:
On Mon, 27 Sep 2010, Igor Stasenko wrote:
On 27 September 2010 22:10, Levente Uzonyi <leves@elte.hu> wrote: On Mon, 27 Sep 2010, Johan Brichau wrote:
On 27 Sep 2010, at 14:37, Schwab,Wilhelm K wrote:
"Works fine" is a value judgment that can cut both ways: one could
also
argue that VW lacks a useful optimization of literals. Non-literal strings should do what you want.
I wonder how useful the optimization is, actually. Probably not many (if any) methods will use the same literal multiple times and count on the compiler to optimize them into the same literal.
I think this is from the 80's or 90's where this could save some memory. According to my calculations in Squeak 4.2 with some extra packages loaded it saves at least 36591 bytes (object size + 1 slot in the literal array), which is only 0.79 bytes / method.
Well, you can save a bit more, if you scan a whole image literals and unify them. This could be userful for tidying up the image size.
Probably yes, but that's not the point I guess. I just wanted to show that the current method doesn't really save much. Unifying the literals in the image is dangerous, because literal strings are not immutable (and they shouldn't be IMHO). So that could lead to random errors if a method is modifying a shared string literal.
Levente
ByteString allInstances asBag sortedCounts Guess who the biggest waster in Core12147 is, at nearly 60KB duplicate strings for three top 5 finishes? :)
Starting in VW post the immutable string literals change that was done there, I don't really mind it. Personally, I feel the gains are too low to even justify it for space efficiency reasons though, and the immutable string literal discussion, which would be needed, is a big one.
I vaguely remember reading something like that in CompiledMethods, access is faster for literal slots 1-n, where n is a rather low number. Even if that would turn out to be true, I doubt it warrants the compiler optimizations for equivalent literal strings anymore though. Spacewise you've at least already debunked that it's needed :)
Well, unifying for space is one thing. Another is search for a literal in image. It could be much quicker if all literals are unified.
Arguably, but much of the time would go in the search of methods for literals rather than the faster comparisons between literals. However, the notion that this would save space is suspect. To implement literal pooling you either slow-down compilation *a lot* by searching for literals amongst all methods (an implicit pool) or you maintain an explicit pool and likely end up _not saving any space_ since the space occupied by the pool is more-or-less equal to to the space saved by pooling since you'll likely find literals are shared approximately once. We've been-there-done-that with VisualWorks trying to pool the bytecodes in methods and abandoned the idea because there was no net space saving. So you need to quantify the degree of sharing you see in a typical dev image and see whether average sharing is significantly greater than 1. Its not an invitation to do it, just to consider options which opening
for us, if we do that :)
Cheers, Henry
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig.
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
From Pharo By Example: Symbols are like Strings, in that they contain a sequence of characters. However, unlike a string, a literal symbol is guaranteed to be globally unique. There is only one Symbol object #Hello but there *may be* multiple String objects with the value 'Hello'.
According to the above: Strings -> 1+ per value Symbols -> always one per value Where did you get that Strings are guaranteed not to be 1 per value? Sean -- View this message in context: http://forum.world.st/a-a-true-tp2715066p2715916.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
Johan Brichau-2 wrote:
where did I say that?
I thought that's what you meant by "imho the optimization yields a wrong semantics." If there is no guarantee on whether or not two strings with the same value are the same object, what is wrong with the result you observed? Sean -- View this message in context: http://forum.world.st/a-a-true-tp2715066p2716156.html Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
But that's the point, there should be no business semantics to '=='. Only reflective semantics. The reflective semantics are ok. Niko On Mon, Sep 27, 2010 at 11:51 AM, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- http://scg.unibe.ch/staff/Schwarz twitter.com/nes1983 Tel: +41 076 235 8683
Perhaps the discussion I wanted to raise is not about the use of '==' but about the fact that equal string literals in the same method body are optimized to be the same object. Without immutability, such optimization is just plain wrong. In addition, it does not even seem to be a particularly useful optimization. The use of '==' in the exercise is exactly about the reflective semantics, btw. Johan On 28 Sep 2010, at 10:05, Niko Schwarz wrote:
But that's the point, there should be no business semantics to '=='. Only reflective semantics. The reflective semantics are ok.
Niko
On Mon, Sep 27, 2010 at 11:51 AM, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- http://scg.unibe.ch/staff/Schwarz twitter.com/nes1983 Tel: +41 076 235 8683
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On Tue, Sep 28, 2010 at 7:39 AM, Johan Brichau <johan@inceptive.be> wrote:
Perhaps the discussion I wanted to raise is not about the use of '==' but about the fact that equal string literals in the same method body are optimized to be the same object. Without immutability, such optimization is just plain wrong. In addition, it does not even seem to be a particularly useful optimization.
I think it's orthogonal to immutability. Non-immutable literals are "just plain wrong" (actually unsafe). The optimization is confusing and unexpected to the inexperienced. But I emphatically agree with the last part; it's not a particularly useful optimization. cheers Eliot The use of '==' in the exercise is exactly about the reflective semantics,
btw.
Johan
On 28 Sep 2010, at 10:05, Niko Schwarz wrote:
But that's the point, there should be no business semantics to '=='. Only reflective semantics. The reflective semantics are ok.
Niko
On Mon, Sep 27, 2010 at 11:51 AM, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between
strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- http://scg.unibe.ch/staff/Schwarz twitter.com/nes1983 Tel: +41 076 235 8683
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
More over, the optimisation seems quite short sighted : | x | x := #( 'a' 'a'). ^x first == x last -> false For example, if I encode some "data" in an Array with strings, I can expect more frequent repetitions (I know, not very object oriented/ could also use Symbol/etc... but think of a simple 2D game), Nicolas 2010/9/28 Eliot Miranda <eliot.miranda@gmail.com>:
On Tue, Sep 28, 2010 at 7:39 AM, Johan Brichau <johan@inceptive.be> wrote:
Perhaps the discussion I wanted to raise is not about the use of '==' but about the fact that equal string literals in the same method body are optimized to be the same object. Without immutability, such optimization is just plain wrong. In addition, it does not even seem to be a particularly useful optimization.
I think it's orthogonal to immutability. Â Non-immutable literals are "just plain wrong" (actually unsafe). Â The optimization is confusing and unexpected to the inexperienced. Â But I emphatically agree with the last part; it's not a particularly useful optimization. cheers Eliot
The use of '==' in the exercise is exactly about the reflective semantics, btw.
Johan
On 28 Sep 2010, at 10:05, Niko Schwarz wrote:
But that's the point, there should be no business semantics to '=='. Only reflective semantics. The reflective semantics are ok.
Niko
On Mon, Sep 27, 2010 at 11:51 AM, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 11:28, Igor Stasenko wrote:
On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not.
Yes, this is exactly what the exercise is doing. I want them to be aware that equal _symbols_ are the same objects, but that equal _strings_ are not, which is why I let them evaluate:
a := #foobar. b := #foobar. a == b.
a := 'foobar'. b := 'foobar'. a == b
The problem is that evaluating the second snippet also yields true in Pharo/Squeak, so I cannot illustrate it using these snippets (which works fine in Visualworks, btw).
Yes, this is a compiler optimization and, yes, people should use #= instead of #== normally. But imho the optimization yields a wrong semantics, which is why I posted the email.
I have absolutely no clue if it can be changed (I am not familiar with the compiler implementation *at all*), but I would be happy to look over the shoulder of an experienced compiler hacker during the next sprint to learn ;-)
cheers Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- http://scg.unibe.ch/staff/Schwarz twitter.com/nes1983 Tel: +41 076 235 8683
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
On 28 Sep 2010, at 18:00, Eliot Miranda wrote:
I think it's orthogonal to immutability. Non-immutable literals are "just plain wrong" (actually unsafe). The optimization is confusing and unexpected to the inexperienced. But I emphatically agree with the last part; it's not a particularly useful optimization.
Of course, you are right: non-immutable literals are unsafe. However, when you know what you are doing and you are 'mutating' a literal in your code, I think it's surprising that the mutation also happens to what seems to be another literal in the same code (because they are written in different locations in the same method body), just because they happen to be equal. Admittedly, it's not a common issue and mutating literals might sound like dirty code (it probably is in 99% of the cases) but the flexibility also enables powerful things. I have, for example, used that in the implementation of the compiled methods for proxy java classes in JavaConnect. Anyway, I appreciate the discussion! Johan
#== (test for identity/same object) is perhaps most useful when verifying that objects are copying themselves as intended, or that code has or has not made a copy of an object - I lost a few hours this weekend over a glorified version of just that question :( Found it :) Literals can sometimes be confusing, being identical (courtesy of the compiler) when one might otherwise think they should be distinct but equal objects. As for whether a string and a symbol should have the same address, I am not convinced they would, but a good exercise for your students would be to make a C function that prints on stdout and/or returns the address of something passed to it, and then call it with both 'hello' and 'hello' asSymbol, #hello, etc. Bill ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Igor Stasenko [siguctua@gmail.com] Sent: Monday, September 27, 2010 5:28 AM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] ('a' == 'a') == true ? On 27 September 2010 11:54, Johan Brichau <johan@inceptive.be> wrote:
On 27 Sep 2010, at 10:38, Lukas Renggli wrote:
Am I wrong?
Yes, almost always one should probably use #= instead of #==.
I will add that to the exercise :-) The exercise actually makes students aware of the difference between strings and symbols (which should be pointer-equal)
I think you can avoid using 'equal' word when describing a #== comparison. It can be explained as 'test whether comparands are same object or not' while #= is test whether two objects equal or not. Also keep in mind that #== optimized by compiler. So , even if you override it in some class, it won't behave differently. And #=, of course, can be implemented in any way you like. One of interesting example: = anObject ^ false saying 'i am not equal to anything' :)
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- Best regards, Igor Stasenko AKA sig. _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Am 2010-09-27 um 10:32 schrieb Johan Brichau:
I convinced the teacher who will be taking over my Smalltalk courses at UCLouvain (starting this week) to use Pharo :-) One of the introductory exercises in these courses shows the difference between '==' and '='. However, in Pharo (&Squeak) the following goes wrong imho:
'a' == 'a' -> true $a asString == $a asString -> false
It seems that when you evaluate the expression, the (semantically identical) strings are represented as the same literal in the compiled block. For example, try to evaluate the following code by evaluating each statement in a separate doit. Then do it again as a single block...
|a b| a := 'a'. b := 'a'. a == b inspect
Do I make it an issue? Is there already an issue? (did not find one) Am I wrong?
I think this is a compiler optimization, as strings in general are immutable if created via literal notation (afaik). Remember that most operations on strings create copies of the original string. It gets even more interesting: Look at doit1.png I've referenced to 'abs' four times in the doit, nevertheless, there is only one literal stored. When i execute the second line, i operate with the #at:put: directly on that literal (doit2.png). hence, the method does not return 'abs' but 'ads' (as you can see by the 'stack top' in doit3.png) HTH, So Long, -Tobias
Perhaps interestingly, in the original Self paper promoting mirrors, it was argued that one of the lessons learned of using mirrors in self was that '==' is really a reflective property, that should be accessible only through mirrors. That is because, whether or not two pointers are equal is really a question on the VM level, and not on your business level. Niko On Mon, Sep 27, 2010 at 10:32 AM, Johan Brichau <johan@inceptive.be> wrote:
I convinced the teacher who will be taking over my Smalltalk courses at UCLouvain (starting this week) to use Pharo :-) One of the introductory exercises in these courses shows the difference between '==' and '='. However, in Pharo (&Squeak) the following goes wrong imho:
'a' == 'a' -> true $a asString == $a asString -> false
It seems that when you evaluate the expression, the (semantically identical) strings are represented as the same literal in the compiled block. For example, try to evaluate the following code by evaluating each statement in a separate doit. Then do it again as a single block...
|a b| a := 'a'. b := 'a'. a == b inspect
Do I make it an issue? Is there already an issue? (did not find one) Am I wrong?
Johan _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
-- http://scg.unibe.ch/staff/Schwarz twitter.com/nes1983 Tel: +41 076 235 8683
participants (14)
-
Alexandre Bergel -
Eliot Miranda -
George Herolyants -
Göran Krampe -
Henrik Sperre Johansen -
Igor Stasenko -
Johan Brichau -
Levente Uzonyi -
Lukas Renggli -
Nicolas Cellier -
Niko Schwarz -
Schwab,Wilhelm K -
Sean P. DeNigris -
Tobias Pape