What functionality does such a thing actually need?
I think the requirements should be: * The resulting symbol behave exactly like None. IE: the symbol should not be an instance of object, but an instance of its own class * A symbol can optionally be globally unique. * Two symbols created by the same key must not be equal. IE: they have equal key, but different value * if we're trying to create global symbols with the same key, an exception is thrown This is mostly based on the Javascript spec.
On Thu, Jul 5, 2018 at 1:25 PM, Flavio Curella <flavio.curella@gmail.com> wrote:
What functionality does such a thing actually need?
I think the requirements should be: * The resulting symbol behave exactly like None. IE: the symbol should not be an instance of object, but an instance of its own class * A symbol can optionally be globally unique. * Two symbols created by the same key must not be equal. IE: they have equal key, but different value * if we're trying to create global symbols with the same key, an exception is thrown
This is mostly based on the Javascript spec.
I think the name "symbol" here is pretty confusing. It comes originally from Lisp, where it's used to refer to an interned-string data type. It's a common source of confusion even there. Then it sounds like JS took that name, and it ended up drifting to mean something that's almost exactly the opposite of a Lisp symbol. In Lisp, symbols are always "global"; the whole point is that if two different pieces of code use the same name for the same symbol then they end up with the same object. So this is *super* confusing. I think I see how JS ended up here [1], but the rationale really doesn't translate to other languages. The thing you're talking about is what Python devs call a "sentinel" object. If your proposal is to add a sentinel type to the stdlib, then your chance of success will be *much* higher if you use the word "sentinel" instead of "symbol". People don't read mailing list threads carefully, so if you keep calling it "symbol" then you'll likely spend infinite time responding to people rushing in to critique your proposal based on some misconception about what you're trying to do, which is no fun at all. Honestly I'd probably start a new thread with a new subject, ideally with an initial straw-man proposal for the semantics of these objects. -n [1] What was JS thinking? Well, I'm not sure I have all the details right, but AFAICT it's all very logical... JS objects, like Python objects, have attributes, e.g. 'console.log' is the 'log' attribute of the 'console' object. There's a table inside the 'console' object mapping keys like 'log' to their corresponding values, much like a Python object's __dict__. But a Python dict can use arbitrary objects as keys. JS attribute tables are different: the keys are required to be Lisp-style symbol objects: they're arbitrary strings (and only strings), that are then interned for speed. This kind of table lookup is exactly why Lisp invented symbols in the first place; a Lisp scope is also a table mapping symbols to values. BUT THEN, they decided to enhance JS to add the equivalent of special methods like Python's __add__. Now how do you tell which attributes are ordinary attributes, and which ones are supposed to be special? In Python of course we use a naming convention, which is simple and works well. But in JS, by the time they decided to do this, it was too late: people might already be using names like "__add__" for regular attributes, and making them special would break compatibility. In fact, *all* possible strings were potentially already in use for ordinary attributes; there were no names left for special attributes. SO, they decided, they needed to expand the set of symbol objects (i.e., attribute names) to include new values that were different from all possible strings. So now the JS Symbol class is effectively the union of {strings, compared as values} + {sentinels, compared by identity}. And for string attributes, you can mostly ignore all this and pretend they're ordinary strings and the JS interpreter will paper over the details. So the main kind of symbol that JS devs actually have to *know* about is the new sentinel values. And that's how the name "symbol" flipped to mean the opposite of what it used to. See? I told you it was all very logical. -- Nathaniel J. Smith -- https://vorpus.org
On Thu, Jul 05, 2018 at 05:26:36PM -0700, Nathaniel Smith wrote:
I think the name "symbol" here is pretty confusing. It comes originally from Lisp, where it's used to refer to an interned-string data type.
Even if Lisp was the first programming language to use the term for a data type (which seems likely), that doesn't give Lisp ownership of the concept. A number of languages have a Symbol data type, without needing to ape Lisp semantics or implementation. https://en.wikipedia.org/wiki/Symbol_%28programming%29 See for example: https://planspace.org/20141129-ruby_symbols_are_not_lisp_symbols/ Since "symbol" is a plain English word that doesn't necessarily have anything to do with Lisp, we're free to use it provided we determine what it will mean in Python. That may not be identical to Lisp's semantics, or Javascript semantics, or Ruby semantics. But that's okay, they're semantics aren't identical with each other either.
It's a common source of confusion even there. Then it sounds like JS took that name, and it ended up drifting to mean something that's almost exactly the opposite of a Lisp symbol. In Lisp, symbols are always "global";
I don't think that's right, at least not in Common Lisp. Symbols may or may not be accessible from a particular namespace: http://www.lispworks.com/documentation/HyperSpec/Body/t_symbol.htm#symbol In Ruby, symbols are global, the opposite of Lisp symbols: http://chneukirchen.org/blog/archive/2005/12/ruby-symbols-are-not-lisp-symbo...
the whole point is that if two different pieces of code use the same name for the same symbol then they end up with the same object. So this is *super* confusing.
Well, it's certainly super confusing to me *wink* since I'm not sure whether your "whole point" comment is referring to how symbols work in Javascript, Lisp, how you think they ought to work, or something else, or who "this" is super confusing to. (Javascript programmers? Lisp programmers? You?) [...]
The thing you're talking about is what Python devs call a "sentinel" object.
"Sentinel" describes the *purpose* of the object, not the "kind of thing" it is. It is a special value used to indicate the end of data. https://en.wikipedia.org/wiki/Sentinel_value By extension, any placeholder value indicating missing data can be called a sentinel: def function(value=None): Here, None is being used as a sentinel in the second sense.
If your proposal is to add a sentinel type to the stdlib, then your chance of success will be *much* higher if you use the word "sentinel" instead of "symbol".
Oh I really, really hope not. Symbols aren't merely sentinels. They're also a kind of enumerated value: C enums are a kind of symbol. None and NotImplemented and Ellipsis are kinds of symbols. Symbols can be used for all sorts of reasons, not just as a sentinel. For example, NotImplemented is returned by operator dunder methods to indicate "give the other operand a chance to respond". None is not a sentinel, but it can be used as a sentinel. But for that matter, so could -1 or "Aardvark" be used as sentinels, under the right circumstances. Arguably, True and False could be considered symbols. Sometimes I need a three-state flag, and I often use True, False and None, but often what I really want is True, False and Maybe. Or True, False, Mu. https://en.wikipedia.org/wiki/Mu_(negative)#In_popular_culture If we had Symbols first, we possibly wouldn't need enum.Enum; arguably, since we do have enum.Enum, perhaps we don't need Symbols. Or maybe there's still use for them both -- any potential PEP would have to sort out that question.
People don't read mailing list threads carefully, so if you keep calling it "symbol" then you'll likely spend infinite time responding to people rushing in to critique your proposal based on some misconception about what you're trying to do, which is no fun at all.
As opposed to them critiquing the proposal based on the misuse of the term "sentinel" for something which isn't (just) used as a sentinel. -- Steve
participants (3)
-
Flavio Curella
-
Nathaniel Smith
-
Steven D'Aprano