Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-29 Thread Bill Hart


On Thursday, 28 August 2014 16:48:31 UTC+2, R. Fourquet wrote:

  Sorry, I had some errors in this next bit. 

  myfun(a :: Union(EuclideanPoly, Poly)) 

  It should have been 
  myfun{T : Union(EuclideanPoly, Poly)}(a :: T) 

 The first version is perfectly ok and more idiomatic in this case. You 
 said earlier: 

  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 

 Function signatures typically look like this only when T (a type 
 variable) is used in the function definition, e.g. 
 myfun{T}(::Poly{T}) = T 

 or to constrain argument types, e.g. 
 myfun{T}(a::Poly{T}, b::Poly{T}) = a+b # a and b must be Polys of the same 
 type 

 or to constrain the type variable, e.g. 
 myfun{T:Field}(a::Poly{T}) = 1/coeff(a)[1] # method of myfun working 
 only with Polys over fields (and myfun(a::Poly{:Field}) is 
 envisioned) 

 Otherwise, fname(a :: Z) is the way, even if Z is abstract 
 (typeclass). And even then, the concrete type of a can be referred 
 to via typeof(a). And fname will be compiled separately for each 
 concrete type it is called on. 


Thanks very much for pointing that out. I was not aware of this trick! 

-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-29 Thread Bill Hart


On Thursday, 28 August 2014 18:13:10 UTC+2, R. Fourquet wrote:

  or to constrain argument types, e.g. 
  myfun{T}(a::Poly{T}, b::Poly{T}) = a+b # a and b must be Polys of the 
 same type 
 which is better expressed as : 

 myfun{P:Poly}(a::P, b::P) = a+b 


Thanks. I've figured this one out since.

In my code I actually have

myfun{T : Ring}(a::Poly{T}, b::Poly{T})

a lot. Is there a shorthand for this?
 


 So a better example: 

 myfun{T}(a::Poly{T}, b::Monomial{T}) = ... 


-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-29 Thread Rafael Fourquet
 In my code I actually have

 myfun{T : Ring}(a::Poly{T}, b::Poly{T})

 a lot. Is there a shorthand for this?

I don't think so. According to
https://github.com/JuliaLang/julia/issues/6984, it may be possible to
have the following in the future:

myfun{P:Poly{:Ring}}(a::P, b::P)

-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-28 Thread Rafael Fourquet
 Sorry, I had some errors in this next bit.

 myfun(a :: Union(EuclideanPoly, Poly))

 It should have been
 myfun{T : Union(EuclideanPoly, Poly)}(a :: T)

The first version is perfectly ok and more idiomatic in this case. You
said earlier:

 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

Function signatures typically look like this only when T (a type
variable) is used in the function definition, e.g.
myfun{T}(::Poly{T}) = T

or to constrain argument types, e.g.
myfun{T}(a::Poly{T}, b::Poly{T}) = a+b # a and b must be Polys of the same type

or to constrain the type variable, e.g.
myfun{T:Field}(a::Poly{T}) = 1/coeff(a)[1] # method of myfun working
only with Polys over fields (and myfun(a::Poly{:Field}) is
envisioned)

Otherwise, fname(a :: Z) is the way, even if Z is abstract
(typeclass). And even then, the concrete type of a can be referred
to via typeof(a). And fname will be compiled separately for each
concrete type it is called on.

-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-28 Thread Rafael Fourquet
 or to constrain argument types, e.g.
 myfun{T}(a::Poly{T}, b::Poly{T}) = a+b # a and b must be Polys of the same 
 type
which is better expressed as :

myfun{P:Poly}(a::P, b::P) = a+b

So a better example:

myfun{T}(a::Poly{T}, b::Monomial{T}) = ...

-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Pierre
 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.

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?

If so, I find this quite complicated. Here good old OOP treats this much 
more elegantly. But perhaps I am mistaken?

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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


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 

[sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Pierre
Thanks again for the explanations. I realize that there were many things 
about Julia/Nemo which I had misunderstood. Let me explain a little, so I 
can (i) embarrass myself a little more, and (ii) perhaps give an indication 
of common mistakes, for anyone who would write a tutorial about Julia/Nemo 
:-)

Mistake (1): taking it for OOP. When hearing about the way Julia worked, I 
jumped when I saw it wasn't OO, and then naturally was looking for ways to 
emulate OOP with Julia (rather than make the effort of a paradigm shift). 
And with multi-dispatch, i thought OK, if I want to write code that applies 
to objects of type A, B and C at once, just declare them A : X, B : X and 
C : X and define f(x :: X). However this gave me the wrong intuition  A 
: X is the same as A inherits from X. 

At this point, the fact that abstract types could be instantiated was seen 
as a limitation compared to OOP. And somehow, it is. Except at the same 
time, the type system does many new things. Apples and oranges, really.

Mistake (2): taking types for sets. This little discussion about names 
reveals another mistake of mine: thinking of types as sets. I thought ZZ : 
QQ for example. That's not even consistent with the previous mistake. In 
Sage say, i'm guessing QQ is of type Field or something, which inherits 
from a type Ring or something -- but not the other way around! So mistake 
(1) should have led me to believe QQ : ZZ. Oh well. 

Mistake (3): thinking about Sage too much. To my discharge, ZZ in Sage is 
an object, like 1/2, not a type or anything. This has unconsciously 
contributed to my confusion greatly. Also the fact that there is a coercion 
from ZZ to QQ, and somewhere I must have taken A : B to mean there is a 
coercion from A to B.

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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Pierre


 At this point, the fact that abstract types could be instantiated was seen 
 as a limitation compared to OOP. And somehow, it is. Except at the same 
 time, the type system does many new things. 


typo : read could NOT be instantiated. 

-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Robert Bradshaw
On Mon, Aug 25, 2014 at 6:02 AM, Bill Hart goodwillh...@googlemail.com wrote:
 Hmm. Some more explaining is necessary.


 On Monday, 25 August 2014 12:04:16 UTC+2, Pierre wrote:

 Thanks again for the explanations. I realize that there were many things
 about Julia/Nemo which I had misunderstood. Let me explain a little, so I
 can (i) embarrass myself a little more, and (ii) perhaps give an indication
 of common mistakes, for anyone who would write a tutorial about Julia/Nemo
 :-)

 Mistake (1): taking it for OOP.


 Julia is OOP!

 There are two ways to do OOP. The first is with classes and usually single
 dispatch and the other is with multi-methods. The latter is the Julia way
 and it is more flexible.

 There is a dual notion for data structures as well, and Julia supports that
 too, giving even greater flexibility. The combination of the two is more
 powerful than standard OOP, which can be very restrictive in practice.


 When hearing about the way Julia worked, I jumped when I saw it wasn't OO,
 and then naturally was looking for ways to emulate OOP with Julia (rather
 than make the effort of a paradigm shift). And with multi-dispatch, i
 thought OK, if I want to write code that applies to objects of type A, B and
 C at once, just declare them A : X, B : X and C : X and define f(x :: X).
 However this gave me the wrong intuition  A : X is the same as A inherits
 from X.


 None of that makes sense.

 f(x :: X) is the way you write a function prototype in Julia. It corresponds
 to the following prototype in C.

 void f(X x);

 X is just a type, like int or float or double or MyType, etc. In Julia, you
 just write the type on the right, after a double colon, instead of on the
 left like C.

 A : X does not mean A is an object of type X. It means A is a subtype of X,
 where both A and X are types (one or both may be abstract types).

 The way to write A is an object of type X is A :: X.

 The way to write X is a subtype of Y is X : Y.

 But remember that subtype here *may* mean X is in the typeclass Y.


 At this point, the fact that abstract types could be instantiated was seen
 as a limitation compared to OOP.


 No. There is no similar concept in OOP, except for languages like scala
 which have traits/interfaces/typeclasses. It's an extension over and above
 what is found in standard OOP languages.

 You can also write all your Julia programs without any : symbols if you
 want. And in fact you can leave all types out too and let Julia figure them
 out.

 Types and subtyping simply allows you to restrict what is allowed. Otherwise
 everything is allowed, just like Python.


 And somehow, it is.


 No it is not. You never need to use the : notation in Julia if you don't
 want to. You can just stick to values (objects) and types (classes) if you
 want. Then you have the same thing as standard OOP. You can even restrict
 yourself to single dispatch if you want, in which case you have OOP exactly.
 But there's no reason to restrict yourself in this way, because Julia offers
 all the other goodies on top of that.


 Except at the same time, the type system does many new things. Apples and
 oranges, really.

 Mistake (2): taking types for sets.


 They sort of are. Formally a type is just a set of values. Well, not in a
 mathematical sense. But in some intuitive sense.

 Types of course satisfy some calculus just as sets do and the rules of the
 calculus are somewhat similar, but not quite the same. Technically dependent
 types correspond exactly to predicates in the predicate logic, via Type
 theory (an extension of the Curry-Howard isomorphism). But that's all a bit
 complicated, so we informally think of types as sets.

 One big difference is there are plenty of non-computable functions between
 sets. But the functions between types are always computable. But again, it's
 not even vaguely necessary to understand this to get the concept of a type.
 It's intuitively just a name given to the collection of all values which an
 object of that type can have.

 This little discussion about names reveals another mistake of mine:
 thinking of types as sets. I thought ZZ : QQ for example.


 Yeah, the : notation doesn't mean contained in. It's not a mathematical
 operator. It means subtype of. There are three things the notation can
 mean:

 1) If A : B where A and B are types, then it means that if a function can
 take an argument of type B, then an argument of type A will work just as
 well in its place. In some sense, the set of values of type A is a
 restriction of the set of values of type B. This is pretty close to a subset
 meaning though technically it has more to do with the representation in bits
 on the machine than anything mathematical.

 2) If A : B where A is a type and B is an abstract
 type/typeclass/interface/trait, it means that a function which requires a
 type in class B can take the type A. This is not a subset meaning. It means
 the type A belongs to the typeclass B.

 3) If A : B where A 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


On Monday, 25 August 2014 20:14:01 UTC+2, Robert Bradshaw wrote:

 On Mon, Aug 25, 2014 at 6:02 AM, Bill Hart goodwi...@googlemail.com 
 javascript: wrote: 
  Hmm. Some more explaining is necessary. 
  
  
  On Monday, 25 August 2014 12:04:16 UTC+2, Pierre wrote: 
  
  Thanks again for the explanations. I realize that there were many 
 things 
  about Julia/Nemo which I had misunderstood. Let me explain a little, so 
 I 
  can (i) embarrass myself a little more, and (ii) perhaps give an 
 indication 
  of common mistakes, for anyone who would write a tutorial about 
 Julia/Nemo 
  :-) 
  
  Mistake (1): taking it for OOP. 
  
  
  Julia is OOP! 
  
  There are two ways to do OOP. The first is with classes and usually 
 single 
  dispatch and the other is with multi-methods. The latter is the Julia 
 way 
  and it is more flexible. 
  
  There is a dual notion for data structures as well, and Julia supports 
 that 
  too, giving even greater flexibility. The combination of the two is more 
  powerful than standard OOP, which can be very restrictive in practice. 
  
  
  When hearing about the way Julia worked, I jumped when I saw it wasn't 
 OO, 
  and then naturally was looking for ways to emulate OOP with Julia 
 (rather 
  than make the effort of a paradigm shift). And with multi-dispatch, i 
  thought OK, if I want to write code that applies to objects of type A, 
 B and 
  C at once, just declare them A : X, B : X and C : X and define f(x 
 :: X). 
  However this gave me the wrong intuition  A : X is the same as A 
 inherits 
  from X. 
  
  
  None of that makes sense. 
  
  f(x :: X) is the way you write a function prototype in Julia. It 
 corresponds 
  to the following prototype in C. 
  
  void f(X x); 
  
  X is just a type, like int or float or double or MyType, etc. In Julia, 
 you 
  just write the type on the right, after a double colon, instead of on 
 the 
  left like C. 
  
  A : X does not mean A is an object of type X. It means A is a subtype 
 of X, 
  where both A and X are types (one or both may be abstract types). 
  
  The way to write A is an object of type X is A :: X. 
  
  The way to write X is a subtype of Y is X : Y. 
  
  But remember that subtype here *may* mean X is in the typeclass Y. 
  
  
  At this point, the fact that abstract types could be instantiated was 
 seen 
  as a limitation compared to OOP. 
  
  
  No. There is no similar concept in OOP, except for languages like scala 
  which have traits/interfaces/typeclasses. It's an extension over and 
 above 
  what is found in standard OOP languages. 
  
  You can also write all your Julia programs without any : symbols if you 
  want. And in fact you can leave all types out too and let Julia figure 
 them 
  out. 
  
  Types and subtyping simply allows you to restrict what is allowed. 
 Otherwise 
  everything is allowed, just like Python. 
  
  
  And somehow, it is. 
  
  
  No it is not. You never need to use the : notation in Julia if you 
 don't 
  want to. You can just stick to values (objects) and types (classes) if 
 you 
  want. Then you have the same thing as standard OOP. You can even 
 restrict 
  yourself to single dispatch if you want, in which case you have OOP 
 exactly. 
  But there's no reason to restrict yourself in this way, because Julia 
 offers 
  all the other goodies on top of that. 
  
  
  Except at the same time, the type system does many new things. Apples 
 and 
  oranges, really. 
  
  Mistake (2): taking types for sets. 
  
  
  They sort of are. Formally a type is just a set of values. Well, not in 
 a 
  mathematical sense. But in some intuitive sense. 
  
  Types of course satisfy some calculus just as sets do and the rules of 
 the 
  calculus are somewhat similar, but not quite the same. Technically 
 dependent 
  types correspond exactly to predicates in the predicate logic, via Type 
  theory (an extension of the Curry-Howard isomorphism). But that's all a 
 bit 
  complicated, so we informally think of types as sets. 
  
  One big difference is there are plenty of non-computable functions 
 between 
  sets. But the functions between types are always computable. But again, 
 it's 
  not even vaguely necessary to understand this to get the concept of a 
 type. 
  It's intuitively just a name given to the collection of all values which 
 an 
  object of that type can have. 
  
  This little discussion about names reveals another mistake of mine: 
  thinking of types as sets. I thought ZZ : QQ for example. 
  
  
  Yeah, the : notation doesn't mean contained in. It's not a mathematical 
  operator. It means subtype of. There are three things the notation can 
  mean: 
  
  1) If A : B where A and B are types, then it means that if a function 
 can 
  take an argument of type B, then an argument of type A will work just as 
  well in its place. In some sense, the set of values of type A is a 
  restriction of the set of values of type B. This is pretty close to a 
 subset 
  

[sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


On Monday, 25 August 2014 17:42:46 UTC+2, Pierre wrote:


 Julia is OOP!


 If it is, 


It is. 

how do you do the following in Julia: define a class (i'm using Python 
 parlance) Foo 


 type Foo
data1::T1
data2::T2
end

with some attributes,


is_infinite(::Type{Foo}) = yes
is_pierrian(::Type{Foo}) = no
 

 say if x is an instance of Foo it has an integer x.n ; and then define a 
 class Bar that inherits from Foo, that is, has all the attributes from Foo, 
 and some more, for example if y is an instance of Bar it has y.n because it 
 is an instance of Foo, and say it also has a string y.name. In python

 class Foo:
 n= 0

 class Bar(Foo):
 name= 


Tongue-in-cheek solution:

abstract FooBar
 
type Foo : FooBar
end

type Bar : FooBar
end

n{T : FooBar}(::Type{T}) = 0

name(::Type{Bar}) = 

Though quite obviously the above is clearly not what you meant. 


 These classes don't even have methods, so it's not exactly complicated 
 OOP. Yet, I'm not sure how to do this (emulate this?) the Julia way. 
 Presumably, not with the : relation at all. I'm wondering how 
 multi-dispatch comes in, given there are no methods involved.


You want to be able to inherit fields, but that highlights the difference 
between Julia and the traditional OOP perspective. In the traditional 
perspective the focus is on the data. In the Julia paradigm, the focus is 
on the behaviour, i.e. the functions.

In a very well defined sense, functions and types are dual. Just as you can 
inherit structure in traditional OOP, you can inherit 
behaviour/functionality in the multimethod approach.

The key feature of Julia in this regard is the ability to add new methods 
to a generic function. So instead of classes and attributes becoming the 
focus of inheritance, in Julia, Generic functions and their (multi)methods 
become the focus.

The Julia authors claim that this is more flexible than traditional OOP. A 
lot of the real world restrictions of OOP come from their servitude to the 
structure inheritance paradigm.

So in short, if you want to write bad Python or C++ in Julia, you can't. 
But you also can't write good Julia in Python or C++.

In order to see why the other approach to OOP is not a restriction, you 
have to go back to what you were trying to model in the first place.

You have in mind something like this:

A real world thing, such as a Rectangle and inheriting from it a 
ColouredRectangle.

Perhaps the Rectangles are part of a windowing system, and as such any 
object of type Rectangle (I will avoid using the word class because it may 
be confused with typeclass, which has nothing to do with the concept of a 
class) will have a width and length and any object of type 
ColouredRectangle has the same fields as Rectangle, but also has associated 
with it a colour.

So that describes the structure of Rectangles and ColouredRectangles.

Now I think about what behaviour I want.

I clearly want to be able to resize any rectangle. I also want to be able 
to compute the area of a rectangle. I'd like to be able to enquire what the 
current colour of a coloured rectangle is.

Oh and by the way, some time whilst this project is underway, Circles are 
invented. We want all the same behaviour for those too, according to 
management.

So in Julia:

abstract Shape 

abstract RecShape : Shape

type Rectangle : RecShape
   width::Int
   height::Int
end

type ColouredRectangle : RecShape
   width::Int
   height::Int
   colour::Int
end

function resize{T : RecShape}(a :: T, width :: Int, height :: Int)
   a.width = width
   a.height = height
end

getcolour(a::ColouredRectangle) = a.colour

Oh damn, just got the fax from management. They want Circles too. But 
Circles don't inherit the structure of rectangles at all. They don't even 
have sides! What to do?

abstract CircShape : Shape

type Circle : CircShape
   radius::Int
end

type ColouredCircle : CircShape
   radius::Int
   colour::Int
end

resize{T : CircShape}(a::T, radius::Int)
a.radius = radius
end

getcolour(a::ColouredCircle) = a.colour

Notice how I inherited the behaviour called resize between the different 
kinds of rectangles. But later, when a type came along with a different 
structure, I could still add to the same behaviour resize by adding another 
method to the generic function resize.

And I also didn't need to rewrite the function getcolour either. I only 
really needed to go back to the original definition and change it to

getcolour(a::Union(ColouredCircle, ColouredRectangle)) = a.colour

Or if there was multiple inheritance (Julia doesn't have it yet) I could 
add some more nodes in my abstract type graph so that there is 
ColouredShape : Shape. Then just have

getcolour{T : ColouredShape}(a::T) = a.colour
 
Now, one final observation will demonstrate why this is such a useful 
paradigm:

Most real world computer programs define *far* fewer classes than methods. 
The ability to inherit structure is not all that important. The ability to 
inherit 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Julien Puydt

Le 25/08/2014 23:26, Bill Hart a écrit :

You want to be able to inherit fields, but that highlights the difference
between Julia and the traditional OOP perspective. In the traditional
perspective the focus is on the data. In the Julia paradigm, the focus is
on the behaviour, i.e. the functions.


In the Eiffel language, when you define a class foo with a member 
variable bar, the api just says that bar has such-type -- only the 
class writer knows if it's a constant or a function returning the value 
after a computation.


Is that the same principle?

Snark on #sagemath

PS: it's off topic on that list, but I'm still glad following the 
discussion.


--
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Robert Bradshaw
On Mon, Aug 25, 2014 at 1:24 PM, Bill Hart goodwillh...@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.

 Anyway, it's irrelevant because Python.

 In Julia types are also able to be passed around as first class objects.
 Which means you can define multimethods which take types as parameters. I do
 this all the time in Nemo.

 So I can send a type to a function which gives me some properties of the
 type, if I so wish. I thought about adding properties like is_infinite to
 types in Nemo. But I found that I had been thinking the wrong way about
 things all along.

Good, because I was worried there for a minute you were praising Julia
for not treating types as first class objects.

 or use it as a parameter
 (e.g. the domain of a Map object). Sometimes the Objects (in the
 categorical sense) are more interesting than their elements.

 If you are a category theorist yes. Most mathematicians think categories are
 just sets.


 If your Objects are parameterized types,

 I'm curious how you handle in
 Julia the fact that R[x] is a Euclidean domain iff R is a field.

 I'm curious, is the category of Euclidean domains a full subcategory of
 Rings?

I think so; the Euclidean property doesn't place any constraint on the
morphisms.

I am still curious how you would express that
UnivariatePolynomialRing{QQ} : EuclideanDomans but the same doesn't
hold for UnivariatePolynomialRing{ZZ} in Julia.

 (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.

- 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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


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 
 javascript: 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.

(Except that I was using that as an argument for using ZZ as a name for my 
bignum integer type in Julia; which argument you have now destroyed. I 
would have liked to use Integer though. But it was already taken.)
 


  Anyway, it's irrelevant because Python. 
  
  In Julia types are also able to be passed around as first class objects. 
  Which means you can define multimethods which take types as parameters. 
 I do 
  this all the time in Nemo. 
  
  So I can send a type to a function which gives me some properties of the 
  type, if I so wish. I thought about adding properties like is_infinite 
 to 
  types in Nemo. But I found that I had been thinking the wrong way about 
  things all along. 

 Good, because I was worried there for a minute you were praising Julia 
 for not treating types as first class objects. 


Nah. But I don't have anything against not making types first class 
objects. So long as their constructors are.

It also depends somewhat on your definition of first class.
 


  or use it as a parameter 
  (e.g. the domain of a Map object). Sometimes the Objects (in the 
  categorical sense) are more interesting than their elements. 
  
  If you are a category theorist yes. Most mathematicians think categories 
 are 
  just sets. 
  
  
  If your Objects are parameterized types, 
  
  I'm curious how you handle in 
  Julia the fact that R[x] is a Euclidean domain iff R is a field. 
  
  I'm curious, is the category of Euclidean domains a full subcategory of 
  Rings? 

 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 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


On Tuesday, 26 August 2014 02:19:25 UTC+2, Bill Hart 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.

 (Except that I was using that as an argument for using ZZ as a name for my 
 bignum integer type in Julia; which argument you have now destroyed. I 
 would have liked to use Integer though. But it was already taken.)
  


  Anyway, it's irrelevant because Python. 
  
  In Julia types are also able to be passed around as first class 
 objects. 
  Which means you can define multimethods which take types as parameters. 
 I do 
  this all the time in Nemo. 
  
  So I can send a type to a function which gives me some properties of 
 the 
  type, if I so wish. I thought about adding properties like is_infinite 
 to 
  types in Nemo. But I found that I had been thinking the wrong way about 
  things all along. 

 Good, because I was worried there for a minute you were praising Julia 
 for not treating types as first class objects. 


 Nah. But I don't have anything against not making types first class 
 objects. So long as their constructors are.

 It also depends somewhat on your definition of first class.
  


  or use it as a parameter 
  (e.g. the domain of a Map object). Sometimes the Objects (in the 
  categorical sense) are more interesting than their elements. 
  
  If you are a category theorist yes. Most mathematicians think 
 categories are 
  just sets. 
  
  
  If your Objects are parameterized types, 
  
  I'm curious how you handle in 
  Julia the fact that R[x] is a Euclidean domain iff R is a field. 
  
  I'm curious, is the category of Euclidean domains a full subcategory of 
  Rings? 

 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} : 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart
Stoopid google. 

On Tuesday, 26 August 2014 02:48:11 UTC+2, Bill Hart wrote:

 I am still curious how you would express that 
 UnivariatePolynomialRing{QQ} : EuclideanDomans but the same doesn't 
 hold for UnivariatePolynomialRing{ZZ} in Julia. 

  
So it doesn't get lost in all that noise. Here is an actual Julia session 
expressing this:

julia abstract Ring

julia type ZZ : Ring
   end

julia type Poly{T : Ring} : Ring
  #blah
   end

julia abstract Field : Ring

julia type QQ : Field
   end

julia typealias EuclideanDomain{T : Field} Union(Field, Poly{T}, ZZ)
Union(Poly{T:Field},Field,ZZ)

With all that defined, here is what Julia replies in response to various 
questions about this:

julia Field : EuclideanDomain
true

julia Ring : EuclideanDomain
false

julia ZZ : EuclideanDomain
true

julia QQ : EuclideanDomain
true

julia Poly{ZZ} : EuclideanDomain
false

julia Poly{QQ} : EuclideanDomain
true

-- 
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.


Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Robert Bradshaw
On Mon, Aug 25, 2014 at 5:19 PM, Bill Hart goodwillh...@googlemail.com 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 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 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart


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 

Re: [sage-devel] Re: On scientific computing, Python and Julia

2014-08-25 Thread Bill Hart
Oh how very silly of me. As soon as I pressed enter I figured out the right 
way to do this.

abstract Ring
abstract EuclideanDomain : Ring
abstract Field : EuclideanDomain

type Poly{T : Ring} : Ring
end

type ZZ : EuclideanDomain
end

type QQ : Field
end

PolynomialRing{T : Ring}(::Type{T}) = Poly{T}

function PolynomialRing{T : Field}(::Type{T})
   R = Poly{T}
   R.super = EuclideanDomain
   return R
end

So with those definitions, here is the result:

julia R = PolynomialRing(ZZ)
Poly{ZZ} (constructor with 1 method)

julia R : EuclideanDomain
false

julia S = PolynomialRing(QQ)
Poly{QQ} (constructor with 1 method)

julia S : EuclideanDomain
true

julia ZZ : EuclideanDomain
true

julia QQ : EuclideanDomain
true

julia type Robert : EuclideanDomain
   end

julia Robert : EuclideanDomain
true

This is so elegant I can actually use it in Nemo. Great!

Bill.


-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart
As evidence of my claims that Julia is technically capable of doing generic 
programming faster than you can do it in C, I offer Fateman benchmark times 
for various systems.

Julia 0.3 was released today and gives a nice speedup over 0.2, hence the 
better times for Julia.

Fateman benchmark

Magma: 247s
Pari/GP: 161s
Sage: 135 s
Bland (generic C + flint): 42s
Nemo (Julia 0.3 + flint): 36s

The Fateman benchmark for us is to precompute f = 1 + x + y + z + t; p = 
f^30; and then to time p*(p + 1);

Whilst you can compute the Fateman benchmark faster than this with a 
special bignum structure and sparse distributed format for the polynomials, 
the point here is that the generic C version in Bland and the Julia version 
in Nemo both use flint's fmpz integer type, recursive dense format (!) and 
the same algorithms.

Another benchmark, called the Pearce benchmark, which computes f = (x + y + 
2z^2 + 3t^3 + 5u^5 + 1)^16; g = (u + t + 2z^2 + 3y^3 + 5x^5 + 1)^16; and 
then times f*g; dropped from 90s down to 72s. This is a sparse benchmark, 
but we are just using recursive dense representation.

I claim it's possible for Julia to do better still. And I'm sure we'll see 
that in a later release.

Bill.

On Friday, 22 August 2014 02:12:04 UTC+2, Bill Hart wrote:

 I just found time to actually read the links posted by the OP on Graydon 
 Hoare's history of programming language development, culminating in Julia.

 Oh I wish I could write like that! The guy is clearly a genius of immense 
 proportions. 

 I truly, truly wish that the computer algebra and number theoretic 
 communities were engaging people like this and leveraging their insight and 
 vision to the fullest.

 Bill.

 On Friday, 22 August 2014 01:19:22 UTC+2, Bill Hart wrote:

 Another thing that I think is terribly important is that the entire 
 technology stack, LLVM, all its libraries and packages, its console, the 
 IJulia web interface and Julia itself, all work out of the box on Windows 
 64, natively, not as a Cygwin app (they use MinGW64/MSYS2 to build Julia).

 And I've personally verified this. After some initial troubles due to the 
 fact that flint.dll is not built correctly on Windows 64, Nemo works 
 perfectly on Windows and from the IJulia interface running on my local 
 Windows 64 machine.

 This doesn't solve any problems for Sage, as many mathematical libraries 
 still don't natively support Windows 64 despite it being a decade old. But 
 it is a significant feature of Julia (and of the Nemo project I am writing 
 with Julia).

 Bill.
  
 On Friday, 22 August 2014 00:26:23 UTC+2, Bill Hart wrote:



 On Friday, 22 August 2014 00:08:20 UTC+2, Bill Hart wrote:



 My cursory look into Julia only poped out JIT stuff, not a real 
 complier... 


 Static compilation is coming to Julia. But not because it will speed 
 things up. It already has all the speed of an optimising compiler at the 
 console, as you type!


 I should qualify that. Technically, jit compilation and type inference 
 begin at the function boundary in Julia. So stuff you type at the top level 
 is not optimised. I think that is a mistake, as it's unnecessary. In the 
 language I was working on (using LLVM) type inference and optimisation 
 begin at the top level (which for me is a function). There is a small 
 runtime hit with global variables, but that is all.

 In particular, in the language I was working on, loops at the top level 
 are jit compiled. In Julia they are not. But it's almost irrelevant, except 
 when doing timing experiments to see how fast Julia really goes. You might 
 easily think to type a loop into the top level and time it and wonder what 
 all the fuss is about. Put that loop inside a function and you'll soon see.

 julia function sumit(n::Int)
   s = 0
   for i = 1:n
 s += i
   end
   return s
end
 sumit (generic function with 1 method)

 julia @time sumit(10)
 elapsed time: 0.913325036 seconds (78060 bytes allocated)
 55

 Bill.



-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Pierre
I thought we would have another argument about real numbers this morning, 
but I see the topic has changed back to Julia. And I have to say that I 
find the Nemo project very interesting, in spite of the over-aggressive 
publicity it is receiving here.

You don't often get to see a new piece of software in its infancy, with the 
opportunity to request features from the developpers so early on. So here's 
a suggestion for Bill Hart; you write:

Nemo is Julia, in the same way as Sage is Python

I'm not sure if I fully understand this, but I'm afraid I do. And I don't 
think it's a good decision. Let me explain.

I'm very jealous of some colleagues in numerical analysis here at my 
university whose ecosystem is ipython+numpy+matplotlib (pretty much, i may 
forget something). All three can be installed with easy_install at the 
prompt; it's modular (don't load matplotlib if you don't plan to plot); 
it's lightweight.

why shouldn't nemo by a Julia module that people load explicitly?

There are many good reasons why Sage cannot just be a module for Python. 
However I remember conversations in this forum years ago when people were 
musing about how great it would be if, by some miracle, Sage could indeed 
be a (collection of) module(s): it would be so simple and healthy. (Wasn't 
the Purple Sage project started with this simplicity in mind?) And it 
would be much easier to explain to people what Sage is. This may be a minor 
point, but if you've followed the conversation on reddit a few hours ago:

http://www.reddit.com/r/math/comments/2e3qla/william_stein_says_sage_has_overall_failed/

then you will see how many misconceptions people have about Sage, and how 
scary the technology appears to some.

Again there are very good reasons why Sage is what it is, but I see no 
reason why Nemo should be compelled to take over Julia like Sage has had to 
take over Python. You even say that no preparsing is needed! I'm not sure 
if, for example, you want to insist that integer constants be interpreted 
automatically as elements of ZZ. It seems to me a minor nuisance to have to 
write a few extra ZZ's, if in exchange the system can be that much simpler. 
I'm wondering what other people think.

Oh, and I ain't trying Nemo myself until installation is along the lines of 
julia --easy_install nemo, sorry... I would love to try it on 
SageMathCloud if it's available.

best,
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart


On Friday, 22 August 2014 11:49:20 UTC+2, Pierre wrote:

 I thought we would have another argument about real numbers this morning, 
 but I see the topic has changed back to Julia. And I have to say that I 
 find the Nemo project very interesting, in spite of the over-aggressive 
 publicity it is receiving here.


I wasn't going to mention it here at all. But I decided that on the tail 
end of a very long thread it wouldn't hurt much. It seems like a lot more 
people were reading the thread than I thought.

I don't intend to plug Nemo on sage-devel!
 


 You don't often get to see a new piece of software in its infancy, with 
 the opportunity to request features from the developpers so early on. So 
 here's a suggestion for Bill Hart; you write:

 Nemo is Julia, in the same way as Sage is Python

 I'm not sure if I fully understand this, but I'm afraid I do. And I don't 
 think it's a good decision. Let me explain.

 I'm very jealous of some colleagues in numerical analysis here at my 
 university whose ecosystem is ipython+numpy+matplotlib (pretty much, i may 
 forget something). All three can be installed with easy_install at the 
 prompt; it's modular (don't load matplotlib if you don't plan to plot); 
 it's lightweight.

 why shouldn't nemo by a Julia module that people load explicitly?


At the moment this is possible. But the bignum issue is really too much 
inconsistency for me. It's not just that, but the way the operators are 
defined on the Int's is also not what an algebraist wants. 1/2 returns 0.5 
instead of 1/2. And  div(7//2, 1//3) returns 10. Go figure.

You can't have consistent computer algebra when small integer literals 
behave differently to bigger ones. It just doesn't work.

This will be an issue when it comes to p-adics for example:

a = 1 + 2*65537 + 3^65537^2 + 11*65537^3 + 13*65537^4 + 12345*65537^5 + 
O(65537^6) will return who knows what. Certainly not what you entered.

Factorisations of number a = 
2*3*5^2*17*71*65537*123456543234565433489*3249861239487619238746032103420132947612384712340813246341
 
will return who knows what. Certainly not what you entered.

This is just not a tolerable situation for computer algebra. So alas, the 
input has to be changed to bignum by default.
 
It's also a pain in the neck to take output from one system, such as 
Pari/GP and cut and paste a long polynomial, having to put ZZ(...) around 
every bignum. It's just not practical.


 There are many good reasons why Sage cannot just be a module for Python. 
 However I remember conversations in this forum years ago when people were 
 musing about how great it would be if, by some miracle, Sage could indeed 
 be a (collection of) module(s): it would be so simple and healthy. (Wasn't 
 the Purple Sage project started with this simplicity in mind?) And it 
 would be much easier to explain to people what Sage is. This may be a minor 
 point, but if you've followed the conversation on reddit a few hours ago:


 http://www.reddit.com/r/math/comments/2e3qla/william_stein_says_sage_has_overall_failed/


I did.
 



 then you will see how many misconceptions people have about Sage, and how 
 scary the technology appears to some.

 Again there are very good reasons why Sage is what it is, but I see no 
 reason why Nemo should be compelled to take over Julia like Sage has had to 
 take over Python. You even say that no preparsing is needed! I'm not sure 
 if, for example, you want to insist that integer constants be interpreted 
 automatically as elements of ZZ. It seems to me a minor nuisance to have to 
 write a few extra ZZ's, if in exchange the system can be that much simpler. 
 I'm wondering what other people think.


I wish it were that simple. It might be possible to have Julia load in 
bare-module mode and still make Nemo available as a Julia Pkg though. I'll 
talk to the Julia developers about it. It would certainly be great if that 
were possible.
 


 Oh, and I ain't trying Nemo myself until installation is along the lines 
 of julia --easy_install nemo, sorry... I would love to try it on 
 SageMathCloud if it's available.


Yeah me too.

Bill.
 


 best,
 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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Pierre
Thanks for the examples. However, given that in Julia you can re-define 
about everything (cf your example with the function extracting elements 
from a list, replaced by  print 'test' ), surely you could change, say, 
the behaviour of the function / upon loading the Nemo module? (without 
mention of a bare-module mode or anything) This in order to make the 
ordinary machine words behave consistently in comparison with bignums. 
(There would be the occasional problem when someone has written code 
speciafically expecting a/b to be a float, but will you ever mix code 
involving floats with your own ?) This would be the exact reverse of the 
from __future__ import division which you see at the beginning of so many 
python+numpy scripts.

I don't think the factorization of a = 
2*3*5^2*17*71*65537*123456543234565433489*3249861239487619238746032103420132947612384712340813246341
 
is a good example. You can expect the user to known that this will fail, 
and wrap things in ZZ. (Do not underestimate the users: there are zillions 
of casual C programmers out there who realize that int is not the same as 
double; understanding the difference between Int64 and ZZ is no harder.) 
Of course Python or Sage users don't have to worry about that. But isn't 
Julia about better performance at the cost of specifying types?

As for :

It's also a pain in the neck to take output from one system, such as 
Pari/GP and cut and paste a long polynomial, having to put ZZ(...) around 
every bignum. It's just not practical.

i tend to disagree. A little function parse_PARI(string) or whatever would 
be easy to write.

I also have an unrelated question, still about Nemo. I think in Julia's 
type system, when A : B, then the intuition is that elements of type A are 
also of type B, or am I wrong? Like elements of type Int64 are also of type 
Integer (or whatever it's called). If so, your supertype of ZZ should not 
be called Ring, but RingElement. For an element of ZZ is not a ring. Well, 
abstract types are not types, they are more like type classes, but still 
with the machine types the logic is as I've said.


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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart


On Friday, 22 August 2014 14:10:10 UTC+2, Pierre wrote:

 Thanks for the examples. However, given that in Julia you can re-define 
 about everything (cf your example with the function extracting elements 
 from a list, replaced by  print 'test' ), surely you could change, say, 
 the behaviour of the function / upon loading the Nemo module? (without 
 mention of a bare-module mode or anything) This in order to make the 
 ordinary machine words behave consistently in comparison with bignums. 
 (There would be the occasional problem when someone has written code 
 speciafically expecting a/b to be a float, but will you ever mix code 
 involving floats with your own ?) This would be the exact reverse of the 
 from __future__ import division which you see at the beginning of so many 
 python+numpy scripts.


You can redefine things that have already been defined, but it sometimes 
incurs a compiler warning. I will have to look into what can be done.
 


 I don't think the factorization of a = 
 2*3*5^2*17*71*65537*123456543234565433489*3249861239487619238746032103420132947612384712340813246341
  
 is a good example. You can expect the user to known that this will fail, 
 and wrap things in ZZ. (Do not underestimate the users: there are zillions 
 of casual C programmers out there who realize that int is not the same as 
 double; understanding the difference between Int64 and ZZ is no harder.) 
 Of course Python or Sage users don't have to worry about that. But isn't 
 Julia about better performance at the cost of specifying types?

 As for :

 It's also a pain in the neck to take output from one system, such as 
 Pari/GP and cut and paste a long polynomial, having to put ZZ(...) around 
 every bignum. It's just not practical.

 i tend to disagree. A little function parse_PARI(string) or whatever would 
 be easy to write.

 I also have an unrelated question, still about Nemo. I think in Julia's 
 type system, when A : B, then the intuition is that elements of type A are 
 also of type B, or am I wrong? Like elements of type Int64 are also of type 
 Integer (or whatever it's called). If so, your supertype of ZZ should not 
 be called Ring, but RingElement. For an element of ZZ is not a ring. Well, 
 abstract types are not types, they are more like type classes, but still 
 with the machine types the logic is as I've said.

 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.

The logic from my point of view is that a type is a collection of values, 
and as such Integer : Ring, not Integer : RingElement. But the 
distinction is arbitrary.

In the case of finite fields, I had an argument with myself about whether I 
should use FFElem or FField. I decided on the latter. I would have liked to 
use FiniteField, but this is the name I wanted to give to the function that 
constructs an FField type (what some people call a factory I think).

It's a shame that Julia allows a composite type and constructor to have the 
same name, but a bitstype and constructor can't have the same name and a 
factory and composite type cannot have the same name. Similarly a module 
name and the filename can be the same, but the module name and the main 
type it defines can't be.

Those are all things I would do differently in Julia. And perhaps some of 
these will change in a future release, who knows.

They are minor nuisances at best. And there are probably important reasons 
for those decisions. For example, if a type and factory could have the same 
name, there could be issues with overloading the dot operator for both. And 
that's something a lot of people seem to want Julia to do, so that they can 
write Python in Julia.

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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart
One interesting thing I should mention is that loading Julia in bare module 
mode and redefining all the basic operators and so on does not break all of 
Julia's libraries. They all continue to operate as normal.

This was quite a surprise to me when I first found out, but all those 
modules have to import Base themselves, and so as far as they are 
concerned, everything operates just as it would in normal Julia. 

The operators don't get redefined for everybody when those modules import 
Base, but they just get locally redefined for the modules that use them.

Maybe that's also the same with Python. I guess it must be. But it costs 
nothing, at least, in Julia.

On Friday, 22 August 2014 19:17:29 UTC+2, Bill Hart wrote:



 On Friday, 22 August 2014 14:10:10 UTC+2, Pierre wrote:

 Thanks for the examples. However, given that in Julia you can re-define 
 about everything (cf your example with the function extracting elements 
 from a list, replaced by  print 'test' ), surely you could change, say, 
 the behaviour of the function / upon loading the Nemo module? (without 
 mention of a bare-module mode or anything) This in order to make the 
 ordinary machine words behave consistently in comparison with bignums. 
 (There would be the occasional problem when someone has written code 
 speciafically expecting a/b to be a float, but will you ever mix code 
 involving floats with your own ?) This would be the exact reverse of the 
 from __future__ import division which you see at the beginning of so many 
 python+numpy scripts.


 You can redefine things that have already been defined, but it sometimes 
 incurs a compiler warning. I will have to look into what can be done.
  


 I don't think the factorization of a = 
 2*3*5^2*17*71*65537*123456543234565433489*3249861239487619238746032103420132947612384712340813246341
  
 is a good example. You can expect the user to known that this will fail, 
 and wrap things in ZZ. (Do not underestimate the users: there are zillions 
 of casual C programmers out there who realize that int is not the same as 
 double; understanding the difference between Int64 and ZZ is no harder.) 
 Of course Python or Sage users don't have to worry about that. But isn't 
 Julia about better performance at the cost of specifying types?

 As for :

 It's also a pain in the neck to take output from one system, such as 
 Pari/GP and cut and paste a long polynomial, having to put ZZ(...) around 
 every bignum. It's just not practical.

 i tend to disagree. A little function parse_PARI(string) or whatever 
 would be easy to write.

 I also have an unrelated question, still about Nemo. I think in Julia's 
 type system, when A : B, then the intuition is that elements of type A are 
 also of type B, or am I wrong? Like elements of type Int64 are also of type 
 Integer (or whatever it's called). If so, your supertype of ZZ should not 
 be called Ring, but RingElement. For an element of ZZ is not a ring. Well, 
 abstract types are not types, they are more like type classes, but still 
 with the machine types the logic is as I've said.

 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.

 The logic from my point of view is that a type is a collection of values, 
 and as such Integer : Ring, not Integer : RingElement. But the 
 distinction is arbitrary.

 In the case of finite fields, I had an argument with myself about whether 
 I should use FFElem or FField. I decided on the latter. I would have liked 
 to use FiniteField, but this is the name I wanted to give to the function 
 that constructs an FField type (what some people call a factory I think).

 It's a shame that Julia allows a composite type and constructor to have 
 the same name, but a bitstype and constructor can't have the same name and 
 a factory and composite type cannot have the same name. Similarly a module 
 name and the filename can be the same, but the module name and the main 
 type it defines can't be.

 Those are all things I would do differently in Julia. And perhaps some of 
 these will change in a future release, who knows.

 They are minor nuisances at best. And there are probably important reasons 
 for those decisions. For example, if a type and factory could have the same 
 name, there could be issues with overloading the dot operator for both. And 
 that's something a lot of people seem to want Julia to do, so that they can 
 write Python in Julia.

 Bill.
  


 Pierre



-- 
You received this message because you are subscribed to the Google Groups 
sage-devel group.
To 

[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Jason Grout

On 8/21/14, 18:08, Bill Hart wrote:

In theory, I can do generic programming in Julia that is faster (at
runtime) than you can do in *any* C compiler. And I don't just mean a
little bit. I mean a lot. I don't even think the Julia people fully
realise this yet (I might be wrong about that, I don't know). And it's
not been realised in practice for many cases. But it is true.


Are you talking about the sort of things illustrated in this julia issue 
with the various macros they talk about?


https://github.com/JuliaLang/julia/issues/7033

Thanks,

Jason

P.S. I've been following Julia for a while and I'm very intrigued by it. 
 I've also started keeping an eye on Nemo recently---very interesting!



--
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart


On Saturday, 23 August 2014 04:26:10 UTC+2, jason wrote:

 On 8/21/14, 18:08, Bill Hart wrote: 
  In theory, I can do generic programming in Julia that is faster (at 
  runtime) than you can do in *any* C compiler. And I don't just mean a 
  little bit. I mean a lot. I don't even think the Julia people fully 
  realise this yet (I might be wrong about that, I don't know). And it's 
  not been realised in practice for many cases. But it is true. 

 Are you talking about the sort of things illustrated in this julia issue 
 with the various macros they talk about? 

 https://github.com/JuliaLang/julia/issues/7033 


That's not an example of what I have in mind, but it is an example of the 
sort of thing that is possible with type inference and macros.

Very nice example. Thanks for pointing it out.

(So the Julia developers really do know what they are onto. :-))
 


 Thanks, 

 Jason 

 P.S. I've been following Julia for a while and I'm very intrigued by it. 
   I've also started keeping an eye on Nemo recently---very interesting! 


Cool.
 

-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-22 Thread Bill Hart


On Saturday, 23 August 2014 06:09:00 UTC+2, jason wrote:

 On 8/21/14, 11:36, Bill Hart wrote: 
  You can define the A.b syntax in Julia if you should so desire. It's 
  essentially just another kind of method overload in Julia. 
  
  And then, it supports A.tab giving a list of all the things that could 
  follow the dot, just as Python would. 

 Are you saying you can overload the dot operator?  I thought that was 
 still an open issue (https://github.com/JuliaLang/julia/issues/1974). 


I don't think it has been implemented just yet. I thought it would make 
0.3, but it looks like nothing has happened in that direction yet.

But there's absolutely nothing preventing it, except for the fact that the 
Julia developers don't seem to want a profusion of dots everywhere.

It's not such a useful thing in a language with multimethods, I think.
 


 Harold: Julia does have a module system, which Bill illustrated, that 
 uses the dot to access members of the module.  And a dot also accesses 
 fields of a type instance. 

 Thanks, 

 Jason 




-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-21 Thread Dima Pasechnik
On 2014-08-21, Bill Hart goodwillh...@googlemail.com wrote:
 --=_Part_5_2037022158.1408650350021
 Content-Type: text/plain; charset=UTF-8

 Julia can already call Python functions (and I don't mean in some 
 theoretical, technical sense, I mean very practically via an interface 
 designed explicitly for such). So it's not necessary to move Sage from 
 Python to Julia. Other Scientific Python projects haven't done this.

 There are other reasons why this is not necessary, because of other 
 technical advances that will become available in the coming few years (they 
 are working in labs right now).

 Instead, the Sage project should do two things in my opinion:

 1) Make Julia part of the Sage ecosystem (it's already had a huge 
 investment from the scientific and statistical communities, so this is a 
 no-brainer if you want to embrace that community)

 2) Invest in the technologies that are making Julia successful (jit, 
 dependent typing, metaprogramming, type checking and inference, etc.)

 Whether 2 involves rewriting some functionality in Julia, or simply finding 
 ways of adding such functionality to Python is really neither here nor 
 there.

 What Sage can't do is just stagnate and ignore progress. If it does, it 
 will be brushed aside as if it wasn't even there, as has happened over and 
 over again in the history of computer algebra! And it's happening to Sage. 
 A few years ago, people at conferences were excitedly demonstrating stuff 
 in Sage. This year, they've moved back to Magma.

Perhaps, it's merely thanks to Simons Foundation making Magma free for all
universities in USA?

Oh, perhaps you mean that Magma has switched over to Julia? :-)


 As I have already mentioned, the technology behind Julia can in theory do 
 generic programming even faster than C or C++. So it is a strictly superior 
 technology to what has been available in the past. It's a genuine 
 innovation, whether the Julia designers see it that way or not.

Wait, are you saying there is an optimising Julia compiler available?
Without it, it sounds a bit like claims by Java poeple saying that their
JIT compilers are so great that they beat C compiled with gcc...
My cursory look into Julia only poped out JIT stuff, not a real complier...


 The Julia developers are not like me. They like Python and embrace it (many 
 of them are pythonistas). They would never go around claiming Julia is in 
 any way superior to Python. But I am not one of them and can go around 
 making such claims, because in the sense that I mean it, it is true.

What personally put me off Julia when it was announced was that
We are power Matlab users in the top of the blog post announcing
Julia project back in Feb 2012. I thought oh yes, swell, we do need a better
Matlab nchoosek() and 'everything is a matrix' greatness :-)...

Dima


 Bill.

 On Thursday, 21 August 2014 20:33:00 UTC+2, mmarco wrote:

 So, would it be thinkable of to move sage from Python to Julia? Sounds 
 like a titanic task, but sounds like if there are so many advantages in 
 Julia with respect to Python, it could be worth it.



-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-21 Thread Bill Hart


On Thursday, 21 August 2014 23:08:18 UTC+2, Dima Pasechnik wrote:

 On 2014-08-21, Bill Hart goodwi...@googlemail.com javascript: wrote: 
  --=_Part_5_2037022158.1408650350021 
  Content-Type: text/plain; charset=UTF-8 
  
  Julia can already call Python functions (and I don't mean in some 
  theoretical, technical sense, I mean very practically via an interface 
  designed explicitly for such). So it's not necessary to move Sage from 
  Python to Julia. Other Scientific Python projects haven't done this. 
  
  There are other reasons why this is not necessary, because of other 
  technical advances that will become available in the coming few years 
 (they 
  are working in labs right now). 
  
  Instead, the Sage project should do two things in my opinion: 
  
  1) Make Julia part of the Sage ecosystem (it's already had a huge 
  investment from the scientific and statistical communities, so this is a 
  no-brainer if you want to embrace that community) 
  
  2) Invest in the technologies that are making Julia successful (jit, 
  dependent typing, metaprogramming, type checking and inference, etc.) 
  
  Whether 2 involves rewriting some functionality in Julia, or simply 
 finding 
  ways of adding such functionality to Python is really neither here nor 
  there. 
  
  What Sage can't do is just stagnate and ignore progress. If it does, it 
  will be brushed aside as if it wasn't even there, as has happened over 
 and 
  over again in the history of computer algebra! And it's happening to 
 Sage. 
  A few years ago, people at conferences were excitedly demonstrating 
 stuff 
  in Sage. This year, they've moved back to Magma. 

 Perhaps, it's merely thanks to Simons Foundation making Magma free for all 
 universities in USA? 


Definitely a factor. But a minor one.

William is pretty much right about why people are going back to Magma. But 
a lot of people are missing the other reasons
 


 Oh, perhaps you mean that Magma has switched over to Julia? :-) 


N. Julia is not the issue here. I honestly couldn't give a toss about 
Julia. I've been very open about the fact that I think there are things 
wrong with Julia and that I will likely move my work from Julia to some 
other language in the future (when such a language becomes available). But 
it is definitely the best language around for this sort of thing.

The issue here is the technology Julia is based on. Without it, you are 
going to very rapidly fall behind. And I said so very publicly, years 
before Julia was even announced (I'd have to check, but possibly even 
before private development of Julia began). At the time my criticism was 
posted to sage-flame and ridiculed.

Anyway, to address your point. Magma is technologically superior to Sage in 
many ways (and in other ways is completely backward).

Magma has been actively investing in parallel and GPU technology. And I 
happen to know they employed at least one person working on LLVM and 
web-based technologies.

Magma has its own language, and doesn't need Julia. They can (just as Sage 
can), embrace the new technological innovations, without throwing away 
everything they have.

Magma isn't a static target for which development stopped when Sage began. 
It is a moving target, that in some areas will always outstrip Sage. The 
only way to beat it, is to make sure Sage can move even faster than they 
can in embracing new technology. It needs to be possible to get a Magma 
beating solution off the ground in half the time Magma can do it. And that 
is nowhere near the case.
 


  
  As I have already mentioned, the technology behind Julia can in theory 
 do 
  generic programming even faster than C or C++. So it is a strictly 
 superior 
  technology to what has been available in the past. It's a genuine 
  innovation, whether the Julia designers see it that way or not. 

 Wait, are you saying there is an optimising Julia compiler available? 


You don't need an optimising compiler for Julia. Precisely the same backend 
that is used for the Clang C/C++ compiler underlies Julia. It's over 1 
million lines of code. The difference is, it is jit compiled.
 

 Without it, it sounds a bit like claims by Java poeple saying that their 
 JIT compilers are so great that they beat C compiled with gcc... 


No, I said generic programming can be faster in Julia than in C. Not that 
generic programming can be faster than some particular C compiler. The 
technology is fundamentally superior to C. That's a concept people are 
going to take a long time to understand and accept, but it's true.

In theory, I can do generic programming in Julia that is faster (at 
runtime) than you can do in *any* C compiler. And I don't just mean a 
little bit. I mean a lot. I don't even think the Julia people fully realise 
this yet (I might be wrong about that, I don't know). And it's not been 
realised in practice for many cases. But it is true.

On the other hand, because the Julia Jit is based on the technology 

[sage-devel] Re: On scientific computing, Python and Julia

2014-08-21 Thread Bill Hart


On Friday, 22 August 2014 00:08:20 UTC+2, Bill Hart wrote:



 My cursory look into Julia only poped out JIT stuff, not a real 
 complier... 


 Static compilation is coming to Julia. But not because it will speed 
 things up. It already has all the speed of an optimising compiler at the 
 console, as you type!


I should qualify that. Technically, jit compilation and type inference 
begin at the function boundary in Julia. So stuff you type at the top level 
is not optimised. I think that is a mistake, as it's unnecessary. In the 
language I was working on (using LLVM) type inference and optimisation 
begin at the top level (which for me is a function). There is a small 
runtime hit with global variables, but that is all.

In particular, in the language I was working on, loops at the top level are 
jit compiled. In Julia they are not. But it's almost irrelevant, except 
when doing timing experiments to see how fast Julia really goes. You might 
easily think to type a loop into the top level and time it and wonder what 
all the fuss is about. Put that loop inside a function and you'll soon see.

julia function sumit(n::Int)
  s = 0
  for i = 1:n
s += i
  end
  return s
   end
sumit (generic function with 1 method)

julia @time sumit(10)
elapsed time: 0.913325036 seconds (78060 bytes allocated)
55

Bill.

-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-21 Thread Bill Hart
Another thing that I think is terribly important is that the entire 
technology stack, LLVM, all its libraries and packages, its console, the 
IJulia web interface and Julia itself, all work out of the box on Windows 
64, natively, not as a Cygwin app (they use MinGW64/MSYS2 to build Julia).

And I've personally verified this. After some initial troubles due to the 
fact that flint.dll is not built correctly on Windows 64, Nemo works 
perfectly on Windows and from the IJulia interface running on my local 
Windows 64 machine.

This doesn't solve any problems for Sage, as many mathematical libraries 
still don't natively support Windows 64 despite it being a decade old. But 
it is a significant feature of Julia (and of the Nemo project I am writing 
with Julia).

Bill.
 
On Friday, 22 August 2014 00:26:23 UTC+2, Bill Hart wrote:



 On Friday, 22 August 2014 00:08:20 UTC+2, Bill Hart wrote:



 My cursory look into Julia only poped out JIT stuff, not a real 
 complier... 


 Static compilation is coming to Julia. But not because it will speed 
 things up. It already has all the speed of an optimising compiler at the 
 console, as you type!


 I should qualify that. Technically, jit compilation and type inference 
 begin at the function boundary in Julia. So stuff you type at the top level 
 is not optimised. I think that is a mistake, as it's unnecessary. In the 
 language I was working on (using LLVM) type inference and optimisation 
 begin at the top level (which for me is a function). There is a small 
 runtime hit with global variables, but that is all.

 In particular, in the language I was working on, loops at the top level 
 are jit compiled. In Julia they are not. But it's almost irrelevant, except 
 when doing timing experiments to see how fast Julia really goes. You might 
 easily think to type a loop into the top level and time it and wonder what 
 all the fuss is about. Put that loop inside a function and you'll soon see.

 julia function sumit(n::Int)
   s = 0
   for i = 1:n
 s += i
   end
   return s
end
 sumit (generic function with 1 method)

 julia @time sumit(10)
 elapsed time: 0.913325036 seconds (78060 bytes allocated)
 55

 Bill.


-- 
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.


[sage-devel] Re: On scientific computing, Python and Julia

2014-08-21 Thread Bill Hart
I just found time to actually read the links posted by the OP on Graydon 
Hoare's history of programming language development, culminating in Julia.

Oh I wish I could write like that! The guy is clearly a genius of immense 
proportions. 

I truly, truly wish that the computer algebra and number theoretic 
communities were engaging people like this and leveraging their insight and 
vision to the fullest.

Bill.

On Friday, 22 August 2014 01:19:22 UTC+2, Bill Hart wrote:

 Another thing that I think is terribly important is that the entire 
 technology stack, LLVM, all its libraries and packages, its console, the 
 IJulia web interface and Julia itself, all work out of the box on Windows 
 64, natively, not as a Cygwin app (they use MinGW64/MSYS2 to build Julia).

 And I've personally verified this. After some initial troubles due to the 
 fact that flint.dll is not built correctly on Windows 64, Nemo works 
 perfectly on Windows and from the IJulia interface running on my local 
 Windows 64 machine.

 This doesn't solve any problems for Sage, as many mathematical libraries 
 still don't natively support Windows 64 despite it being a decade old. But 
 it is a significant feature of Julia (and of the Nemo project I am writing 
 with Julia).

 Bill.
  
 On Friday, 22 August 2014 00:26:23 UTC+2, Bill Hart wrote:



 On Friday, 22 August 2014 00:08:20 UTC+2, Bill Hart wrote:



 My cursory look into Julia only poped out JIT stuff, not a real 
 complier... 


 Static compilation is coming to Julia. But not because it will speed 
 things up. It already has all the speed of an optimising compiler at the 
 console, as you type!


 I should qualify that. Technically, jit compilation and type inference 
 begin at the function boundary in Julia. So stuff you type at the top level 
 is not optimised. I think that is a mistake, as it's unnecessary. In the 
 language I was working on (using LLVM) type inference and optimisation 
 begin at the top level (which for me is a function). There is a small 
 runtime hit with global variables, but that is all.

 In particular, in the language I was working on, loops at the top level 
 are jit compiled. In Julia they are not. But it's almost irrelevant, except 
 when doing timing experiments to see how fast Julia really goes. You might 
 easily think to type a loop into the top level and time it and wonder what 
 all the fuss is about. Put that loop inside a function and you'll soon see.

 julia function sumit(n::Int)
   s = 0
   for i = 1:n
 s += i
   end
   return s
end
 sumit (generic function with 1 method)

 julia @time sumit(10)
 elapsed time: 0.913325036 seconds (78060 bytes allocated)
 55

 Bill.



-- 
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.