On Tuesday, 26 August 2014 02:55:25 UTC+2, Robert Bradshaw wrote: > > On Mon, Aug 25, 2014 at 5:19 PM, Bill Hart <goodwi...@googlemail.com > <javascript:>> wrote: > > > > > > On Tuesday, 26 August 2014 00:40:34 UTC+2, Robert Bradshaw wrote: > >> > >> On Mon, Aug 25, 2014 at 1:24 PM, Bill Hart <goodwi...@googlemail.com> > >> wrote: > >> > >> >> > Correct. But classes are essentially objects in Python because > >> >> > everything is > >> >> > an object, pretty much. This really muddies the water. Better to > >> >> > think > >> >> > of > >> >> > classes and objects as being separate concepts. > >> >> > >> >> I, for one, find it very convenient (especially compared to using > >> >> reflection and other hacks that are needed to reason about type at > >> >> runtime in C++ or Java). Not that some languages aren't even better. > >> >> > >> >> > Also better to think of ZZ as a class in Sage and elements of ZZ > as > >> >> > objects, > >> >> > even though actually ZZ happens to be an object too because > Python. > >> >> > >> >> No. ZZ is an object because you might want to do things with it, > like > >> >> ask for it's properties (is it infinite?) > >> > > >> > Sorry if I have that wrong. But when I type ZZ?? into Sage, it pulls > up > >> > the > >> > definition of a class. > >> > >> If a is an instance of class A, typing a?? will give you the definition > of > >> A. > > > > Ah thanks for pointing that out. I now see that 1 is an object of class > > Integer, whereas ZZ is an object of class Integer_ring. > > > > So where I spoke of ZZ in Sage, please substitute Integer. > > Well, some of the places you wrote ZZ at least, as you interchange the > two concepts quite a bit. That explains at least why you sounded so > confused. >
I wasn't really confused. Sage makes the distinction between the mathematical domain, the type and the values. I distinguish only types and values. Sage is not wrong, it's just a bit overcomplicated. And it would be naive to think it can push the carpet down at all the edges. > >> I think so; the Euclidean property doesn't place any constraint on the > >> morphisms. > > > > > > I should have asked whether Fields were. Some references say yes, some > no. > > > > It's also really funny that if you look up Category of Euclidean Domains > on > > the intertubes you get two types of pages in general. The first is Wiki > > articles that use the words category and subcategory in the common > speech > > sense, not in the mathematical sense. Then there is the Sage > documentation, > > which speaks of the Category of Euclidean Domains. > > > > As a concept, it just isn't that useful to category theorists > (apparently; I > > wouldn't know, I'm not a category theorist). > > > > My point is really that having a typeclass hierarchy that revolves > around > > category theory isn't necessarily useful. > > > > Euclidean rings (and more specifically Euclidean domains) are a > difficult > > concept to model in a type hierarchy, because it is not that easy to > tell > > when a ring is a Euclidean ring, and if so, what the Euclidean function > is > > on that ring. > > > > Also, the Euclidean function may only be used implicitly in any > algorithms > > used to compute a gcd. So the Euclidean function is not that useful. And > > there may be more than one Euclidean structure on a ring, e.g. Z/nZ for > n > > composite. > > > > The upshot of this is that whether or not a ring has a Euclidean > function > > defined on it is probably not something you want to represent in an > > "interface". Thus, it is not that useful a concept when defining a > typeclass > > or interface for types to belong to. > > > > You could make your interface depend on whether there is a gcd function. > But > > such a function could just return an ideal, for example in a Dedekind > domain > > (Sage even does this; inconsistently). So whether there is a gcd > function is > > neither here nor there. > > > > So I would argue right from the outset that EuclideanDomain is neither a > > useful concept category theory-wise, nor computationally. > > > > Note that there is no EuclideanDomain typeclass currently in Nemo (I > know I > > did provide it in my big long list of typeclasses that could be added). > > > >> > >> I am still curious how you would express that > >> UnivariatePolynomialRing{QQ} <: EuclideanDomans but the same doesn't > >> hold for UnivariatePolynomialRing{ZZ} in Julia. > > > > > > You wouldn't do this. But suppose you would. > > > > You might have: > > > > abstract Ring > > abstract EuclideanDomain <: Ring > > > > type Poly{T <: Ring} <: Ring > > # blah blah > > end > > > > type EuclideanPoly{T <: Field} <: EuclideanDomain > > # more blah blah > > end > > > > The type construction function PolynomialRing can then be written such > > > > PolynomialRing{T <: Ring}(::Type{T}, S::string) # this is the generic > > function which gets called if T is a ring but not a field > > # return a Poly > > end > > > > PolynomialRing{T <: Field}(::Type{T}, S::string) # this function > specialises > > the previous one, when T happens to be a field > > # return a EuclideanPoly > > end > > > > There are various ways you could handle functions that take either an > > EuclideanPoly or a Poly. For example > > > > myfun(a :: Union(EuclideanPoly, Poly)) > > > > or > > > > typealias AnyPoly Union(EuclideanPoly, Poly) > > > > myfun(a :: AnyPoly) > > > > And there are various ways you could handle functions that take elements > of > > a EuclideanDomain or a general Ring. E.g. > > > > myfun{T <: EuclideanDomain}(a :: T) > > > > myfun{T <: Ring}(a :: T) > > > > But I don't think there is any compelling reason to go to all of this > > trouble. A much better and cleaner way is the following. > > > > abstract Ring > > > > type Poly{T <: Ring} <: Ring > > # blah blah > > end > > > > abstract GCDDomain <: Ring > > abstract Field <: GCDDomain # it's questionable whether you really want > to > > do this instead of Field <: Ring, but that's another story > > > > typealias EuclideanDomain{T <: Field} Union(GCDDomain, Poly{T}) > > So is this Union type extensible, e.g. if I had a third type that was > also a EuclideanDomain but neither a GCDDomain nor a Poly{T}, could I > add it in later? Or mus they all be enumerated upfront? > It is immutable. So adding new types to the union at runtime is right out. Just the same as adding new integers to the Int type is also somewhat forbidden. I defined a type called RobertType then tried: julia> EuclideanDomain.body = Union(Poly,Field,ZZ,RobertType) ERROR: type TypeConstructor is immutable Boom. Capital letters. You really shouldn't have done that! But there is a way, if you really want the ability to change it at runtime. abstract Ring type ZZ <: Ring end type Poly{T <: Ring} <: Ring #blah end abstract Field <: Ring type QQ <: Field end EuclideanDomain = eval(:(typealias $(gensym()){T <: Field} Union(Field, Poly{T}, ZZ))) type Robert <: Ring end Robert <: EuclideanDomain Field <: EuclideanDomain Ring <: EuclideanDomain ZZ <: EuclideanDomain QQ <: EuclideanDomain Poly{ZZ} <: EuclideanDomain Poly{QQ} <: EuclideanDomain EuclideanDomain = eval(:(typealias $(gensym()){T <: Field} Union(Field, Poly{T}, ZZ, Robert))) Field <: EuclideanDomain Ring <: EuclideanDomain ZZ <: EuclideanDomain QQ <: EuclideanDomain Poly{ZZ} <: EuclideanDomain Poly{QQ} <: EuclideanDomain Robert <: EuclideanDomain I know, I know, it's an EVIL hack. But I bet I can find evil hacks in Sage too. And if I were really going to do this in practice I'd write a macro to handle the evil, so it'd be @registertype EuclideanDomain Robert I'm sure there are much better solutions to this problem. At present things don't require this to be solved. In Nemo it just tells you no gcd function is available for your type and gives you a line number in the source. That's pretty much what you want it to do anyway. Admittedly it would be nice if it told you this as soon as you called the function, rather than the first time it encounted the gcd call in the code. But if you want that kind of type safety you don't want a dynamic language. > I do have to admit I was hoping for something a bit more elegant... > A way might exist. I don't know it at the moment. Python has union types too (multiple inheritance with an empty body, > though yes the mix of interface and implementation makes that messy). > > A more concrete example is Z/nZ for n composite or prime. What is the > type hierarchy for 3 in Z/5Z? In Z/10Z? In Nemo, 3 doesn't belong to Z/nZ. If R = Z/5Z then R(3) is an element of Z/5Z. The type of R(3) is basically Residue{ZZ, 5}. > Do you have values for Z/nZ, > or is Z/nZ just a parameterized type (the way ZZ is the time of 3 \in > Z)? > I use a parameterised type for Z/nZ, namely Residue{R, d} where R <: Ring and d :: R. > > > function myfun{T <: EuclideanDomain}(a :: T) > > # blah > > end > > > > This lot all compiles by the way. And you can check it really works: > > > > First define a type which belongs to Field: > > > > type Bill <: Field > > end > > > > julia> myfun(Bill()) > > > > julia> myfun(Poly{Bill}()) > > > > No complaints. > > > > Now define a type which is not a field, but just a ring: > > > > type Fred <: Ring > > end > > > > And then: > > > > julia> myfun(Poly{Fred}()) > > ERROR: `myfun` has no method matching myfun(::Poly{Fred}) > > > > julia> myfun(Fred()) > > ERROR: `myfun` has no method matching myfun(::Fred) > > > > However, in all of the above, you see that I never actually used > GCDDomain > > at all. So it can really be removed if so desired. It's likely you > defined a > > gcd function for some clean set of rings in the first place, which can > all > > be delineated nicely without having some special typeclass for it. > > > > And then, in reality, EuclideanDomain is just a union of various types, > just > > as the particular rings you can define a gcd function for is an eclectic > > mix, with no particular rhyme or reason to it. > > > >> > >> >> (As > >> >> you mention, trying to use the type hierarchy in Python to model > >> >> categorical relationships in Sage has generally lead to pain which > is > >> >> why we're moving away from that...) > >> > > >> > Oh I can't think why. > >> > >> I buy that the type system is more powerful in Julia (yay), but I'm > >> still skeptical that it is the best way to express the relationship > >> between objects and categories, and at the same time elements and > >> objects, and attach useful information to those categories and > >> objects. > > > > > > That was kind of the point of my earlier post. There is no such best > way. > > Categories don't match any concept in computer science (well, that is > not > > strictly true, but that's a long diversion into n-categories and > homotopy > > types). Usually we can't push the carpet down around all the corners of > the > > room, but we can get it sufficiently flat locally. > > Yet you seem to be trying to tie the two together. Or is your point > that Nemo gives you a sufficiently strong type system that the locally > flat place is as big as needed? > Sure, I only plan to handle groups, rings, fields in Nemo at this point. It's a flint interpreter after all. At the moment I only have Field <: Ring at the typeclass level. At the level of types I have ResidueRing, PolynomialRing, PowerSeriesRing, ZZ which all belong to Ring, and FractionField, QQ, FiniteField which all belong to Field. If something needs a gcd and there isn't one, it currently just tells you there's no gcd. But Nemo has a gcd in more rings than just EuclideanDomains, same as Sage. For example, it allows you to take gcds in Z/nZ or of polys over ZZ or polys over Z/nZ and so on. So checking whether you have a polynomial over a field isn't so useful, actually. If I wanted to know if a given ring was a Euclidean domain or not, I could write a generic: is_euclidean_domain{T <: Field}(::Type{Poly{T}}) = true is_euclidean_domain(ZZ) = true is_euclidean_domain{T <: Field}(::Type{T}) = true I could also add: is_euclidean_domain{T <: Ring)(::Type{Poly{T}}) = false is_euclidean_domain{T <: Ring}(::Type{R}) = false but that's probably not really useful, since some rings that are not ZZ, polynomials over fields or fields are still Euclidean domains. And there's just no easy way to tell which. Bill. > - Robert > -- You received this message because you are subscribed to the Google Groups "sage-devel" group. To unsubscribe from this group and stop receiving emails from it, send an email to sage-devel+unsubscr...@googlegroups.com. To post to this group, send email to sage-devel@googlegroups.com. Visit this group at http://groups.google.com/group/sage-devel. For more options, visit https://groups.google.com/d/optout.