What is usually called Universe in Type Theory is the type of types.
(or the type of the codes for types).
What is usually called Universe in Type Theory is the type of types.
(or the type of the codes for types).
(Forking to scala-debate, please remove scala-language from any subsequent replies)Since I think most of us are pretty comfortable with the variance of Function1 being [-A, +B], I would propose the following litmus test:If I write a function with a signature, Universe => ???, would one expect that to take any available input or would one expect it to be uncallable?Personally, I interpret A => B to mean "takes a member of Set A and return a member of Set B"Based on that I'd expect Universe => B to take any member of the Set of things in the Universe and return me a B (whatever that might be). From that I'd conclude that Universe is Top.
If we were talking about Universe.type I could see how the type implies a special type of object. But Universe just implies any object in the universe, not all of them at once.
BR
John
Might also add that Universe => T is a tautology:
Given that anything exists at all then there exists a T
And given that this implication exists in our universe it must then be that a T exists.
Thus Universe => T is the same type as just T, no?
BR
John
...But Universe just implies any object in the universe, not all of them at once.
Would you say x:Boolean ⇔ x={true, false} or x:Boolean ⇔ x=true ⊕ x=false?
When you said that an argument of type Universe implies an object that is the set of everything it seems you you were saying that x:Universe should be interpreted like the first statement.
Would you say x:Boolean ⇔ x={true, false} or x:Boolean ⇔ x=true ⊕ x=false?
When you said that an argument of type Universe implies an object that is the set of everything it seems you you were saying that x:Universe should be interpreted like the first statement.
Trivially no, because it expresses any one of an arbitrary number of mappings between those two sets.
But is it really that simple ? Int is a type, but the set of all positive Int values is not a subtype of Int, unless of course I can define it and state it is.
The same goes for collections, an array of Int is an array of Anyval, so all values of Array[Int] are also in Array[Anyval] TAKEN AS A SET. but is Array[Int] a subtype of Array[Anyval], regardless of if I enforce covariance ? Following this thought, if what you understate is true, the concept of user-defined variance would be rendered meaningless, since variance would implicitly flow from the types taken as a sets. I'm not saying you are "wrong", but I'm intrigued.
So the model of theUniverse
as the conjunction of all its types, i.e. Bottom, is consistent with the collection of its members[1] for an outside observer that can see all infinite possible types in the universe. The type of each such member is a supertype of Bottom and the collection's type parameter has the Top type, i.e. the disjunction of the types of all infinite members in the universe. Since the type parameter of the collection is covariant (not contravariant), the type of the type parameter of the collection when assigning to supertypes is the contravariant dual, i.e. the conjunction of the types of all infinite members in the universe, i.e. which has only one value which is the empty set. So in terms of how both theories can view (i.e. share, assign, or read) the type of the entire universe, they both are the empty set of the conjunction of all infinite types. (Note, the outside observer can also enumerate all the members individually from its infinite collection, but as explained in prior post, this is not a falsifiable theory because we can't test or measure an outside observer since we are inside the universe.)Thus this proves mathematically that the two possible theories for the universe, are equivalent. The only difference is the perspective of the observer. Since we are inside the universe, then we model the universe as a conjunction of its types (thus get an empty set as the observation shared with all infinite instances in the universe), instead of as a collection of the infinite members of those infinite types. But when the outside observer tries to assign the entire universe (instead of enumerating the individual members of its infinite collection), the type also degenerates mathematically to conjunction of its types, as explained in the prior paragraph.
> However, for example a House is not the disjunction of the furniture inside
> of it, a Car is not the disjunction of the seats, engine, windows, etc..
Ok, I think I see what you mean. On my end I was somewhat begging the
question. If x:Universe reads x is a member of Universe (in the venn
diagram sense) it must be Top, but you are focusing on the x IS A
Universe sense.
But to be A Universe, you must be THE Universe.
Thus my earlier
reference to Universe.type as a more sensible type for that use case.
> The Universe has all the things in it simultaneously.
But now you are again flipping to a HAS A relationship between our
universe and it's content. Again something I think makes sense when
discussing Universe.type
How do you arrive at the conclusion that Universe IS A <anything> ?
It would imply that for all types there is an instance that is not
only that type but also the Universe?
> they are used to thinking about a Universal type, and have never seen before
> a Universe type, because it is impossible to instantiate the entire
> Universe. But this is Bottom, but they've either never been taught Bottom,
> or never been exposed to the idea that Universe and Bottom are the same
> thing.
But this is a paradox. You first claim that there is an object
containing everything, and that the type of this object is Universe,
and then based on the premise that this object contains everything
then it must be infinite and therefore cannot exist? But if it does
not exists, how can it then be infinite or contain everything?
What is very intriguing to me is that afaics we can mathematically prove the Liskov Substitution Principle is a consistent model for the universe, and then arrive at Bottom is the Universe.
(Tangentially, Erik Verlinde has also proven how entropy is mathematically equivalent to the gravitational force, and I related LSP to entropy, so I posit it will probably be possible to show consistency to the other proven theories of the universe such as relativity)
On Sat, Oct 6, 2012 at 2:50 AM, Shelby <she...@coolpage.com> wrote:What is very intriguing to me is that afaics we can mathematically prove the Liskov Substitution Principle is a consistent model for the universe, and then arrive at Bottom is the Universe.
I think you're confusing the abstract notion of "the universal set" with the notion of a physical universe.
The universal set is not really tenable as a mathematical object; it's really a "proper class", or it has weird properties such as not supporting filtering (i.e. if you have an indicator function phi: U => Boolean, you cannot in general find {x in U | phi(x)} in the universe). And the physical universe isn't a set at all, it's an instance.
The bottom type is uninhabited, so calling it Nothing makes sense to me, as does identifying it with non-termination (since you don't actually get anything in that case).
(Tangentially, Erik Verlinde has also proven how entropy is mathematically equivalent to the gravitational force, and I related LSP to entropy, so I posit it will probably be possible to show consistency to the other proven theories of the universe such as relativity)
This is astoundingly unlikely. A field falling off as 1/f^2 (or potential as 1/f) is the same as a statistical phenomenon that goes as the power of the number of particles? I don't think so, not under any remotely useful definition of "mathematically equivalent".
On Saturday, October 6, 2012 7:05:32 AM UTC+8, John Nilsson wrote:Ok, I think I see what you mean. On my end I was somewhat begging the
question. If x:Universe reads x is a member of Universe (in the venn
diagram sense) it must be Top, but you are focusing on the x IS A
Universe sense.
":" means subtype of (equivalent to "is or is subtype of").
Subtype means a narrower set (given by the Liskov Substitution Principle).
There is nothing less narrow than top, because it is the disjunction of all types (the instances in the set can be all types).
There is nothing more narrow than bottom (Universe), because it is the conjunction of all types (the only instance is the empty of of types).
On Sat, Oct 6, 2012 at 2:50 AM, Shelby <she...@coolpage.com> wrote:What is very intriguing to me is that afaics we can mathematically prove the Liskov Substitution Principle is a consistent model for the universe, and then arrive at Bottom is the Universe.
... And the physical universe isn't a set at all, it's an instance.
On 06.10.2012 10:26, Shelby wrote:Nope, it means "is instance of". A value which belongs to the set. "x∈A"":" means subtype of (equivalent to "is or is subtype of").
The instances in the set cannot be all types. The instances are not types. The instances *can be/are of-any-type*.
Subtype means a narrower set (given by the Liskov Substitution Principle).
There is nothing less narrow than top, because it is the disjunction of all types (the instances in the set can be all types).
The bottom *IS* the empty set, there is nothing in the empty set. Not even "empty of types", whatever it might be, is the instance of bottom type. There is no instance, there can't be.There is nothing more narrow than bottom (Universe), because it is the conjunction of all types (the only instance is the empty of of types).
P.S. To put gently, I think this "bottom = Universe" is a total non-sense. I'm surprised you can hold it for so long. But I am not arguing against it anymore, it feels hopeless.
On Saturday, October 6, 2012 5:07:21 PM UTC+8, j3vanek wrote:The bottom *IS* the empty set, there is nothing in the empty set. Not even "empty of types", whatever it might be, is the instance of bottom type. There is no instance, there can't be.Not it is not. There are many things that are the empty set:That is a grave error in logic.Bottom has a single value that is the empty set, but its type is not the empty set. Its type is the conjunction of all types. Period. If you want to try to refute that, have fun hitting yourself over the head with a hammer.
On Saturday, October 6, 2012 6:30:41 AM UTC+8, Repain Alex wrote:But is it really that simple ? Int is a type, but the set of all positive Int values is not a subtype of Int, unless of course I can define it and state it is.
The same goes for collections, an array of Int is an array of Anyval, so all values of Array[Int] are also in Array[Anyval] TAKEN AS A SET. but is Array[Int] a subtype of Array[Anyval], regardless of if I enforce covariance ? Following this thought, if what you understate is true, the concept of user-defined variance would be rendered meaningless, since variance would implicitly flow from the types taken as a sets. I'm not saying you are "wrong", but I'm intrigued.
If you defined the collection with a contravariant type parameter, you would never be able to get any value out of it, because the return values will have to be a supertype of Anyval. So Int can be a supertype of Anyval for a collection that is the empty set as viewed by all reading consumers.As you know, covariance is based on the Liskov Substitution Principle, which is best understood in terms of sets. Afaics, it doesn't become inconsistent, i.e. our choice for variance annotation will still obey the narrower sets are subsets rule, and will never be an arbitrary result.Does that entirely address your point?
I think I did make a mistake where I claimed Bottom has a single instance which is the empty set.Bottom's type is the conjunction of all types, which reduces mathematically to the empty set of types, thus bottom has one instance that is the conjunction of all types.We know (originally pointed out by Andriaan Moors) that the conjunction of types, has the disjunction of the members (methods) of those types. So all the methods of the universe are in the Bottom's type, so clearly it is not just the empty set of types.Thus my argument holds that saying Bottom is the empty set of types, i.e. nothing, is semantically incorrect.We can't perceive all of the universe, but the universe continues running anyway (the methods of all the types continue to run).We can't instantiate the bottom type, because the disjunction of the methods has the conjunction of the types of the arguments of all the methods, again arriving at any empty set for argument input types. The methods are not empty, but the ability to call them is obscured from our perspective of infinite shared observers inside the universe.I understand that is very non-intuitive to conceive that something that contains everything could also be an empty set. The key is to understand that the empty set is our mutual (shared) coherence when viewing that infinite set.But it is not empty, because the structure remains, even though we can't perceive the infiniteness of it, i.e. all the methods remain, but we can't all them.
2012/10/6 Shelby <she...@coolpage.com>On Saturday, October 6, 2012 6:30:41 AM UTC+8, Repain Alex wrote:But is it really that simple ? Int is a type, but the set of all positive Int values is not a subtype of Int, unless of course I can define it and state it is.
The same goes for collections, an array of Int is an array of Anyval, so all values of Array[Int] are also in Array[Anyval] TAKEN AS A SET. but is Array[Int] a subtype of Array[Anyval], regardless of if I enforce covariance ? Following this thought, if what you understate is true, the concept of user-defined variance would be rendered meaningless, since variance would implicitly flow from the types taken as a sets. I'm not saying you are "wrong", but I'm intrigued.
If you defined the collection with a contravariant type parameter, you would never be able to get any value out of it, because the return values will have to be a supertype of Anyval. So Int can be a supertype of Anyval for a collection that is the empty set as viewed by all reading consumers.As you know, covariance is based on the Liskov Substitution Principle, which is best understood in terms of sets. Afaics, it doesn't become inconsistent, i.e. our choice for variance annotation will still obey the narrower sets are subsets rule, and will never be an arbitrary result.Does that entirely address your point?
Not exactly, or maybe I missed something in your sentences. What I was trying to point out is that, if the subtyping relation is governed by the set inclusion on types taken as sets, then there would be no theoretical value in variance annotations, since we could infer variance from the types used in the type instanciation... That links to your idea of observer relativity, I suppose : the Universe I observe only has that amount of types, those I'm using or able to access, and if I know their relationships as sets, then every type I will construct using these have their relationships already determined. What I don't know, I can't use, but assuming an external observer that is omniscient and knows fully about the relationships between the types in the Universe (taken as sets of values), that observer do not need the concept of variance, which is what I stumbles on.
It would make more sense if you associated the methods (more generally, the fields) to the value instances of a type than to the type itself. That is, all values in a type share the same set of methods. It can be considered the structure of the type itself, but let's rather see it as the common structure of all instances of a type. Thus Bottom can have only one type instance (disjunction of all types), this instance has zero value (it reduces to the empty set, the only set that is subset of all sets), and all values of this instance possess all fields from all values of all types, by the disjunctive nature of Bottoms.
So the conclusion is that bottom has a type which is not nothing, its type as a structure of fields which is a disjunction, so it can't instantiated...
...meaning you Never reach the edge of the universe. And there is no instance of bottom.
Also I have asserting that returning bottom from a function is returning the entire universe of types (indeterminance), because the (other) type constraints of your functions have been (otherwise) violated. I probably have more reasoning to support why bottom is universe, will need to collect my thoughts more.
Den 6 okt 2012 10:26 skrev "Shelby" <she...@coolpage.com>:
>>
>> Thus my earlier
>> reference to Universe.type as a more sensible type for that use case.
>
>
> I don't understand this notation.
It is a singleton type
Boolean = true.type + false.type
BR
John
I think that the intrusions of physics principles is not serving your point very well here. I can understand the quest for an analogy, but it's hard to follow your thoughts when you do so many travels between type theory and (meta)physics.
What is commonly accepted up to now is that "Univers", as in "Universal Type", is referring to Top
, and that Bottom is a type that has no value (interestingly enough, in the Curry-Howard correspondance, Bottom is mapped to falsity).
Using Universe for Bottom sounds very unappealing to me, rather I'd find something like "All" easier to comprehend : a value of type All is a value that is of all types in the universe.
Because of the Curry-Howard correspondance again, we can affirm it's impossible : if we take a non-trivial type Int, and NotInt, the type of all that is not an Int, we can not find any value that is both an Int and a NotInt. Thus Int inter NotInt can not be populated, and by extension All can not be either. We are indeed using the type that is the conjunction of all types, and it is easy to prove that it is unpopulated.
The word Universe is not as easy to comprehend, at least IMHO.
That said, I'm satisfied enough with Nothing as the bottom type in Scala. It is really used to mean "nothing" most of the times...
The type of bottom has an empty set of *names* of types, but it still has a type with structure.The type of bottom can't be just the empty set of types, because the conjunction of types is not the empty set of types. Rather it is a type which includes the disjunction of all fields.Bottom's type thus has no name (there is an empty set for the *names* of types), but the structure is a disjunction of all fields.
a. it is the subtype of every type in the universe (infinite lower bound is always expressed in computer science as a coinductive type, e.g. streams)
Two things about structural types
A) Do you base your argument on all types being structural? Because that would imply that true.type = false.type which either means not singleton types or that true = false. Neither seems that applicable to Scala.
B) If your point is that Universe can't be instantiated because it must have all possible members I think you are wrong. Wouldn't such an instance simply be the equivalent of a dynamicly typed object responding to every possible message?
BR
John
Two things about structural types
A) Do you base your argument on all types being structural?
Because that would imply that true.type = false.type which either means not singleton types or that true = false. Neither seems that applicable to Scala.
B) If your point is that Universe can't be instantiated because it must have all possible members I think you are wrong. Wouldn't such an instance simply be the equivalent of a dynamicly typed object responding to every possible message?
On Sunday, October 7, 2012 12:23:32 AM UTC+8, John Nilsson wrote:Two things about structural types
A) Do you base your argument on all types being structural?
Bottom is a structural type because it is the conjunction of all types. So the conjunction of all types is the disjunction of (I believe all permutations of groups of) the fields of those types. Thus the result is a type which has no name, but has the disjunction of all fields of all types.A structural type is type without a name, that is matched to other types based on the fields of the type. Afaics, this is how bottom is a subtype of all types (it is matched structurally).Afaics, this puts to rest the notion that the type of bottom is Nothing. The type of bottom is inhabited with a disjunction of all fields in the universe. The values of bottom are not inhabited, so we can say that instances of bottom Never occur.With a normal inductive type, the fields of the type are matched to the values, i.e. a Car class that has a 'color' field. So we are used to focusing only on the "is-a" relationship to the values that are inhabited. But with a coinductive type, the structure of the final object is obscured (disjunction of all fields means the field structure can be anything is thus unknown) and if we name only the final object, then we ignore the coalgebra that gives the coinductive type its semantics. The whole reason that bottom exists is because it is the subtype of all types. To say its final object value is Nothing (does not exist), ignores what bottom really is. See my prior message discussing coinductive types and the link on coalgebras.Because that would imply that true.type = false.type which either means not singleton types or that true = false. Neither seems that applicable to Scala.
I don't understand.B) If your point is that Universe can't be instantiated because it must have all possible members I think you are wrong. Wouldn't such an instance simply be the equivalent of a dynamicly typed object responding to every possible message?
On Saturday, October 6, 2012 4:35:58 PM UTC+8, Rex Kerr wrote:On Sat, Oct 6, 2012 at 2:50 AM, Shelby <she...@coolpage.com> wrote:What is very intriguing to me is that afaics we can mathematically prove the Liskov Substitution Principle is a consistent model for the universe, and then arrive at Bottom is the Universe.
I think you're confusing the abstract notion of "the universal set" with the notion of a physical universe.Are you refuting my proof that the collection of all instances has as its supertypes the collections of any (permutations of) types, thus it has the same supertypes as the bottom type, when restricted to collections of instances?
The bottom type is uninhabited, so calling it Nothing makes sense to me, as does identifying it with non-termination (since you don't actually get anything in that case).
The bottom type is inhabited by the empty set. Its instance has a count member and it returns 0.
A function which returns bottom is actually returning the entire universe
(Tangentially, Erik Verlinde has also proven how entropy is mathematically equivalent to the gravitational force, and I related LSP to entropy, so I posit it will probably be possible to show consistency to the other proven theories of the universe such as relativity)
This is astoundingly unlikely. A field falling off as 1/f^2 (or potential as 1/f) is the same as a statistical phenomenon that goes as the power of the number of particles? I don't think so, not under any remotely useful definition of "mathematically equivalent".
Did you read his proof? It shocked the scientific world two years ago and has been heavily peer reviewed.
Bottom would be inhabited by both, or in other words Bottom = Top
On Sat, Oct 6, 2012 at 4:58 AM, Shelby <she...@coolpage.com> wrote:On Saturday, October 6, 2012 4:35:58 PM UTC+8, Rex Kerr wrote:On Sat, Oct 6, 2012 at 2:50 AM, Shelby <she...@coolpage.com> wrote:What is very intriguing to me is that afaics we can mathematically prove the Liskov Substitution Principle is a consistent model for the universe, and then arrive at Bottom is the Universe.
I think you're confusing the abstract notion of "the universal set" with the notion of a physical universe.Are you refuting my proof that the collection of all instances has as its supertypes the collections of any (permutations of) types, thus it has the same supertypes as the bottom type, when restricted to collections of instances?
I'm not sure the collection of all instances is well-defined theoretically (e.g. what axioms of set theory are you taking?). Also, at the very least you're not being clear about what you mean by "instance" and "collection".
Presumably by "collection" you mean "intersection" as in A0 with A1 with A2 with ....
Anyway, I am probably misunderstanding, but there seems to me to be something profoundly lacking in your view of types that is required to support the universe idea. For example, the type Char with Double is uninhabited/uninhabitable, just like Nothing is. But they're not the same; Char with Double promises far less than Nothing does.
You can enforce duality between the intersection of types and the union of inhabitants of those types (if you disallow uninhabited types as irrelevant), but why do you want to name the type after its dual?
We need a type; just name the type. Nothing is fine, as a mnemonic to remind us that it's uninhabited.
Yes, we have to remember that it's not the only uninhabited type, but the Nothing type.
We could more accurately call it Politician as it will promise to be whatever anyone asks it to be (but not actually do it), or UniverseDual, but I don't think this actually clarifies anything. Even calling it Bottom is probably not an improvement; people who already know what Bottom is can trivially learn that the bottom type is called Nothing in Scala, and people who don't know what Bottom is aren't helped at all by the name, while with "Nothing" they get the idea that you don't actually have an instance
, so maybe it's useful for exception handling or something.
(WithAll is also more correct, but awkward.)
(I'm skipping the set theory stuff since you haven't addressed it.)
The bottom type is uninhabited, so calling it Nothing makes sense to me, as does identifying it with non-termination (since you don't actually get anything in that case).
The bottom type is inhabited by the empty set. Its instance has a count member and it returns 0.
You can define it that way, but Char with Double is _also_ inhabited by that empty set with a count member which returns zero. That particular inhabitation is pretty useless. Why bother formulating things so that it exists?
A function which returns bottom is actually returning the entire universe
This is again completely confusing instances with sets that are duals of type intersections.
(Tangentially, Erik Verlinde has also proven how entropy is mathematically equivalent to the gravitational force, and I related LSP to entropy, so I posit it will probably be possible to show consistency to the other proven theories of the universe such as relativity)
This is astoundingly unlikely. A field falling off as 1/f^2 (or potential as 1/f) is the same as a statistical phenomenon that goes as the power of the number of particles? I don't think so, not under any remotely useful definition of "mathematically equivalent".
Did you read his proof? It shocked the scientific world two years ago and has been heavily peer reviewed.
All right, since your answer was less glib than I'd thought--the relativity thing kind of threw me since there is no intrinsic time among types--what I actually mean is that first, no, I haven't read the proof, but from what I gather of the prerequisites he's come up with a substantially _more_ complicated system to explain a less complicated one. In particular, since entropy is a component of Gibbs free energy, you can run devices, including presumably instantiations of Turing machines, purely off of entropy. Thus _that_ you have found some computation you can do using entropy is much less interesting than _how_. I'm unconvinced that Verlinde has done anything but a nonintuitive curve-fitting exercise. I should probably withhold judgment rather than concluding that he's probably on the wrong track, but I don't think it looks very hopeful.
Inferring anything about relativity from this is almost certainly unwise; the mathematics is very different to that for statistical mechanics, and requires a particular kind of space (-t,x,...) to work.
I already refuted that mistake of mine. The bottom type is not a single instance of the empty set, because the empty set does not include the disjunction of all the fields of the types in the conjunction of all types.
Thus of course an infinite thing can't be instantiated and can't be the subtype of anything, thus it can't ever return to an instance of anything. But that infinite thing is not nothing. It it the final object that everything is deconstructed from.
(Tangentially, Erik Verlinde has also proven how entropy is mathematically equivalent to the gravitational force, and I related LSP to entropy, so I posit it will probably be possible to show consistency to the other proven theories of the universe such as relativity)
This is astoundingly unlikely. A field falling off as 1/f^2 (or potential as 1/f) is the same as a statistical phenomenon that goes as the power of the number of particles? I don't think so, not under any remotely useful definition of "mathematically equivalent".
Did you read his proof? It shocked the scientific world two years ago and has been heavily peer reviewed.
Inferring anything about relativity from this is almost certainly unwise; the mathematics is very different to that for statistical mechanics, and requires a particular kind of space (-t,x,...) to work.
Coinductive types are weird and they are non-intuitive to us, because we are accustomed to thinking in terms of forming things by constructing them from building blocks. Whereas, co-inductive types are formed by deconstructing from something to the parts it was built from.
A function which returns bottom is actually returning the entire universe
This is again completely confusing instances with sets that are duals of type intersections.
My formalism above is weak. Did I fail?
Anyway, I am probably misunderstanding, but there seems to me to be something profoundly lacking in your view of types that is required to support the universe idea. For example, the type Char with Double is uninhabited/uninhabitable, just like Nothing is. But they're not the same; Char with Double promises far less than Nothing does.Do you refute Andriaan Moors' insight that the conjunction of two types contains the disjunction of the fields of those two types?
I want to name the category of objects that the coalgebra of the type contains. The bottom type does not contain nothing. Nor is the use cases of the bottom giving it a semantic of nothing (as I enumerated in a prior message).
We need a type; just name the type. Nothing is fine, as a mnemonic to remind us that it's uninhabited.What are the use cases where it can't contain an instance (i.e. is uninhabited)? I don't know of any.Yes, we have to remember that it's not the only uninhabited type, but the Nothing type.Can you name any other type that can't contain an instance (i.e. is uninhabited)? I can't think of one that is named.
But we never use bottom to represent no instance. I already enumerated the use case examples in a prior message.
, so maybe it's useful for exception handling or something.An exception does not return a "can't make an instance" to the caller. It never returns to the call. And it returns an indeterminant state to some catch block. It has exposed the catch block to all possibilities, i.e. all types in the universe, thus is has returned the universe.
Since this is only marginally on topic for Scala,
maybe you can try to compress your thoughts into a smaller number of posts? I only have a few brief remarks.
On Sun, Oct 7, 2012 at 1:52 AM, Shelby <she...@coolpage.com> wrote:
My formalism above is weak. Did I fail?
I don't know. I haven't studied category theory. It looks plausible given what I know, but I don't know whether that formalism maps adequately onto actual type systems.
Anyway, I actually was never arguing that there was no dual, just that naming something by its dual is liable to be confusing, especially when the duals are in some sense inverses of each other dimensionally (which is true here). For example, I do not call a shot glass the "nearly-universe glass" because almost all the universe is outside of it.
Anyway, I am probably misunderstanding, but there seems to me to be something profoundly lacking in your view of types that is required to support the universe idea. For example, the type Char with Double is uninhabited/uninhabitable, just like Nothing is. But they're not the same; Char with Double promises far less than Nothing does.Do you refute Andriaan Moors' insight that the conjunction of two types contains the disjunction of the fields of those two types?
Of course not. That's what I'm _declaring_.
I want to name the category of objects that the coalgebra of the type contains. The bottom type does not contain nothing. Nor is the use cases of the bottom giving it a semantic of nothing (as I enumerated in a prior message).
Well, I don't think that's a good idea.
We need a type; just name the type. Nothing is fine, as a mnemonic to remind us that it's uninhabited.What are the use cases where it can't contain an instance (i.e. is uninhabited)? I don't know of any.Yes, we have to remember that it's not the only uninhabited type, but the Nothing type.Can you name any other type that can't contain an instance (i.e. is uninhabited)? I can't think of one that is named.
Named? No. But I already gave the Char with Double example.
But we never use bottom to represent no instance. I already enumerated the use case examples in a prior message.
You have it backwards: if we never intend to return an instance (because we're not going to return normally at all, for example), we can promise whatever we want, including everything. Hence, in cases where no instance will materialize, we naturally use Nothing.
, so maybe it's useful for exception handling or something.An exception does not return a "can't make an instance" to the caller. It never returns to the call. And it returns an indeterminant state to some catch block. It has exposed the catch block to all possibilities, i.e. all types in the universe, thus is has returned the universe.
Did you not notice that in the JVM, the catchable value has type Throwable? Saying it has "returned the universe" is just not correct. First, it doesn't return normally, so saying that it has returned is wrong. Second, that value which is given is a Throwable and isn't the universe.
--Rex
P.S. The entropic gravity and related physics discussions are too far afield from Scala for me to continue here, except to mention that I question the parsimony of such a model; it would need to accurately predict a *lot* of data to be worth the weight of the theory. But that's an aside better discussed in another forum.
I did define the fields of true and false like so
fields(true.type) = fields(false.type) = { ∨, ∧, ¬ }
Where did I fail?
Do you refute Andriaan Moors' insight that the conjunction of two types contains the disjunction of the fields of those two types?
The development of the last few posts of mine is that in an eager language, the only way to represent the Universe, is by its coinductive dual form. Thiis coinductive form is no less the universe for an eager language, than the inductive form is in a lazy language. And so in an eager language, the CoUniverse is the Universe. Our Universe is a contradiction, it has both inductive and coinductive forms simultaneously. Anything that is infinite will have this contradiction. This is why bottom is a contradiction in the Curry-Howard correspondence.
If you name bottom something less than the universe (or at least less than the subtype of all types in eager or supertype of all types in lazy), then the name is not correct.
I want to name the category of objects that the coalgebra of the type contains. The bottom type does not contain nothing. Nor is the use cases of the bottom giving it a semantic of nothing (as I enumerated in a prior message).
Well, I don't think that's a good idea.But I haven't seen a good reason for naming something nothing, when it is the universe.I haven't even seen a use case where bottom is semantically nothing.
If a non-terminating function returns CoUniverse, then it is clear that it returns no instance, but it can be assigned to any structural type that has any of the fields of any type in the universe. So that is telling you is your function that catches the exception (the return value) could be any method in the program. So it is mathematically congruent to what an exception can do.
, so maybe it's useful for exception handling or something.An exception does not return a "can't make an instance" to the caller. It never returns to the call. And it returns an indeterminant state to some catch block. It has exposed the catch block to all possibilities, i.e. all types in the universe, thus is has returned the universe.
Did you not notice that in the JVM, the catchable value has type Throwable? Saying it has "returned the universe" is just not correct. First, it doesn't return normally, so saying that it has returned is wrong. Second, that value which is given is a Throwable and isn't the universe.
The return value of an exception is the coinductive form, not what is being return, but where it is being returned to.
On Sun, Oct 7, 2012 at 5:02 PM, Shelby <she...@coolpage.com> wrote:The development of the last few posts of mine is that in an eager language, the only way to represent the Universe, is by its coinductive dual form. Thiis coinductive form is no less the universe for an eager language, than the inductive form is in a lazy language. And so in an eager language, the CoUniverse is the Universe. Our Universe is a contradiction, it has both inductive and coinductive forms simultaneously. Anything that is infinite will have this contradiction. This is why bottom is a contradiction in the Curry-Howard correspondence.
Why is it not the case that the CoUniverse is the CoUniverse and the Universe is the Universe? [...] You _can_ identify this peculiar type with the universe via an isomorphism--that's fine--but where we part company is that you want to call this the universe. It's not. It is it's very own thing, a conjunction of all types, and instead of searching for a name that describes it, you want to use the name for its dual.
In particular, you have built a type that claims instances of it can do anything and everything that any other type can do. This is _not a property of the universe_ since, for example, it doesn't make any sense to negate the universe as negation isn't defined on most things in it.
If you name bottom something less than the universe (or at least less than the subtype of all types in eager or supertype of all types in lazy), then the name is not correct.
I think you're missing something, but I don't have time to check. Laziness ought not change the typing relationship, only whether something can be "instantiated" when it can't actually be computed.
I want to name the category of objects that the coalgebra of the type contains. The bottom type does not contain nothing. Nor is the use cases of the bottom giving it a semantic of nothing (as I enumerated in a prior message).
Well, I don't think that's a good idea.But I haven't seen a good reason for naming something nothing, when it is the universe.I haven't even seen a use case where bottom is semantically nothing.
I think that's because you're trying to name things on the basis of what the fields/methods are, and I'm trying to name the on the basis of what the set of instances is.
That is, when you name something Int, do you say, "Well, this type has methods +,-,* and is inhabited by an additive and multiplicative zero, etc. so I will call it Int", or do you say, "Well, this has elements 0,1,-1,2,-2,... which are the integers, and therefore I will call it Int"?
The naming conventions we use, I argue, are most of the what-instances-can-be-here. For example, Int and a hypothetical UnsignedInt would have exactly the same methods, but in one case you interpret the 0xFFFFFFFF as -1 and in the other as 4294967295 (when converting to other types). In your interpretation, since the fields/methods are the same for the two types they ought to get the same name.
So, anyway, I reject all this "let's call the universal conjunction type Universe" business. That's not how we normally name types, and naming it using the opposite convention from normal isn't likely to yield much insight as to how to use it.
I don't think "Nothing" is necessarily the best, since as we've both pointed out it's not the only possible uninhabited type, but it's way, way better than Universe.
There are no instances in Nothing.
You don't find a Universe in there; if you could instantiate it, it would be the dual of the universe and have really interesting properties but it wouldn't be the universe.
And in Scala you can't even instantiate it. So calling it Universe is a really bad idea.
Universal would hit nearer the mark as it wouldn't confuse name-via-dual vs. name-via-instances so badly,
but I don't like that this implies that it might be possible to have one of these magic Universal things (which would work by, I suppose, keeping a Universe in its pocket and picking out just the right element from the universe to fit any given context it found itself in).
If a non-terminating function returns CoUniverse, then it is clear that it returns no instance, but it can be assigned to any structural type that has any of the fields of any type in the universe. So that is telling you is your function that catches the exception (the return value) could be any method in the program. So it is mathematically congruent to what an exception can do.
Well, yes, in that sense it is, if you adjust your blinders exactly the right way. But this isn't a particularly useful property to notice. (In any particular program, an exception can only be caught by things in the stack trace, which produce way less diversity than anything in the universe, typically. And you completely ignore the fact that exceptions carry a payload; they're not just control flow.)
, so maybe it's useful for exception handling or something.An exception does not return a "can't make an instance" to the caller. It never returns to the call. And it returns an indeterminant state to some catch block. It has exposed the catch block to all possibilities, i.e. all types in the universe, thus is has returned the universe.
Did you not notice that in the JVM, the catchable value has type Throwable? Saying it has "returned the universe" is just not correct. First, it doesn't return normally, so saying that it has returned is wrong. Second, that value which is given is a Throwable and isn't the universe.
The return value of an exception is the coinductive form, not what is being return, but where it is being returned to.
Have you read about the equivalence of programs using exception handling and transformation of that program using Either? This is the useful duality to think about. "Where it is being returned to" is not the useful type information; rather it is "what is being returned". I can't find the reference at the moment; maybe you've seen the paper (or something that refers to it)?
Wrong. That is the top type. Universal is referring the instances in it. It is for inductive subtypes. Universal does not mean Universal. Dictionary says so.
In Shelby's framework (as I understand it), you only have one type. Top, True.type, False.type, and Bottom are all the same type, since they all have the same interface. (I don't think this is either a useful way to think about types or consistent with Scala's type system.)
On Mon, Oct 8, 2012 at 1:14 AM, Shelby wrote:
> Also I think maybe I misunderstood the math that Andriaan implied. Wouldn't
> the disjunction of the named types, be the conjunction of the fields for
> each named type separately, not all fields lumped separately from their type
> names? If yes, then afaics structural types are not incompatible with
> first-class disjunctions.
Hmm, ok that looks like it would resolve some issues
My point was exactly that a simple structural type can't really be
sub-type of a nominal type, because it could inhabit objects violating
the nominal type contract.
So we would have fields(Bottom) = { true.type.∨, true.type.∧,
true.type.¬, false.type.∨, false.type.∧, false.type.¬ }
and I guess, by extension, fields(Top) = {}
Two problems with this though.
1. The Bottom type doesn't really prohibit any implementations. But at
least it won't be true or false. I also guess your point about finite
universes applies too.
I still think it's simpler to say that x:Bottom iff x:true.type ∧
x:false.type though, so I still doesn't see why you insist on Bottom
to be purely structural.
2. I guess we've now lost dynamic dispatch, in this new Boolean
universe we can only call methods on instances of true.type or
false.type.
On Monday, October 8, 2012 7:45:18 AM UTC+8, John Nilsson wrote:On Mon, Oct 8, 2012 at 1:14 AM, Shelby wrote:
> Also I think maybe I misunderstood the math that Andriaan implied. Wouldn't
> the disjunction of the named types, be the conjunction of the fields for
> each named type separately, not all fields lumped separately from their type
> names? If yes, then afaics structural types are not incompatible with
> first-class disjunctions.
Hmm, ok that looks like it would resolve some issuesThe above was not intended to apply to bottom.My point was exactly that a simple structural type can't really be
sub-type of a nominal type, because it could inhabit objects violating
the nominal type contract.
Good point.I thinking we don't get a structural type. I am thinking we get a type without a name, but each the fields are tagged with the name of the type they appeared in. Then we get what I was starting above, plus we get the correct result for bottom too.
----------------------------------------
This message is intended exclusively for the individual(s) or entity to
which it is addressed. It may contain information that is proprietary,
privileged or confidential or otherwise legally exempt from disclosure.
If you are not the named addressee, you are not authorized to read,
print, retain, copy or disseminate this message or any part of it.
If you have received this message in error, please notify the sender
immediately by e-mail and delete all copies of the message.
In any case, you resolved the original problem I was concerned about,
where I was thinking a structural type could be returned in a future
first-class disjunction of named types.
I am curious what if anything I missed from Ryan Hendrickson's point about "member"ship.
We can not name a coinductive type by its values, because it does not have
any values.
For example, List[Nothing] is not a list of members with type Nothing. The
fact that it is chosen to be an empty list has no dependence at all on
Bottom being empty.
On Tuesday, October 9, 2012 11:48:19 AM UTC+8, Rex Kerr wrote:It is not a subjective argument to say that a type should be named to
>> We can not name a coinductive type by its values, because it does not
>> have any values.
>
> Er, "None", "Nothing", "Zilch", "Nada", "Empty", "Uninhabited", "Absent",
> ....
>
> We name things by the fact that there are none of them all the time.
match its semantics for all of its use cases.
> For example, a little while ago I wrote an exception handling classI won't be able to agree that is a valid counter claim, until I see the
> ("Tri")
> in response to Bruce Eckel's wish that there was something with both the
> properties of Try and of Either (i.e. your failure case can either be
> something typed to your specification or a Throwable). After application
> of various methods, one of the alternatives will become uninhabited. So,
> I
> thought: "well, there's obviously nothing in the Bad branch any more,
> let's
> make the type Nothing" and then thought through the issues with it
> actually
> being the Bottom type and made sure it was okay (it's a tradeoff, but I
> decided that it was better that way). The type name was highly suggestive
> of what to do in that case, which would not have been true if the type
> were
> named for its has-all-interfaces property.
code. Devil is in the details, I can't just take your word for it that
your usage had the correct local semantics of Nothing.
As far as naming goes, I am reminded of Simon Peyton-Jones' observation that calling monads "warm fluffy things" might have made a lot of lives a lot easier.
Sometimes formal correctness becomes secondary to easing broader understanding.
// V is the type of the value that you want (in Good)
// P is the type of the problem-reporting object you may generate (in Bad)
// Throwable is also possible (it's Ugly)
sealed trait Tri[+V,+P] {
// ...
def acceptAll[U >: V](f: P => U): Tri[U,Nothing] = this match {
case Bad(p) => try { Good(f(p)) } catch { case t if Recoverable(t) => Ugly[U,Nothing](t) }
case x => x.asInstanceOf[Tri[U,Nothing]]
}
// ...
}
final case class Good[V,P](value: V) extends Tri[V,P] { /* ... */ }
final case class Bad[V,P](problem: P) extends Tri[V,P] { /* ... */ }
final case class Ugly[V,P](thrown: Throwable) extends Tri[V,P] { /* ... */ }
"acceptAll" turns any bad values into good ones; after this you are certain there is nothing left in the Bad category. Hence, Nothing. Note covariance in P, so this is also the correct subtyping relationship.
On Wednesday, October 10, 2012 2:27:34 AM UTC+8, Rex Kerr wrote:// V is the type of the value that you want (in Good)
// P is the type of the problem-reporting object you may generate (in Bad)
// Throwable is also possible (it's Ugly)
sealed trait Tri[+V,+P] {
// ...
def acceptAll[U >: V](f: P => U): Tri[U,Nothing] = this match {
case Bad(p) => try { Good(f(p)) } catch { case t if Recoverable(t) => Ugly[U,Nothing](t) }
case x => x.asInstanceOf[Tri[U,Nothing]]
}
// ...
}
final case class Good[V,P](value: V) extends Tri[V,P] { /* ... */ }
final case class Bad[V,P](problem: P) extends Tri[V,P] { /* ... */ }
final case class Ugly[V,P](thrown: Throwable) extends Tri[V,P] { /* ... */ }
"acceptAll" turns any bad values into good ones; after this you are certain there is nothing left in the Bad category. Hence, Nothing. Note covariance in P, so this is also the correct subtyping relationship.
It is non-intuitive to declare a function that inputs Nothing, i.e. Tri[U,Nothing].acceptAll, because the only way to call it to encourage a downcasting runtime error.
def test( f: Nothing => Int ) = f(0.asInstanceOf[Nothing])
If you've thrown away P, why return a Tri[U,Nothing] and not a U?
So I see you are trying to think about Nothing in terms of its value, but it is getting you into trouble in your design.
Is Nat, the literal named type in the type system, the inductively-constructed type to which you refer? Or are you talking about a *kind* (or a 2-type or something--not sure what the canonical term is for such a beast) that Zero, Succ[Zero], Succ[Succ[Zero]]... all inhabit (in some non-Scala kind system that is richer than the simply typed lambda calculus)? Or is there something else you could be talking about?
What do you mean when you say that an instance of the natural numbers will have only one of its member types?
The ML language has a complete proof of its entire type system. And this proof relies on showing the inductive algebra for each built-in type.
On Tue, Oct 9, 2012 at 4:22 PM, Shelby <she...@coolpage.com> wrote:On Wednesday, October 10, 2012 2:27:34 AM UTC+8, Rex Kerr wrote:// V is the type of the value that you want (in Good)
// P is the type of the problem-reporting object you may generate (in Bad)
// Throwable is also possible (it's Ugly)
sealed trait Tri[+V,+P] {
// ...
def acceptAll[U >: V](f: P => U): Tri[U,Nothing] = this match {
case Bad(p) => try { Good(f(p)) } catch { case t if Recoverable(t) => Ugly[U,Nothing](t) }
case x => x.asInstanceOf[Tri[U,Nothing]]
}
// ...
}
final case class Good[V,P](value: V) extends Tri[V,P] { /* ... */ }
final case class Bad[V,P](problem: P) extends Tri[V,P] { /* ... */ }
final case class Ugly[V,P](thrown: Throwable) extends Tri[V,P] { /* ... */ }
"acceptAll" turns any bad values into good ones; after this you are certain there is nothing left in the Bad category. Hence, Nothing. Note covariance in P, so this is also the correct subtyping relationship.
It is non-intuitive to declare a function that inputs Nothing, i.e. Tri[U,Nothing].acceptAll, because the only way to call it to encourage a downcasting runtime error.
It outputs nothing as a type parameter. If you try to call twice in a row, then you will indeed need to supply f: Nothing => U, which should be a sign that what you're doing is not a good idea.
def test( f: Nothing => Int ) = f(0.asInstanceOf[Nothing])
0 is not Nothing, it's zero (the identity element for +). That this blows up in your face should be no more surprising than any 0.asInstanceOf[String] or any other nonsensical cast blowing up in your face. ("Wait, why didn't it give me the empty string?!?!")
If you've thrown away P, why return a Tri[U,Nothing] and not a U?
Because it might be a Throwable instead of a U. The code says so, even in this heavily abridged version.
So I see you are trying to think about Nothing in terms of its value, but it is getting you into trouble in your design.
I don't think you've understood the design yet, so I don't think you're in a position to conclude that.
Also, you can of course make this discussion tautologically resolve in your favor by firmly misinterpreting any type declaration of "Nothing" and doing something nonsensical,
My point was that you shouldn't be instantiating a Tri[U,Nothing], because by doing so, you've created a function that does not make any sense. And the only way to call that function is to create a run-time error.
Afaics, a function that inputs Nothing is nonsensical. The semantics of the language never allows you to call such a function, so why would create one?
If you've thrown away P, why return a Tri[U,Nothing] and not a U?
Because it might be a Throwable instead of a U. The code says so, even in this heavily abridged version.
So why not return Either[U,Throwable], so as to avoid that unsound function that inputs Nothing?
class Head[T]( head: T, tail: Option[Head[T]]) extends List[T]
> I create a method that requires a function that cannot be called.Problem is that you've shifted a compile-time check into a run-time check.
Returning instead Either[U, Throwable] would make the code more
self-documenting.
And you get rid of that asInstanceOf downcast. (this tells you that you've
opened a run-time hole somewhere)
Yeah, that is why my library does instead:
>
> This is done all over the place in the Scala library: Nil.head, None.get,
> Vector.empty(0), Seq.empty.map((n: Nothing) => "uhoh").
class Head[T]( head: T, tail: Option[Head[T]]) extends List[T]
So it is impossible to call Nil.head and get a run-time exception.
>
> This is harder to tell from the source: because Tri (as with Try) is
> bulletproof in that it catches all exceptions during processing. If you
> return an Either, any further processing loses its bulletproofness.
You can use the return value to instantiate another Tri.
The big hint is the use of a downcast (`asInstanceOf`) in your code. This
always means we have introduced a run-time hole some where (even if
manifests external to our API).
We can agree to disagree, if the following rebuttal doesn't convince you.
The big hint is the use of a downcast (`asInstanceOf`) in your code. This
always means we have introduced a run-time hole some where (even if
manifests external to our API).
Derek, I am not rebutting per se, but I want to repeat what I already
wrote, because (and I hope this has amicable tone as intended) your reply
causes me to be unsure if you realized that you are repeating what I
already wrote to some degree. So I prefer not to guess what you argument
...
I'd like to too, but perhaps I have introduced clarity (or mistakes?) that
requires one last followup?
Oh, it's completely useless, but completely safe. Shelby said that downcasting via asInstanceOf _always_ means that we've introduced a run-time hole. I provided an example where there is no run-time hole, just to demonstrate that his claim was incorrect.
> On Wed, Oct 10, 2012 at 7:24 PM, Shelby Moore <she...@coolpage.com> wrote:Rex, this reply wasn't addressed to you, so I wasn't forcing you to
>> I'd like to too, but perhaps I have introduced clarity (or mistakes?)
>> that
>> requires one last followup?
explain anything.
> Just mistakes, lots of mistakes. The worst at the moment is confusing TopI don't know what you are thinking about here, but I do not see where I
> and Bottom in that you're confusing uninhabited options on a sum type with
> arbitrarily inhabited options.
have conflated Top and Bottom. You would have to show in code what you
mean. I bet you conflated some things I have written.
What are you talking about?
> I think that beats the "if I create a
> function I must also create a value to pass to it" nonsense.
Did I ever say your API had to create a value of Nothing?
You are stubbornly clinging to your stance. I am to mine. Either it is
subjective or one of us is correct. If you have some allegations, then by
all means show it.
If you feel I am missing something, you can explain or your can agree to
disagree.
Upcasting in an inductive (eager) language exposes your program to the
upcast below. I guess you are thinking about how an input type is erased
Rex and Derek,It seems that Tri[U,Nothing] doesn't protect your API from anything, because this instance can be assigned to:Tri[U,Any]
So as much as Rex criticized me for the error of suggesting the return of Tri[U,Any], your code has the same error no?
Returning Tri[U,Nothing] is no different than returning Tri[U,Any], because the consumer of your API can UPcast it to Tri[U,Any].
So as I said before, using Nothing (essentially a defacto DOWNcast, i.e. implied asInstanceOf), exposes your program to the entire Universe of indeterminance.
So now do you finally believe me that Bottom is Universe? (analyze how the Any and Nothing get interchanged between the covariant return position and covariant input of the function f, then you see clearly the categorical dual has bitten your code)
You see trying to pretend that bottom is an nonexistent value, just allows your design to end up with the Universe where you did not intend it to be.
I knew I was correct on the theory!Am I wrong?
>> So as much as Rex criticized me for the error of suggesting the returnacceptAll returns Tri[U,Nothing] by design I assume to enforce a contract
>> of Tri[U,Any], your code has the same error no?
>>
>
> That's not an error.
that P remains Nothing?
The implied semantics (given by the meaning of the word nothing) that
Nothing marks an empty error condition in the Tri, is proven to be false,
by the fact that I can assign Tri[Int,Nothing] to a Tri[Int,String] and
the code still compiles and works the same.
_|_ will refer to "the bottom type"
Our discussion remains about what is the meaning of _|_ as it is being
used in the Tri use case, and thus what is the correct name for _|_.
A) The meaning of the P type parameter in Tri, is to hold the restrictions
on the future problem **types** that can be returned.
_|_ is used in an instance of Tri where the set of possible future problem
**types** is still infinite.
This semantics is due to the Q >: P in flatMap, and thus the only type
that fits is the "subtype of all types".
B) Afaics, you and Rex are essentially arguing that the above correct
semantic is equivalent to the semantic that says Tri[_,Nothing] means
there is no problem **type** specified yet.
But afaics B is not equivalent semantics to A because:
1. _|_ is only nothing w.r.t. to instances, not w.r.t. to types.
2. Nothing gives no indication that the set of types is still open.
The correct semantic for an intuitive name would be
"NothingYetAllAreAllowed".
But that specialized name won't work in all use cases for _|_.
#1 even causes an intuitive problem because if the problem is "nothing"
then how can I change it to "something" and what is the type of that
"something" I can change it to?
Also, when creating that Tri API, one needs to know that _|_ is the
"subtype of all types" in order to correctly design and understand how the
API works.
Also, afaics the programmer will never see the name for _|_ when
interacting with the Tri API.
object None extends Option[Nothing]
> If you want to see scaladoc of what I'd consider Nothing enforcing the
> lack
> of a value, look at the scaladoc for None. Nothing all over the place in
> the api there.
Says the **type** of the instance boxed by Option is nothing. Type is
nothing?
Incorrect semantics. The library designer will need to go study and find
out that Nothing is "subtype of all types".
And if you are arguing it is more intuitive for the consumer of the API,
they never see Option[Nothing]. They only see None.
(well I guess the compiler messages might print Option[Nothing])
> And when it comes to the name for bottom, I don't really much care, as youYeah :) I also said some eons ago in this thread that we can just declare
> should be able to just 'import scala.{Nothing => Universe}' if that floats
> your boat.
an alias :D
Any way, I wasn't seriously asking Scala to change the name. (I stated
this before)
I wanted to test if I have an objective case against Nothing.
I also thought it was pretty cool theoretically that _|_ is the universe.
I also thought the connection to inductive (eager) and coinductive (lazy)
duality was inspired and potentially helpful for seeing the bigger picture
of type theory.
sincerely.
I also thought it was pretty cool theoretically that _|_ is the universe.
I also thought the connection to inductive (eager) and coinductive (lazy)
duality was inspired and potentially helpful for seeing the bigger picture
of type theory.
On Thu, Oct 11, 2012 at 11:24 AM, Shelby Moore wrote:I also thought it was pretty cool theoretically that _|_ is the universe.
I also thought the connection to inductive (eager) and coinductive (lazy)
duality was inspired and potentially helpful for seeing the bigger picture
of type theory.
I think I can see your line of reasoning now, if I look at types in terms of subclassing. If Nothing is the subclass of all types then it should contain the function of all types. When I think in terms of types, I guess I don't really think about the relationships between them being due to subclassing, just that subclassing creates a relationship between 2 types. If that makes any sense.
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 is non-existent value.
Bottom is at the other end of the 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 is the root of all types! And the top type never has a value!
So you can't think about the infinite co-end of your 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 that is available in the coinductive (lazy) languages. And vice versa, in Haskell, top represents the entire universe that is available in our inductive (eager) languages, e.g. Ceylon, Java, Scala.
No one replied to my prior message, so I assume that made my logic clear?
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).