This demonstrates the usual issue in almost all high-level languages: they do have constructs which seem like lower level, but these mechanisms are not reliable or predictable.
What's even stranger is the range of integers for which a is b: [-5 to +256] inclusive.
This demonstrates the usual issue in almost all high-level languages: they do have constructs which seem like lower level, but these mechanisms are not reliable or predictable.
No I think you've got that the wrong way around. The idea here is that it is exposing an interface that ought to be high level, but is actually low level and you have to understand the low level [implementation specific] behaviour to use it.
The high level idea is that an immutable entity, let's say the number 1, is always the same entity. So if you have two variables that refer to the entity that is what they do (in an abstract sense), they don't store values, they currently refer to the entity [and you're supposed to know nothing of the concrete implementation, of the idea of values being represented by bit patterns stored in words or bytes, or pointers to words or bytes storing bit patterns]. That's the high level abstraction that is being presented, an attempt to present things in their set-theoretic representation. If that's what one wants to do, fine do it. But don't have window dressing that says you're doing that and then in fact present a god awful mish-mash of an abstract model and physical implementation that can't be treated as the abstract model that you pretend you're presenting.
This demonstrates the usual issue in almost all high-level languages: they do have constructs which seem like lower level, but these mechanisms are not reliable or predictable.
No I think you've got that the wrong way around. The idea here is that it is exposing an interface that ought to be high level, but is actually low level and you have to understand the low level [implementation specific] behaviour to use it.
The high level idea is that an immutable entity, let's say the number 1, is always the same entity. So if you have two variables that refer to the entity that is what they do (in an abstract sense), they don't store values, they currently refer to the entity [and you're supposed to know nothing of the concrete implementation, of the idea of values being represented by bit patterns stored in words or bytes, or pointers to words or bytes storing bit patterns]. That's the high level abstraction that is being presented, an attempt to present things in their set-theoretic representation. If that's what one wants to do, fine do it. But don't have window dressing that says you're doing that and then in fact present a god awful mish-mash of an abstract model and physical implementation that can't be treated as the abstract model that you pretend you're presenting.It would probably be slower, and then you would bitch about that instead of this.
The high level idea is that an immutable entity, let's say the number 1, is always the same entity. So if you have two variables that refer to the entity that is what they do (in an abstract sense), they don't store values, they currently refer to the entity [and you're supposed to know nothing of the concrete implementation, of the idea of values being represented by bit patterns stored in words or bytes, or pointers to words or bytes storing bit patterns]. That's the high level abstraction that is being presented, an attempt to present things in their set-theoretic representation. If that's what one wants to do, fine do it. But don't have window dressing that says you're doing that and then in fact present a god awful mish-mash of an abstract model and physical implementation that can't be treated as the abstract model that you pretend you're presenting.
...
It would probably be slower, and then you would bitch about that instead of this.
Eh? What I, and RoGeorge, are bitching about ...
$ python3
Python 3.8.12 (default, Jan 2 2022, 01:12:07)
[Clang 11.0.1 (git@github.com:llvm/llvm-project.git llvmorg-11.0.1-0-g43ff75f2c on freebsd13
Type "help", "copyright", "credits" or "license" for more information.
>>> girl = "Dana"
>>> girl.strip("all clothes")
'Dan'
lambasting a detail that is not useful in practice
I thought about this and figured it might be a problem if you were collecting objects and wanted to remove duplicates.
What's even stranger is the range of integers for which a is b: [-5 to +256] inclusive.
I'm not going to scribble bit patterns and work out what is going on, but I will note that in Smalltalk implementations small integers are represented in a fashion that allows one to have a word hold a pointer to an Integer (which is a fully fledged object) or contain a restricted range of integers that don't occupy a full word. The bits 'stolen' to mark the type vary depending on platform and on some platforms (SPARC, SOAR) allow one to let the hardware sort out whether to call an object method or just do the arithmetic in the ALU (which understands tagged arithmetic). I'd guess it's some similar scheme that 'steals' a (few) bit(s) from a pointer as a type marker.
I thought about this and figured it might be a problem if you were collecting objects and wanted to remove duplicates.That's exactly how one would make sure in an unit test that a singleton object really is a singleton. I just don't see any use case wrt. immutable objects; for those, all uses I can think of, equivalence check (logical equality) works; remembering that Python is a language with automatic garbage collection.
I want this discussion to be clear about which complaints are personal, theoretical, or practical, because the distinction is useful to those who are deciding whether Python is a good fit for their particular use case.
[Also, please note that I am asking Cerebus, because I could be wrong here. It is always a possibility. And although I stated it as if a fact, it is only my understanding of the reason why it is so in Python right now, since it is how many if not most Python details get agreed upon; see PEPs.)
Python 2.7.17 (default, Dec 23 2019, 21:25:34)
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.16)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 is 1
True
>>> 1024 is 1024
True
>>> 1000000 is 1000000
True
>>> a = 1
>>> b = 1
>>> a is b
True
>>> a = 1000000
>>> b = 1000000
>>> a is b
False
>>> quit()
It's really really hard to imagine an implementation of tagged objects in which a range of -5..256 makes sense.
Philosophically, when you assign an integer to a variable in Python you bind the variable to the immutable integer object that has that particular value (obviously in implementation terms you just store an integer value somewhere) so two identical integers (identical values as we'd normally say if we were discussing, say, C) should return True for an is. In CPython* they don't, which is inconsistent.
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. (In a sense, and in conformance to Von Neumann’s model of a “stored program computer”, code is also represented by objects.)
Every object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity.
My take on it is simply one of disliking the inconsistent behaviour.
QuoteEvery object has an identity, a type and a value. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘is’ operator compares the identity of two objects; the id() function returns an integer representing its identity.
My problem is twofold, and is about this philosophy (or programming paradigm) you described. One, I cannot see any practical use for it, compared to say how Python documents its objects and their identity. Two, I do not see how you have determined that the philosophy applies to Python, because nothing in the official documentation I've seen event hints that way.
This I can fully appreciate; and I agree. It is annoying –– I would say even suspicious! –– that the documentation lies: that in fact, some immutable objects (integers between -5 and 256, inclusive, for Python 3.6.9 on x86-64 in Linux at least) do not actually have an unique identity when using CPython Python interpreter.
As a pure difference observed between official documentation and observable behaviour, like Siwastaja wrote in reply #400, this is illogical and unexpected. Like I said earlier, it seems obvious to me that this is only allowed (for those integer objects) because the developers believe nobody will notice it in practice. That kind of purely practical examination is how Python has evolved thus far.
... What other things might we have missed? Will they be gotchas with practical importance?...
I prefer the strongly typed languages.
At least then the compiler throws it out if I made a mistake.
Add 1 to 1 and getting 11 because the compiler thought the the types were a string and not numbers isnt good.
Oh how I hate this damn machine,
I wish that they would sell it!
It never does quite what I want,
but only what I tell it
As to what practical use that philosophy has? Well, it is what moulds the language. You must have encountered discussions that include a phrase like "What would be the most pythonic way to do it?". The very existence of the word is indicative that there is a philosophy of Python (that encompasses everything from the design of the language to coding styles), and if anything that the existence of a philosophy of Python is more important to some people than it is to aficionados of [most*] other programming languages because someone coined the word and it gained currency.
Or you can flip that on its head and say that if a new programming language doesn't have a philosophy then what is the point of having the new language? If it does all the same things, in the same ways, as existing programming languages, just with different syntax then it brings nothing new to the table.
Finally examining the philosophy (in the general sense) of the type systems of programming languages is in itself important in the same way that Russell examining the philosophy of mathematics was important. As you know, Russell discovered problems with, and solutions to the problems of, the very foundations of mathematics. Instinctively I feel we are in Russell territory here asking the question "In the light of these inconsistencies, is the Python type system well formed?" with, at least on my behalf, a sneaking suspicion that the answer might be "no" . Now, as I know I'm not in the least qualified to discuss Russell's logic that's where I'm going to leave it.
You're more than entitled to take that position. It's just for me that "purely practical" stepping around the issue feels rather like cleaning the floor by sweeping the dust up, and then putting it underneath the carpet. It will niggle and moreover it make me wonder "What other things might we have missed? Will they be gotchas with practical importance?". It's a bit like Gödel, Russell and the underpinnings of mathematics (perhaps with a little sprinkle of Turing), for all practical purposes it all worked before they got their hands on it, but now we how to make some bits work better, and perhaps most importantly, we now know where it can't work.
I can definitely appreciate that. To me, the situation is more like an earthen floor, sweeping of which for dust is impractical, and see concentrating on the larger debris and unwanted dirt more appropriate for now. I would love to have a proper floor (programming language with solid underpinnings), but I do not have the, uh, engineering experience in floors?, to construct one myself; so, I have resigned to work with what I have, and help develop better stuff in other, more limited scopes first. (Like embedded C patterns or a replacement for the C standard library. Or how to make web based services more secure by leveraging the Unix/POSIX kernel-provided privilege separation mechanisms (process user and groups) and so on, using Python (or any other scripting language) on the backend.)
(Apologies for stretching the analogy so far .)
Type - instead of + by accident, or > instead of >= and no compiler will help you.
if( foo /= bar) {
doSomething();
}
if( foo /= 0) {
doWeEvenGetHere();
}