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.

Reply via email to