Symbol equality method #= - weird condition in the Pharo sourcecode

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

Symbol equality method #= - weird condition in the Pharo sourcecode

Pharo Smalltalk Users mailing list
Hello, this is Symbol equality method in Pharo:

1: = aSymbol
2: "Compare the receiver and aSymbol."
3: self == aSymbol ifTrue: [^ true].
4: self class == aSymbol class ifTrue: [^ false].
5: "Use String comparison otherwise"
6: ^ super = aSymbol

Look at line 4 - what does it mean? That's wrong, isn't it?

Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.

If line 4 and further are correct, can someone explain a little?

Thanks! pf

Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Sven Van Caekenberghe-2


> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
>
>
> From: Petr Fischer <[hidden email]>
> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
> Date: 1 March 2019 at 17:08:03 GMT+1
> To: [hidden email]
>
>
> Hello, this is Symbol equality method in Pharo:
>
> 1: = aSymbol
> 2: "Compare the receiver and aSymbol."
> 3: self == aSymbol ifTrue: [^ true].
> 4: self class == aSymbol class ifTrue: [^ false].
> 5: "Use String comparison otherwise"
> 6: ^ super = aSymbol
>
> Look at line 4 - what does it mean? That's wrong, isn't it?
>
> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
>
> If line 4 and further are correct, can someone explain a little?
>
> Thanks! pf

Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.

Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.

The super call in line 6 is what allows Symbols and String to be compared.

I would say line 4 is a kind of sanity check, but probably not needed.



Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - issue submitted

Pharo Smalltalk Users mailing list
Issue submitted:
https://github.com/pharo-project/pharo/issues/2744

pf

> > On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
> >
> >
> > From: Petr Fischer <[hidden email]>
> > Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
> > Date: 1 March 2019 at 17:08:03 GMT+1
> > To: [hidden email]
> >
> >
> > Hello, this is Symbol equality method in Pharo:
> >
> > 1: = aSymbol
> > 2: "Compare the receiver and aSymbol."
> > 3: self == aSymbol ifTrue: [^ true].
> > 4: self class == aSymbol class ifTrue: [^ false].
> > 5: "Use String comparison otherwise"
> > 6: ^ super = aSymbol
> >
> > Look at line 4 - what does it mean? That's wrong, isn't it?
> >
> > Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
> >
> > If line 4 and further are correct, can someone explain a little?
> >
> > Thanks! pf
>
> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
>
> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>
> The super call in line 6 is what allows Symbols and String to be compared.
>
> I would say line 4 is a kind of sanity check, but probably not needed.
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

David T. Lewis
In reply to this post by Sven Van Caekenberghe-2
On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:

>
>
> > On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
> >
> >
> > From: Petr Fischer <[hidden email]>
> > Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
> > Date: 1 March 2019 at 17:08:03 GMT+1
> > To: [hidden email]
> >
> >
> > Hello, this is Symbol equality method in Pharo:
> >
> > 1: = aSymbol
> > 2: "Compare the receiver and aSymbol."
> > 3: self == aSymbol ifTrue: [^ true].
> > 4: self class == aSymbol class ifTrue: [^ false].
> > 5: "Use String comparison otherwise"
> > 6: ^ super = aSymbol
> >
> > Look at line 4 - what does it mean? That's wrong, isn't it?
> >
> > Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
> >
> > If line 4 and further are correct, can someone explain a little?
> >
> > Thanks! pf
>
> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.

It is wrong in a Spur image, because we now have subclasses of Symbol.
But removing line 4 is not the right solution. See Nicolas' implementation
in Squeak:

Symbol>>= aSymbol
        "Compare the receiver and aSymbol."
        self == aSymbol ifTrue: [^ true].
        aSymbol isSymbol ifTrue: [^ false].
        "Use String comparison otherwise"
        ^ super = aSymbol

Dave

>
> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>
> The super call in line 6 is what allows Symbols and String to be compared.
>
> I would say line 4 is a kind of sanity check, but probably not needed.
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Sven Van Caekenberghe-2
Why ? Please explain ...

> On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:
>
> On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:
>>
>>
>>> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
>>>
>>>
>>> From: Petr Fischer <[hidden email]>
>>> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
>>> Date: 1 March 2019 at 17:08:03 GMT+1
>>> To: [hidden email]
>>>
>>>
>>> Hello, this is Symbol equality method in Pharo:
>>>
>>> 1: = aSymbol
>>> 2: "Compare the receiver and aSymbol."
>>> 3: self == aSymbol ifTrue: [^ true].
>>> 4: self class == aSymbol class ifTrue: [^ false].
>>> 5: "Use String comparison otherwise"
>>> 6: ^ super = aSymbol
>>>
>>> Look at line 4 - what does it mean? That's wrong, isn't it?
>>>
>>> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
>>>
>>> If line 4 and further are correct, can someone explain a little?
>>>
>>> Thanks! pf
>>
>> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
>
> It is wrong in a Spur image, because we now have subclasses of Symbol.
> But removing line 4 is not the right solution. See Nicolas' implementation
> in Squeak:
>
> Symbol>>= aSymbol
> "Compare the receiver and aSymbol."
> self == aSymbol ifTrue: [^ true].
> aSymbol isSymbol ifTrue: [^ false].
> "Use String comparison otherwise"
> ^ super = aSymbol
>
> Dave
>
>>
>> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>>
>> The super call in line 6 is what allows Symbols and String to be compared.
>>
>> I would say line 4 is a kind of sanity check, but probably not needed.


Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Steffen Märcker
Is it consistent with the definition of #= in String such that
'aSymbol = aString' iff 'aString = aSymbol'?
Sorry, I don't have an image at hand.


Am 1. März 2019 18:40:11 MEZ schrieb Sven Van Caekenberghe <[hidden email]>:
Why ? Please explain ...

On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:

On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:


On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:


From: Petr Fischer <[hidden email]>
Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
Date: 1 March 2019 at 17:08:03 GMT+1
To: [hidden email]


Hello, this is Symbol equality method in Pharo:

1: = aSymbol
2: "Compare the receiver and aSymbol."
3: self == aSymbol ifTrue: [^ true].
4: self class == aSymbol class ifTrue: [^ false].
5: "Use String comparison otherwise"
6: ^ super = aSymbol

Look at line 4 - what does it mean? That's wrong, isn't it?

Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.

If line 4 and further are correct, can someone explain a little?

Thanks! pf

Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.

It is wrong in a Spur image, because we now have subclasses of Symbol.
But removing line 4 is not the right solution. See Nicolas' implementation
in Squeak:

Symbol>>= aSymbol
"Compare the receiver and aSymbol."
self == aSymbol ifTrue: [^ true].
aSymbol isSymbol ifTrue: [^ false].
"Use String comparison otherwise"
^ super = aSymbol

Dave


Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.

The super call in line 6 is what allows Symbols and String to be compared.

I would say line 4 is a kind of sanity check, but probably not needed.


Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Sven Van Caekenberghe-2
In reply to this post by Sven Van Caekenberghe-2
Ah, it is an optimisation: if the first #== fails, but the argument is also a Symbol, then that means the are different for sure, so false is returned early, instead of failing in super's #= after that.

And with ByteSymbol and WideSymbol, although they are exclusive (can never be equal), they can be different and if they are both Symbols, then you can return early (not just when their classes differ).

> On 1 Mar 2019, at 18:40, Sven Van Caekenberghe <[hidden email]> wrote:
>
> Why ? Please explain ...
>
>> On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:
>>
>> On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:
>>>
>>>
>>>> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
>>>>
>>>>
>>>> From: Petr Fischer <[hidden email]>
>>>> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
>>>> Date: 1 March 2019 at 17:08:03 GMT+1
>>>> To: [hidden email]
>>>>
>>>>
>>>> Hello, this is Symbol equality method in Pharo:
>>>>
>>>> 1: = aSymbol
>>>> 2: "Compare the receiver and aSymbol."
>>>> 3: self == aSymbol ifTrue: [^ true].
>>>> 4: self class == aSymbol class ifTrue: [^ false].
>>>> 5: "Use String comparison otherwise"
>>>> 6: ^ super = aSymbol
>>>>
>>>> Look at line 4 - what does it mean? That's wrong, isn't it?
>>>>
>>>> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
>>>>
>>>> If line 4 and further are correct, can someone explain a little?
>>>>
>>>> Thanks! pf
>>>
>>> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
>>
>> It is wrong in a Spur image, because we now have subclasses of Symbol.
>> But removing line 4 is not the right solution. See Nicolas' implementation
>> in Squeak:
>>
>> Symbol>>= aSymbol
>> "Compare the receiver and aSymbol."
>> self == aSymbol ifTrue: [^ true].
>> aSymbol isSymbol ifTrue: [^ false].
>> "Use String comparison otherwise"
>> ^ super = aSymbol
>>
>> Dave
>>
>>>
>>> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>>>
>>> The super call in line 6 is what allows Symbols and String to be compared.
>>>
>>> I would say line 4 is a kind of sanity check, but probably not needed.
>


Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Richard Sargent
Administrator
On Fri, Mar 1, 2019 at 12:02 PM Sven Van Caekenberghe <[hidden email]> wrote:
Ah, it is an optimisation: if the first #== fails, but the argument is also a Symbol, then that means the are different for sure, so false is returned early, instead of failing in super's #= after that.

And with ByteSymbol and WideSymbol, although they are exclusive (can never be equal), they can be different and if they are both Symbols, then you can return early (not just when their classes differ).


Thanks for explaining that!

As an aside, this is the kind of information that should be in a method's comment. Rationale and explanation, rather than what it does.



> On 1 Mar 2019, at 18:40, Sven Van Caekenberghe <[hidden email]> wrote:
>
> Why ? Please explain ...
>
>> On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:
>>
>> On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:
>>>
>>>
>>>> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
>>>>
>>>>
>>>> From: Petr Fischer <[hidden email]>
>>>> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
>>>> Date: 1 March 2019 at 17:08:03 GMT+1
>>>> To: [hidden email]
>>>>
>>>>
>>>> Hello, this is Symbol equality method in Pharo:
>>>>
>>>> 1: = aSymbol
>>>> 2: "Compare the receiver and aSymbol."
>>>> 3: self == aSymbol ifTrue: [^ true].
>>>> 4: self class == aSymbol class ifTrue: [^ false].
>>>> 5: "Use String comparison otherwise"
>>>> 6: ^ super = aSymbol
>>>>
>>>> Look at line 4 - what does it mean? That's wrong, isn't it?
>>>>
>>>> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
>>>>
>>>> If line 4 and further are correct, can someone explain a little?
>>>>
>>>> Thanks! pf
>>>
>>> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
>>
>> It is wrong in a Spur image, because we now have subclasses of Symbol.
>> But removing line 4 is not the right solution. See Nicolas' implementation
>> in Squeak:
>>
>> Symbol>>= aSymbol
>>      "Compare the receiver and aSymbol."
>>      self == aSymbol ifTrue: [^ true].
>>      aSymbol isSymbol ifTrue: [^ false].
>>      "Use String comparison otherwise"
>>      ^ super = aSymbol
>>
>> Dave
>>
>>>
>>> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>>>
>>> The super call in line 6 is what allows Symbols and String to be compared.
>>>
>>> I would say line 4 is a kind of sanity check, but probably not needed.
>


Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Sean P. DeNigris
Administrator
Richard Sargent wrote
> As an aside, this is the kind of information that should be in a method's
> comment. Rationale and explanation, rather than what it does.

Yes!!!



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

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

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Richard O'Keefe
In reply to this post by Sven Van Caekenberghe-2
Surely a Symbol should never be #= to anything that is not
a Symbol?  At least in VW, GST, Dolphin, and VAST,
#a = 'a'
'a' = #a
both answer false, and I'd be rather upset if a symbol
ever compared equal to a string.  The ANSI Smalltalk standard
says in several places that "Symbol objects are identity
objects", which is defined as "An object defined such that
a=b implies a==b".

So the definition I am expecting to see is

Symbol>>
= other
  ^self == other

Anything else is inconsistent with the standard and common
practice.  Symbol hash and = are supposed to be fast all the
or what's the point?

On Sat, 2 Mar 2019 at 09:02, Sven Van Caekenberghe <[hidden email]> wrote:
Ah, it is an optimisation: if the first #== fails, but the argument is also a Symbol, then that means the are different for sure, so false is returned early, instead of failing in super's #= after that.

And with ByteSymbol and WideSymbol, although they are exclusive (can never be equal), they can be different and if they are both Symbols, then you can return early (not just when their classes differ).

> On 1 Mar 2019, at 18:40, Sven Van Caekenberghe <[hidden email]> wrote:
>
> Why ? Please explain ...
>
>> On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:
>>
>> On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:
>>>
>>>
>>>> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
>>>>
>>>>
>>>> From: Petr Fischer <[hidden email]>
>>>> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
>>>> Date: 1 March 2019 at 17:08:03 GMT+1
>>>> To: [hidden email]
>>>>
>>>>
>>>> Hello, this is Symbol equality method in Pharo:
>>>>
>>>> 1: = aSymbol
>>>> 2: "Compare the receiver and aSymbol."
>>>> 3: self == aSymbol ifTrue: [^ true].
>>>> 4: self class == aSymbol class ifTrue: [^ false].
>>>> 5: "Use String comparison otherwise"
>>>> 6: ^ super = aSymbol
>>>>
>>>> Look at line 4 - what does it mean? That's wrong, isn't it?
>>>>
>>>> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
>>>>
>>>> If line 4 and further are correct, can someone explain a little?
>>>>
>>>> Thanks! pf
>>>
>>> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
>>
>> It is wrong in a Spur image, because we now have subclasses of Symbol.
>> But removing line 4 is not the right solution. See Nicolas' implementation
>> in Squeak:
>>
>> Symbol>>= aSymbol
>>      "Compare the receiver and aSymbol."
>>      self == aSymbol ifTrue: [^ true].
>>      aSymbol isSymbol ifTrue: [^ false].
>>      "Use String comparison otherwise"
>>      ^ super = aSymbol
>>
>> Dave
>>
>>>
>>> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
>>>
>>> The super call in line 6 is what allows Symbols and String to be compared.
>>>
>>> I would say line 4 is a kind of sanity check, but probably not needed.
>


Reply | Threaded
Open this post in threaded view
|

Re: Symbol equality method #= - weird condition in the Pharo sourcecode

Sven Van Caekenberghe-2


> On 6 Mar 2019, at 15:15, Richard O'Keefe <[hidden email]> wrote:
>
> Surely a Symbol should never be #= to anything that is not
> a Symbol?  At least in VW, GST, Dolphin, and VAST,
> #a = 'a'
> 'a' = #a
> both answer false, and I'd be rather upset if a symbol
> ever compared equal to a string.  The ANSI Smalltalk standard
> says in several places that "Symbol objects are identity
> objects", which is defined as "An object defined such that
> a=b implies a==b".
>
> So the definition I am expecting to see is
>
> Symbol>>
> = other
>   ^self == other
>
> Anything else is inconsistent with the standard and common
> practice.  Symbol hash and = are supposed to be fast all the
> or what's the point?

Because it is very convenient. It has also been like this in Pharo (and Squeak) for a long time. With the correct implementation, #= and #~= are just as fast when both arguments are Symbols. (We need a little fix there, as recently uncovered).

We do not feel bound to the ANSI standard (we won't break it just for fun, it is a guide, but it can't stop us evolving).

There are many points of view in the world, yours might be different than mine.

> On Sat, 2 Mar 2019 at 09:02, Sven Van Caekenberghe <[hidden email]> wrote:
> Ah, it is an optimisation: if the first #== fails, but the argument is also a Symbol, then that means the are different for sure, so false is returned early, instead of failing in super's #= after that.
>
> And with ByteSymbol and WideSymbol, although they are exclusive (can never be equal), they can be different and if they are both Symbols, then you can return early (not just when their classes differ).
>
> > On 1 Mar 2019, at 18:40, Sven Van Caekenberghe <[hidden email]> wrote:
> >
> > Why ? Please explain ...
> >
> >> On 1 Mar 2019, at 18:02, David T. Lewis <[hidden email]> wrote:
> >>
> >> On Fri, Mar 01, 2019 at 05:18:27PM +0100, Sven Van Caekenberghe wrote:
> >>>
> >>>
> >>>> On 1 Mar 2019, at 17:08, Petr Fischer via Pharo-users <[hidden email]> wrote:
> >>>>
> >>>>
> >>>> From: Petr Fischer <[hidden email]>
> >>>> Subject: Symbol equality method #= - weird condition in the Pharo sourcecode
> >>>> Date: 1 March 2019 at 17:08:03 GMT+1
> >>>> To: [hidden email]
> >>>>
> >>>>
> >>>> Hello, this is Symbol equality method in Pharo:
> >>>>
> >>>> 1: = aSymbol
> >>>> 2: "Compare the receiver and aSymbol."
> >>>> 3: self == aSymbol ifTrue: [^ true].
> >>>> 4: self class == aSymbol class ifTrue: [^ false].
> >>>> 5: "Use String comparison otherwise"
> >>>> 6: ^ super = aSymbol
> >>>>
> >>>> Look at line 4 - what does it mean? That's wrong, isn't it?
> >>>>
> >>>> Typically, every symbol comparisons end up in line 3, but if you do some work with forward proxies for example, condition on line 3 is "false" and then weird things on line 4 happens.
> >>>>
> >>>> If line 4 and further are correct, can someone explain a little?
> >>>>
> >>>> Thanks! pf
> >>>
> >>> Yes, that looks weird. Line 4 should probably be removed, unless I am missing something.
> >>
> >> It is wrong in a Spur image, because we now have subclasses of Symbol.
> >> But removing line 4 is not the right solution. See Nicolas' implementation
> >> in Squeak:
> >>
> >> Symbol>>= aSymbol
> >>      "Compare the receiver and aSymbol."
> >>      self == aSymbol ifTrue: [^ true].
> >>      aSymbol isSymbol ifTrue: [^ false].
> >>      "Use String comparison otherwise"
> >>      ^ super = aSymbol
> >>
> >> Dave
> >>
> >>>
> >>> Symbols are by definition always #== so in that sense, #= should not even be implemented (as #= on Object is defined as #==), but since its direct super class String already overwrote #=, it has to follow.
> >>>
> >>> The super call in line 6 is what allows Symbols and String to be compared.
> >>>
> >>> I would say line 4 is a kind of sanity check, but probably not needed.
> >
>
>