-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Should we rename Void and Bottom? #186
Comments
What about Anything/Nothing? (Scala has Any/Nothing.) I also like Top/Bottom. |
This is subjective by nature, so: To me (i.e. with some C(++) background) void mainly means "comes with no assumptions about the actual type". Of course, the concept's beatuy dies with the pointers you don't have in Java/Ceylon. So I concur that Void is a bit misplaced, even though it is to me because Top/Bottom is nice for thinking in trees. Less so if you include interfaces in your topology ;( Anything/Everything comes to mind, but is probably a bit off for c eyes. Why Bottom could be SubType or NonValue or Undefined is beyone me. I guess I hate it. I could think of |
Unknown/Impossible sounds good to me. Unknown invokes memories of COM's IUnknown, the superinterface of IDispatch (which was mapped to Object in Visual Basic). |
@durban But I suppose we could potentially use |
I vote for! |
@gavinking Well, if I understand correctly this: http://www.scala-lang.org/api/current/index.html, then Scala actually has a type called "Null" (null is an instance of this), and has a type called "Nothing", which is indeed Bottom (the empty type, i.e., it has no instances, and it is a subtype of every type). So yes, I think it would be good to rename the current "Nothing" to "Null", and use Anything / Nothing as top/bottom as you said. I mostly like this version, because then if I have something which has the type "Nothing", then I know, that "it can be nothing" (because Nothing has no instances). Similarly with Anything: "it can be anything" (because everything is an instance of Anything). (I'm not a native speaker though, so I may be mistaken.) |
Definitely seems the best option so far. Nicely symmetric names and |
Ah, OK, well, yeah, Scala's
So just be a little bit careful about mapping concepts back and forth between Ceylon and Scala, because they are not precisely the same. |
I like Anything/Nothing and using Null as the type of null. It makes the type system look more regular. |
This change would be acceptable to me. |
+1 |
-1 on the Anything/Nothing. I prefer Anything/Everything, or Anything/All, or Any/All. An instance of SomeType<All> is assignable to SomeType<out T> for any T. SomeType<Nothing> does not make the correct implication in the above case. Without deeper reasoning by the user, it seems to imply that it can't instantiated. An example use case is if an empty collection is modeled with a Nil satisfies Collection<All>. This specific use example may not apply to the eventual standard collection library, since Ceylon has first class treatment of null with an intersection type. Nevertheless, there may be other use cases. Also in my mind, Nothing is not the symmetric meaning to Anything. For me, it is intuitive that All or Everything can't be instantiated, because the set of types of a program is open due to subtyping. |
"Without deeper reasoning by the user, it seems to imply that it can't instantiated" well as far as I understand things that's exactly what it means. That's why one of the alternative suggestions was |
But my point is that SomeType<Impossible> can be instantiated. The user has to reason out that while Impossible can't be instantiated, given the covariant parameter of SomeType, the former can be instantiated (the type parameter will never be allowed in the method input position). Whereas, in my mind, it is obvious that type All or Everything, can't be instantiated, because there is no value that is all types of the program. And then there is not the implication that SomeType<All> can't be instantiated. But the more I think about it, I don't like All and Everything, because the bottom type is not the supertype of all types. And it is not just Nothing or Impossible either. It is the subtype of all types. It is something and it is possible to use it for the type of a value, as per the example above. The most accurate I can think of which is perhaps more intuitive than Top/Bottom is AnySub/AllSuper or AnySubtype/AllSupertypes. Since Ceylon favors verbosity for clarity, perhaps my suggestion is AnySubtype/AllSupertypes. |
It cannot be instantiated, no value will ever exist of the type |
Please correct me, but I think it can be instantiated. http://en.wikipedia.org/wiki/Bottom_type#Computer_science_applications "3. List[Bot] is a natural type for the "null pointer" value (a pointer which does not point to any object) of languages like Java: in Java, the null type is the universal subtype of reference types. null is the only value of the null type; and it can be cast to any reference type.[3] However, the null type does not satisfy all the properties of a bottom type as described above, because bottom types cannot have any possible values, and the null type has the value null." You can work it out by studying the Scala use cases. Scala instantiates "object Nil extends List[Nothing]" and "object None extends Option[Nothing]": http://www.codecommit.com/blog/ruby/monads-are-not-metaphors Tangentially, that Wikipedia link says that Void is not the top type, and instead the unit type. I am not sure what corner cases that might introduce since Ceylon is conflating the top and void types. I saw that Ceylon wants to be able to assign any function that returns any type, to a type that is a function that returns Void. |
I'd say this says it all: "However, the null type does not satisfy all the properties of a bottom type as described above, because bottom types cannot have any possible values, and the null type has the value null". Our bottom type is a "real" bottom type and has no possible values. |
Apparently you are equating the instantiation of the bottom type with the instantiation of a type where the bottom type is a covariant parameter (which is exactly the misunderstanding I am trying to avoid, by suggesting using AllSupertypes instead of Nothing or Impossible). The latter is instantiable, the former is not. The Scala type Nothing is not instantiable, and is the "real" bottom type too. The Scala type Option[Nothing] is instantiable (and is not a bottom type, so agrees with your Wikipedia quote). The Null type is distinct from Nothing in Scala too. The requirements of a covariant type parameter enable that. What you are forgetting is that the bottom type is populated with every supertype in the program (which is why Nothing and Impossible are not truthful names). This means it can be instantiated where it is used as covariant type parameter. P.S. In Ceylon, currently Nothing corresponds to Scala's Null type and Bottom to Scala's Nothing type. What I said for Scala, applies the same to Ceylon. |
I don't see how |
It can do something, e.g. the instance of Note that in Ceylon, one could mark the end of the list with Whereas, assigning a If I am not mistaken, there is a key type theory insight. In the domain of values, the bottom type is an empty set, but in the domain of types, it is definitely not an empty set, because it is populated by every supertype (every type other than bottom) in the program. That is fundamental reason that Any way, in the end perhaps it is just a matter of user taste on the name choice (although in any case, I am thinking the spec needs to corrected on the empty set domain point). I dunno. |
Well the matter of taste is an important one in this case, because the current name is maybe to most semantically correct but we're looking at alternative names exactly because of the reason that we think it will be hard to explain to "The Average Java Enterprise Developer" what things like |
Yeah I leave the interpretation of user pyschology to the major stake holders in Ceylon. ;) Thanks for taking the time to help me explain my point on the issue deeply. Also hope someone looks at the point I made about Void should be distinct from the top type. |
If I am correct that the bottom type is populated as the subtype of all types other than itself (i.e. not the empty set in the type domain), then another suggestion is:
Maybe that makes it more clear that the bottom type is not populated with values, but is populated with all types. So if user thinks about instantiating an AllTypes, they will realize there is no single type that will suffice. When I first saw The But I see that if not confused to be More descriptive:
|
Probably it is completely nuts, but have you considered promoting E.g. |
Hey, let's call the bottom type either |
So, if the bottom type is
|
Aren't you conflating unit (i.e. http://en.wikipedia.org/wiki/Unit_type I also made an argument for equating unit and bottom, and was not well received: http://stackoverflow.com/questions/19132/expression-versus-statement/8450398#8450398 You've given me an idea. Perhaps I like the name |
The bottom type has no values, but is populated as the subtype of all types. The unit type has only one value, thus contains no compile-time information. Runtime exceptions can't be checked at compile-time, as that defeats the point of having them (as Java painfully discovered). Even functions that return a value and have exceptions, really return the union containing the unit type. I read that unit is necessary to express some generic relationships, where bottom won't work. Bottom type can only be used where it doesn't instantiate a value, so afaik this is some exceptional case, because it can be populated by all types in the contravariant direction. So if you really don't want the user to think hard about what bottom really means, perhaps |
I don't think so, no. Ceylon doesn't use a unit type to represent the type of a |
I remember that Afaics, this is a type hole because one can assume they are calling a function that has side-effects ( Afaics, the underlying dilemma is due to mixing pure functions with impure functions. Pure functions can never be The bottom type is the type of any function that does not return, e.g.
I can't think of a name other than So I guess I would choose |
Well, but on the other hand we have |
I agree.
I can't bring myself to take |
We can perhaps express categorical duals in english using the word "not". Top and bottom are categorical duals, given their simple definitions:
So I have a fresh idea, to get us away from the many problems of
This is not the same as saying I don't agree with @RossTate that For me, For me, I preferred I agree that This leads to another idea:
Hmmm. Brainstorming continues... |
Given a I still prefer
As I said, we are not brainstorming anymore. We could keep coming up with new possibilities forever, but we've done that for long enough. We are now trying to eliminate/narrow options so that we can come to a decision. |
Also why was
Negatives:
|
Or:
None of your available choices are perfect, so might as well choose the most concise, symmetrical, and stay consistent with Scala (at least on bottom). One argument that can be made against the ambiguity of I want to see how it works out for a mainstream targeted language :) If I were creating a language for the mainstream, I would instead choose concise type theoretically correct names (e.g. |
In the Curry-Howard correspondence, logical falsity (falsum or contradiction) is equivalent to the Bottom type. http://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspondence#General_formulation A function that returns the bottom type
Bottom is |
I want to end by moving my feedback objectively towards your consensus as much as I can, without being dishonest with myself. When we can't describe exactly what something is with a noun, but we can describe what a coinductive type[1] can't do exactly with a verb, then perhaps we should choose the verb. Afaics, there exists only one noun for Bottom that fully completes the is-a relationship, but people don't understand well the meaning of the entire The noun Thus if Thus I change my vote from As for Top, I don't understand why you want to copy Scala's emphasis on using the top type to hold instances, as it throws away type information at compile-time and opens the run-time to use of default cases (downcasting) and thus run-time exceptions. It is essentially dynamic typing (a/k/a unityping). Scala has to do this because it doesn't have a first-class intersection type, but Ceylon has one. And Scala does implicit subsumption (automatically casting to top), but afaik Ceylon does not. But any way, I can tolerate well any of those 3 choices for top, as well [1] A inductive type such as the integers is expressed by a known initial point, e.g. 0 and a succeeding function to get the next values. A coinductive type such as a stream or bottom, is where the succeeding function that expresses the type is expressed towards the final point, but we never get there. The succeeding function for bottom is the disjunction, as we add another type to the universe. It is difficult to describe the succeeding function of a coinductive type as noun. |
Correction: bottom does not have one instance which is the empty set, but bottom's type is also more than the empty set (so my argument against https://groups.google.com/d/msg/scala-debate/vysv97J0xok/KE5_ZpH5EX0J |
So here's my take on all this:
Therefore, I'm inclined to stick with the much earlier proposal:
To be truthful, I can think of some much better names for |
Gavin wrote:
Gavin I am sorry to inform you that the bottom type is never used to represent its non-existent value. So naming it based on its value is going to lead to incorrect semantics. Here is the hard proof: https://groups.google.com/d/msg/scala-debate/vysv97J0xok/bIy1VbYIagoJ After 129 messages in that thread, I think that is pretty well vetted now with some very strong programmers there. Notice they all went silent after the revelation in the link above. Bottom is always used as either the input or output type of a function (that can't be called or returns the universe of exceptions), or as a type parameter that has semantics that doesn't have anything to do with the type of a non-existent value (see the proof at the link above). If you are determined to find an "intuitive" name for bottom, which is not too much incorrect from its use cases (which are always contravariant semantics!), and if you are going to choose
Accepted english definitions do allow that a "nothing" is an "anything". Nonsense! List of elements of type "Nothing", again nonsensical. I know you want to say "List of Nothing" in your mind, but that is not how type parameters work. Do we want to create this false semantics that type parameters can not do.
Anyway, my 2 cents...good luck with your choice. |
@shelby3 You're overthinking this. We have a type with no values. If asked to describe a value of this type, "nothing" is as good a description as you're going to find. Consider the following common English usage:
The question asks for a description of an element of the empty set. I don't think anyone would find the response "nothing" unnatural. Now, the empty set is a subset of the universal set, and I don't see how anyone could disagree with using "anything" as a good description of an element of the universal set. So it seems that, from the set view of the world:
At least in the sense that the set of nothing is a subset of the set of "all anythings". Now consider how this stuff actually occurs in code:
To me it is totally intuitive that an empty list is a "list of nothing", and that asking for the element at an index would return "nothing". To me it would be completely unnatural that an empty list would be a "list of everything", and I'm pretty certain that 99.9% of English speakers would agree with me on that. |
Q: what is both an animal and a mineral? That answer is incorrect (should be And we can reason out that bottom will never be used in covariant semantics. Thus your answer is always wrong (should be class Empty() satisfies List { Nothing item(Integer index) { throw; } } First, it is the wrong design. Even if you allow yourself the wrong unsafe (no typing!) design, it is still not "intuitive" that an empty list is a "list of nothing", and that asking for the element at an index would return "nothing". To me it would be completely unnatural that an empty list would be a "list of everything", But you are giving magic powers to type parameters that they don't have. The type parameter does not become the kind, the kind is The correct descriptions are: "list of members, where the members have a type nothing" The first choice is nonsense (assuming Do you really expect to dumb-down programming to the level where people don't even speak in their mind correctly what a type parameter is and thus conflate it with the kind of the type? You will create inconsistencies with conflated thought process in the mind of the user. To make it more clear, |
WTF? That was a question about ordinary types, not about parametrized types. I'm certain that no native English speaker would answer the above question with the response "everything". And FTR, the name
Which is fair enough. If the bottom type were named
I think your preference for "everything" over "nothing" here is that you're still thinking of relationships between types here i.e. bottom is the intersection of "every type". But that's not our naming convention. We name things by the values of the type, in this case "no values".
I don't understand the basis for this assertion, but I'm quite certain that everything I'm doing with the bottom type is perfectly sound from a type theory point of view.
That's a strange assertion and irrelevant to the discussion. Let's think of a
That's simply wrong. A method of return type
We're arguing about naming conventions and what names encourage the right intuition in most developers. We're not discussing the semantics of type parameters, which we all understand perfectly well. So I'm definitely not giving "magic powers" to anything.
I don't think anyone is conflating anything. I think you're projecting thought processes onto us that are not actually anything like how we understand this stuff.
FTR, no, it's not. Ceylon doesn't define this stuff in terms of virtual types, but in terms of type constructors. |
Q: what is both an animal and a mineral? The only other use case is as the input type of a function that can never be called, and the return type of a function that can never return. Both can never happen because the bottom type is subtype of all types. In neither case, will a non-existent value be input or returned. Thus we see the meaning of bottom is always about typing, never about values. And FTR, the name Nothing works even better for contravariant types than it does for covariant types. I am wondering if you entirely missed the point I was claiming, which is to differentiate between the semantics given by the declaration of
(there appears to be a bug in the parsing of your markdown, if I put the above inside blockquote tags) Afaics, the contravariant (w.r.t. to the kind I think your preference for "everything" over "nothing" here is that you're still thinking of relationships between types here. Yes, I even said so many times. And I said the reason is because never will the bottom type be used in any semantics where it is about its non-existent value. Bottom is at the other end of the infinite inductive type hierarchy, thus it only has coinductive semantics. This is why it will never have a use case where its semantics are about its non-existent value. And conversely for a coinductive language like Haskell, where the roles of the top and bottom types are reversed. In Haskell, the bottom type (conjunction of all types) is the root of all types! And the top type (disjunction of all types) never has a value! So you can't think about the infinite co-end of your infinite type hierarchy as consistent in semantics with the rest of your hierarchy in terms of values. Bottom in an inductive language represents the entire universe of values that is available in the coinductive (lazy) languages (which is accessible only as a type in contravariant semantics in an inductive language). And vice versa, in Haskell, top represents the entire universe of values that is available in our inductive (eager) languages, e.g. Ceylon, Java, Scala, (which is accessible only as a type in covariant semantics in a coinductive language). You are trying to apply covariant semantics to a type that is never (can't be!) used in covariant semantics. When bottom is used as a type parameter, it will never have covariant semantics. The only other uses cases are for the input and return type of a function. First, it is the wrong design. List should not contain an item method, Head should. If you want in private email, I can share with you the correct way to design a list api, so that it never throws an exception. Then we can talk about how your Producer argument is irrelevant. It would be too lengthy to go back and forth on here. Or we can just leave the issue as is. Even if you allow yourself the wrong unsafe (no typing!) design, it is still not "intuitive" that item returns Nothing. It most definitely returns an exception. There are two ways of thinking of the same thing. Either we say the function never returns, which supports my argument (as I explained near top of this post). Or we can conceptually realize that the function returns to any function in the program (via an exception) and returns any possible type. In support of the latter interpretation, note that exceptions can be modeled as return values in an ExceptionMonad. Thus we never have semantics for bottom, which are about its non-existent value, rather always about its type. We're arguing about naming conventions and what names encourage the right intuition in most developers. We're not discussing the semantics of type parameters, which we all understand perfectly well. So I'm definitely not giving "magic powers" to anything. Every use case of bottom never relatives to it as a non-existent value. So WTF would you name its non-existent value? Use cases are vital in engineering. You want to be consistent and name types according to their values, but this rule must be broken for the bottom type, because it has no semantics that use its non-existent value property. Thus by emphasizing the semantics of bottom that are never used, you impart some inconsistent thinking about what type parameters do (as I explained in the prior post). I don't think anyone is conflating anything. I think you're projecting thought processes onto us that are not actually anything like how we understand this stuff. You guys are the one who wrote "list of nothing" is intuitive. That means you are encouraging the interpretation of type parameters that is inconsistent with what type parameters are. You are actually moving the type parameter into the kind (as I explained in my prior post). To make it more clear, List is a shorthand for List with a membertype of Agree that List is a kind which is a type constructor (like a Functor in Standard ML), and the type parameter is T. And you are correct that generally speaking T does not mean "member type". But in the case of the List, it does mean member (or element) type. So both of our statements were correct, yours was just less specific (i.e. more generalized to all possible semantics for kinds). P.S. I am not arguing this to force any name for Ceylon. I am arguing so that FTR, I will know if I was able to present an objective logic. Because ultimately I have to pick a name for the language I am creating. If my effort to explain my logic can benefit Ceylon, then great. |
I consider my input here to be completed. Thank you for letting me contribute my feedback. I accept any name choice. I need to move on. I have spent too much time on it, and it is objectively clear (in my own mind at least) for my own language that in type theory the co-end of our language's evaluation strategy (eager or lazy, i.e. inductive/covariant or coinductive/contravariant) is never about its non-existent value. Afaik, that is a new finding in type theory (also that the dual evaluation strategy is the other side of the universe), so although it is obvious in hindsight, I should probably write a research paper on the finding. P.S. For my language, I have chosen I am conflicted about the choice between Regarding the prior complaint about I have since shown that the bottom type will never be used in such a contravariant (i.e. Here is a link to my prior post with the tradeoffs for The more I think about it, I could choose So by choosing And I am not sure it is an inferior implicit "is-a" relationship to The names that have a correct "is-a" relationship are The advantage of Finally, I could also accept |
Extremely happy to see Anything/Nothing replace Void/Bottom. I found this discussion after googling for "name bottom ceylon". Excellent! |
WTF? I just noticed the top type in Ceylon is |
I'm sooo going to tweet about this. |
The nirvana of the active nonresponse strategy is simply not having a twitter account to not respond with. Sent from my iPhone On 06/12/2012, at 3:59 PM, OneCheese notifications@github.com wrote:
|
I have renamed |
We find that
Void
(the top of the hierarchy) is not adequatly named, since it conveys the idea that it can only point to nothing.Similarly we find that
Bottom
(the subclass of every type) is confusing for those unfamiliar with the notion (everyone except ML guys).We proposed the following alternatives:
Note that
undefined
is a valid value in many languages and would therefore be confusing.The text was updated successfully, but these errors were encountered: