On Monday, 25 August 2014 09:48:12 UTC+2, Pierre wrote: > > > A <: B either tells you if a type A is of abstract type B or if abstract > type A is of abstract type B. >> >> >> So, whether or not you use RingElement or Ring depends on whether you >> consider an element of ZZ to be a ring element or whether you think the >> integers ZZ form a ring. >> >> With the machine types, we really want a :: T where T <: Integer <: Ring. >> Again with the baremodule idea, we might be able to do this, but it's not >> possible if you use the standard provided modules, as far as I can tell. >> > > I guess to me the only names that would really make sense would be > ZZElement <: RREelement <: RingElement (or else rename the builtin types to > something else: it's "Integer" that's not the same of a set!! Rename it > Integers and everything makes sense). Anyway, I probably need to learn to > think differently about this. >
Integer is an abstract type in Julia. For example, Int <: Integer. Int is a concrete type (actually, it's a typealias for either the concrete type Int32 or Int64, depending on what sort of computer you have). Note it's not IntElement! And Integer is not a concrete type, despite Integer being the name of an element of the ring of Integers. There is no Integers in Julia. You are probably being confused by the fact that the <: notation in Julia can be used with either concrete types or abstract types on both sides. This is to prevent needing Level 1: values Level 2: types Level 3: typeclasses Level 4: typesuperclasses Level 5: typesupersuperclasses Level 6: typesupersupersuperclasses ... etc. All types, no matter what level in Julia are just DataType's. It's just that some can be instantiated and some are just abstract. The abstract ones serve the purpose of typeclasses, mostly. But they can be arbitrary levels in your hierarchy. It's up to you what interpretation you put on your abstract types. The only thing that can't go on the left side of <: is an actual value, like 1. (There's an argument that it should be possible since types can be parameterised on Int's, but that's another story.) > I do wonder about one thing. Since it is not possible in Julia to have > instances of abstract types, and you have ZZ <: RR with the possibility of > doing ZZ(3) as well as RR(3), does it mean that you've created > supplementary concrete types, say ZZ_concrete <: ZZ and RR_concrete <: RR > or similar, together with a bunch of constructors to hide everything? > ZZ is not an abstract type. It's a concrete type. Concrete doesn't mean system defined. It means it has values. A ZZ in Nemo is nothing more and nothing less than a flint fmpz_t integer. So it is very concrete. I could very easily have called it fmpz_t if I wanted. I'd have used Integer to name the type, actually, but that was already taken. As was Int, BigInt and numerous other things. So ZZ was what I decided to use. I used ZZ because fundamentally, a type is a set of values. ZZ is the name of a set of values. Int is the name of a set of values. It's just a name. I used the first sensible name that popped into my head. Sage uses ZZ for the same purpose roughly, though in Sage there is supposedly a separation between types and mathematical domains. And ZZ is technically a mathematical domain (called a parent in Sage) which has an underlying representation whose values have types. Aldor is another language that conceptually distinguises mathematical domains from their representations. On the other hand, you can think of ZZ as being blackboard bold Z, and Z stands for Zahl (number) in German. There is no RR type in Nemo yet. But it can just as well stand for Real if you want, instead of Reals. After all Real is already used for the name of a typeclass in Julia. > If so, I find this quite complicated. Here good old OOP treats this much > more elegantly. But perhaps I am mistaken? > How can you even express traits elegantly in good old OOP? It's a template metaprogramming nightmare in C++! You have to model traits yourself in Python. In fact, name one "good old OOP" language that supports traits smoothly. Maybe Scala? Good luck fighting with the type checker though. Now I will admit that after you first brought this up, I have begun to think that FField should be FFElem. This comes about because we don't have a special name for an element of a finite field, like Polynomial for an element of a Polynomial Ring, or Integer for an element of the ring of Integers or Real Number for an element of the Reals. I might change that one. But this has nothing to do with how elegant Julia is or how smooth it's OOP paradigm is. It's just a name I made up. I could have called it anything, including Fred! And given that I was essentially forced to use ZZ instead of my preferred Integer for a bigint, I think there is no great harm done in using FField instead of FFElem. It's just a name. I certainly won't be changing Ring to RingElement. That would be wrong. Ring is a typeclass, as is Field. Think of it as an interface or trait in other parlance. Roughly speaking, a typeclass is a collection of types. But the name doesn't have to reflect that. It just has to convey some meaning. And Ring does that perfectly well. T <: Ring conveys that T is a type that belongs to the Ring typeclass, i.e. it notionally implements the interface required for doing ring operations. So in Nemo we will have Level 1: (values) 1, 1/2, x^2 + x + 1, etc Level 2: (types) ZZ, QQ, Fraction, Residue, FFElem, Poly, PowerSeries Level 3: (typeclasses) Ring, Field So typically function signatures will look like fnname{T <: Z}(a :: T) where we have: a is a value T is a type Z is a typeclass Of course nothing is stopping us having more levels in the hierarchy, e.g. Field <: EuclideanDomain <: PID <: UFD <: IntegralDomain <: CommutativeRing <: Ring I'd really like to see that done in standard OOP. I don't think it can be even remotely done smoothly. In Julia it is this simple abstract Ring abstract CommutativeRing <: Ring abstract IntegralDomain <: CommutativeRing abstract UniqueFactorisationDomain <: IntegralDomain abstract PrincipalIdealDomain <: UniqueFactorisationDomain abstract EuclideanDomain <: PrincipalIdealDomain abstract Field <: EuclideanDomain And then I can even do abstract EuclideanRing <: CommutativeRing if I want. Bill. > > Pierre > > > > > > -- 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.