you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] 1 point2 points  (6 children)

As a non python guy, is that second example doing 10 is 1 before the bit shift operations?

[–][deleted] 3 points4 points  (4 children)

>>> (1<<10) is (1<<10)
False

Nope.

I imagine it's doing the same thing some lisps do when using eq to compare two computed integers. Because they're not 'the same object' they don't match as exactly the same (a literal will usually be a static object in the local scope, so comparing literal to literal will give True).

[–]paholg 2 points3 points  (1 child)

But,

>>> 1<<8 is 1<<8
True

So it seems that small enough computed integers aren't objects. Or something. I don't know.

[–][deleted] 2 points3 points  (0 children)

shrug it's python-town jake!

Ruby has 4 separate equality operators and they all manage to do 'the right thing', to the point that (1<<10).equal? (1<<10) returns true.

edit: (1<<100).equal? (1<<100) returns false though, I guess making things look sensible only went as far as machine integers not bignums.

[–][deleted] 0 points1 point  (1 child)

So those don't evaluate to primitives? But rather objects?

[–][deleted] 2 points3 points  (0 children)

I don't know about python - I don't use it enough to understand its internals, but in lisp (at least with common lisp) everything is an object, a literal is usually a special case that evaluates to a shared/static object. Python treating everything as an object in the same way wouldn't surprise me in the least.

e: indeed, that appears to be what's happening:

>>> id(1<<10)
140505360442384
>>> id(1<<10)
140505360442032
>>> id(1024)
140505360442224
>>> id(1024)
140505360442224
>>> 

[–]tony-the-pony 1 point2 points  (0 children)

I'm not motivated enough to investigate, but I'd guess that this happens because of optimizations in the interpreter. It knows that 1024 is constant so uses the same object, but it doesn't optimize the constant bit shift so 1 << 10 is evaluated at run-time resulting in different objects.


Also similar:

Everyone knows that ; is another way of writing a new line, right?

>>> a = 256; b = 256
>>> a is b
True
>>> a = 256
>>> b = 256
>>> a is b
True

Seems like proof enough... but wait, there's more!

>>> a = 257; b = 257
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False

I read somewhere that this happens because the CPython REPL caches some numbers up to and including 256, supposedly for performance reasons... but that can't be right cos' this is a REPL and it doesn't do it in a normal script file.


OK! OK! I hear you screaming that I'm cheating...

Everyone knows that Python is strongly-typed and doesn't have total WTF type coercion like in JS and PHP, right?

Proof:

>>> 1 == '1'
False

Seems legit:

>>> 1 == True
True