# Is Julia lazy?

**URL:** <https://discourse.julialang.org/t/is-julia-lazy/64192>\
**Category:** New to Julia\
**Created:** [July 7, 2021, 4:25am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192 "2021-07-07T04:25:57Z")\
**Posts on this page:** 20\
**Page:** 3

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 8, 2021, 12:35pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/41 "2021-07-08T12:35:08Z")

</div>

> [@Gilles\_Dubois](#):
>
> What is the benefit doing this ?

Methods that accept an integer will also accept `Z{P}`, so you may gain access to that functionality. This depends on that you have correctly implemented the basic functionality (or ‘interface’) of `Integer`, otherwise it may end throwing errors or doing strange things. My code examples probably has not done that.

> [@Gilles\_Dubois](#):
>
> What do you loose if you don’t do it ?

You cannot use that functionality for `Z{P}`, or you’ll have to implement it yourself. Off the top of my head I can’t remember what functionality that would be, but basically any method that someone has written with `::Integer` in its type signature.

> [@Gilles\_Dubois](#):
>
> What if instead of Integer you choose something higher in the hierarchy such as Real or Number ?

Then the pool of available methods that work ‘out of the box’ for your method is a bit smaller.

> [@Gilles\_Dubois](#):
>
> What if you choose instead a primitive concrete type such as Int64 for example ?

That won’t work. You cannot subtype a concrete type, only abstract types.

---

<div class="post-metadata">

**Author:** ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)\
**Post date:** [July 8, 2021, 12:42pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/42 "2021-07-08T12:42:06Z")

</div>

It’s a bit unfortunate that the interfaces to base types (Integer, Number, etc) aren’t documented better. In lieu of that the documentation of the [array interface](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array) is a decent conceptual substitute. If you have a type that you want to behave like an array you can subtype abstractarray, and implement the few functions listed in the documentation and your new type will get all the functions already defined for abstractarrays across the ecosystem.

The same is true of Integer, Number, etc. but the required functions are not as well documented.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 8, 2021, 12:47pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/43 "2021-07-08T12:47:53Z")

</div>

thank you it is perfectly clear. Possibly another question this evening. My wife wants to bring me back down to this earth.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 8, 2021, 12:52pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/44 "2021-07-08T12:52:37Z")

</div>

> [@Jordan\_Cluts](#):
>
> It’s a bit unfortunate that the interfaces to base types (Integer, Number, etc) aren’t documented better

Indeed. While I was typing up that `Z{P, T}` code, I was constantly running into weird effects, such as

```julia
>> length(Z13(0):Z13(12))
0

```

and `collect` returned an empty vector, even though I could iterate over it and print all the elements.

It felt a bit like playing whack-a-mole. New problems kept popping up when I tried new things, then I tried, half-blindly, to patch up the necessary functionality, but ended up creating ambiguity problems because I didn’t know which methods to add, and some of the time I chose the wrong ones.

A bit frustrating, and I have _no_ idea if I’m even close, what to add, what to remove, and when the next error will pop up.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 8, 2021, 12:52pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/45 "2021-07-08T12:52:41Z")

</div>

I understand that Julia’s abstract types are the equivalent of C++ abstract classes or Java interfaces. Don’t know anything equivalent in Python’s world.

---

<div class="post-metadata">

**Author:** ![Jordan\_Cluts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jordan_cluts/32/13753_2.png) [@Jordan\_Cluts](https://discourse.julialang.org/u/Jordan_Cluts)\
**Post date:** [July 8, 2021, 12:57pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/46 "2021-07-08T12:57:33Z")

</div>

The best bet would probably be to find a package that implements a new type subtyping the same abstract type you wish to subtype and see what they implement. For example if you wanted to create a new \<: Real, looking at the Rational type in base would be good as presumably it implements all needed functions. There are surely packages out there that subtype integer already to crib off of.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 8, 2021, 1:03pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/47 "2021-07-08T13:03:10Z")

</div>

Good point. The implementation grew a bit ‘organically’, so the realization that this should be done more systematically came a bit late.

Another question is: what is the right abstract type, `Integer` or `Unsigned`, or `Real`? It sure seems like an integer type, though.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 8, 2021, 1:18pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/48 "2021-07-08T13:18:18Z")

</div>

Wow. I just realized that basing the `Z{P, T}` type on `UInt` was a _bad_ idea! Wraparound effects when subtracting are plain wrong. Use `Int` (or `Int8` etc. instead!!)

```julia
jl> zu1, zu2 = Z{13, UInt8}.((2, 5))
(2₁₃, 5₁₃)

jl> zu1 - zu2
6₁₃ # Wrong-o!!

jl> zs1, zs2 = Z{13, Int8}.((2, 5))
(2₁₃, 5₁₃)

jl> zs1 - zs2
10₁₃ # correct!

```

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [July 8, 2021, 1:27pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/49 "2021-07-08T13:27:21Z")

</div>

Good thing we’re still prototyping! 🙂

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 8, 2021, 1:35pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/50 "2021-07-08T13:35:46Z")

</div>

Have you tried looking at how an existing package defines new number types?

For example, [GaloisFields.jl](https://github.com/tkluck/GaloisFields.jl) implements finite fields. This package implements a lot of features, but the basic number type for prime fields is implemented [here](https://github.com/tkluck/GaloisFields.jl/blob/master/src/PrimeFields.jl).

Another nice and relatively simple example of a custom number type can be found in the [Quaternions.jl](https://github.com/JuliaGeometry/Quaternions.jl) package, which defines a quaternion type [here](https://github.com/JuliaGeometry/Quaternions.jl/blob/master/src/Quaternion.jl).

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 8, 2021, 7:35pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/51 "2021-07-08T19:35:17Z")

</div>

Good evening ! (night is coming in my native France).  
Let’s continue, if you agree with my continuing questions. I will play the ‘Candide’ role or ‘advocate of the devil’ according the situation. It’s just a matter of style to stimulate the debate.  
OK as I understood you derive (sub-type) from some abstract type to access functionality.  
But in any case you’re obliged to explain Julia how to add, multiply, subtract F\_p objects, just like me who didn’t use any sub-typing.  
We do the same things parallel, don’ t we ?  
You :  
`Base.:+(a::Z{P}, b::Z{P}) where {P} = Z{P}(a.x + b.x)  
Base.:-(a::Z{P}, b::Z{P}) where {P} = Z{P}(a.x - b.x)  
Base.:-(a::Z{P}) where {P} = Z{P}(-a.x)  
Base.:\*(a::Z{P}, b::Z{P}) where {P} = Z{P}(a.x \* b.x)`type or paste code here`  
me :

```julia
Base.:+(k::F_p,h::F_p) = F_p(k.x+h.x)
Base.:*(k::F_p,h::F_p) = F_p(k.x*h.x)
Base.:-(k::F_p)=F_p(-k.x)
Base.:-(k::F_p,h::F_p)=F_p(k.x-h.x)

```

So I ask again : what advantage do you draw from sub-typing ???  
Tell me what you can do which I cannot according our two approaches.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 8, 2021, 7:50pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/52 "2021-07-08T19:50:54Z")

</div>

For sure I’ll have a look at this.  
For now I have no ambitions except [teaching the base of linear algebra](http://gilles.dubois10.free.fr/algebre_lineaire/algebre_lineaire.html) using simple programs as examples (python and now julia //)  
But I just published [a site of algebra](http://gilles.dubois9.free.fr/) specially dedicated to mobile devices (telephones and tablets). Sorry but everything is in French.  
For the moment the algebra site has a development mainly guided by historical considerations. As a consequence complete results concern mostly the characteristic 0 where separability is obvious.  
Nevertheless it’s my intention to develop more the general theory and to give examples with appropriate programs.  
So I will need models for Fp polynomials, Fp-vector spaces, finite extension of Fp and so on to make computations.  
For sure this module will be of great help.  
This is a plan for future now I’m busy with learning correct use of sub-typing, parametric types and so on.

---

<div class="post-metadata">

**Author:** ![Fliks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fliks/32/2494_2.png) [@Fliks](https://discourse.julialang.org/u/Fliks)\
**Post date:** [July 8, 2021, 8:26pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/53 "2021-07-08T20:26:08Z")

</div>

There are functions which are defined for Integer directly and therefore also for all its suptypes.  
For example, when you take @DNF s [simpler example](https://discourse.julialang.org/t/is-julia-lazy/64192/23) without the subtyping, you couldn’t do

```julia
a = Z{5}(3) 
a ^ 2 

```

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 8, 2021, 8:48pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/54 "2021-07-08T20:48:59Z")

</div>

you mean that once \* overloaded not necessary to overload exponent ^.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 8, 2021, 9:00pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/55 "2021-07-08T21:00:03Z")

</div>

> [@Gilles\_Dubois](#):
>
> So I ask again : what advantage do you draw from sub-typing ???  
> Tell me what you can do which I cannot according our two approaches.

Yes, you have to define a limited number of methods, like basic arithmetic. But every other method that anyone ever defines for `Integer`, which could be any countless number, are now available, as well as all the functionality that derives from those again.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [July 8, 2021, 9:12pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/56 "2021-07-08T21:12:56Z")

</div>

> [@Gilles\_Dubois](#):
>
> I understand that Julia’s abstract types are the equivalent of C++ abstract classes or Java interfaces. Don’t know anything equivalent in Python’s world.

I think this is the source of a lot of your confusion here. Julia has nothing at all equivalent to C++'s abstract classes. Python classes are similar to C++'s (except python people would typically add in an old school `raise NotImplemented` for any methods not defined rather than actually having it abstract. See [class - Is it possible to make abstract classes in Python? - Stack Overflow](https://stackoverflow.com/questions/13646245/is-it-possible-to-make-abstract-classes-in-python) Java Interfaces are a little bit closer, but even then I don’t think it is the right way to think about it.

The closest thing in C++ are trait classes. Remember that Julia is much closer to the parametric/generic programming in C++ than anything object orietned. Look at code which uses overloading of functions defined on templated classes in C++ to get into the right spirit. With C++ overloading and templates, you can have things “dispatch” statically to different functions, but it is tough to carefully control which functions are called.

So when doing generic programming in C++ you sometimes subclass from a empty classes (these are not abstract in the sense of having a non-implemented member function). These are just used to organization of traits for dispatching. But don’t be fooled as the use of a `class` and inheritance from them is just a trick, and has nothing to do with classes in object-oriented programming. This has some of the tricks in this insanity: [http://cppedinburgh.uk/slides/201603-tmp.pdf](http://cppedinburgh.uk/slides/201603-tmp.pdf) Also [Substitution failure is not an error - Wikipedia](https://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error) explains some of this stuff

With that C++ lets you rig up what you could call “multiple static dispatch” for functions when all of the types are known at compiletime - although it is often incredibly painful to get there.

* * *

OK, now forget all of that if you didn’t know it. C++ is powerful but insane due to people having to find hacks to implement these features on an old language. In Julia you can do **dynamic dispatch** at runtime and with different specializations for all of the parameters of the function (i.e. multiple dispatch). The abstract types are your way to use existing code for the implementations of your functions if they fit into the same “interface” in a loose generic programming sense.

I wrote up some lecture notes on some of these topics: [5. Introduction to Types and Generic Programming — Quantitative Economics with Julia](https://julia.quantecon.org/getting_started_julia/introduction_to_types.html) and [6. Generic Programming — Quantitative Economics with Julia](https://julia.quantecon.org/more_julia/generic_programming.html)

---

<div class="post-metadata">

**Author:** ![John\_Gibson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/john_gibson/32/5321_2.png) [@John\_Gibson](https://discourse.julialang.org/u/John_Gibson)\
**Post date:** [July 8, 2021, 11:07pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/57 "2021-07-08T23:07:47Z")

</div>

“C++ is powerful but insane” +1

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 9, 2021, 6:07am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/58 "2021-07-09T06:07:25Z")

</div>

Yes, I tried with Integer sub-typing a^n is evaluated correctly for n integer \>0 without any extra-code except overloading of \*.  
But a^0 and a^-1 lead (logically) to errors.  
Can you find one or two examples let’s say more ‘spectacular’ because honestly I’m not too much impressed by this one. In a field you must be able to compute any power positive or negative of any non null element. To do this you have to overload iszero and inv and define a ^k so to redefine on the way the positive powers isn’t much job.  
Examples given by DNF are more convincing But it is the explicit ‘promotion rule’ which does the job.  
Well, access to some functionality is not straightforward from derivation.

---

<div class="post-metadata">

**Author:** ![Gilles\_Dubois](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gilles_dubois/32/25830_2.png) [@Gilles\_Dubois](https://discourse.julialang.org/u/Gilles_Dubois)\
**Post date:** [July 9, 2021, 6:35am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/59 "2021-07-09T06:35:19Z")

</div>

OK forget about this, I mean benefit of sub-typing now. As I answered to Fliks it seems to me modest without the associated promotion rule.  
I made some test with my simple and naive definition of Z\_p with a global p (which you hate). I adapted  
your rule to my context

```julia
Base.promote_rule(::Type{<:Number}, ::Type{F_p}) = F_p

```

and after this I could multiply a F\_p by a natural

So to this point Julia knows how to multiply two F\_p, how to multiply two naturals and by promotion a natural by a F\_p 12a and a\*12 are understood and give the same result.  
I tried to make some changes . Actually your rule converts any Type sub-typing the very general Number abstract type to F\_p. But in reality it is just necessary to convert integers. So I changed :\<Number for :\<Integer it works. What is the reason of your choice (I mean Number and not Integer) ?  
As I understood it is only possible from a type to a sub-type, not conversely. One cannot decide to identify a F\_p with it’s x member, or is it possible and how to do it.  
This is pure curiosity I don’t see any practical interest to do it now, I just want to close the chapter of explicit promotion-conversion rules.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [July 9, 2021, 7:53am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/60 "2021-07-09T07:53:06Z")

</div>

> [@Gilles\_Dubois](#):
>
> OK forget about this, I mean benefit of sub-typing now.

You mean in this particular case? I don’t have an overview of that, it depends on what you want to do. If you have no interest in functionality beyond basic arithmetic, then you don’t need subtyping. I found that _printing_ of arrays is nicer when you subtype `Integer`, but that’s just my preference.

> [@Gilles\_Dubois](#):
>
> it seems to me modest without the associated promotion rule.

Sure. But why not use both?

> [@Gilles\_Dubois](#):
>
> I made some test with my simple and naive definition of Z\_p with a global p (which you hate).

I’m sure it works, I just don’t think students should learn to use globals like that. And it’s less elegant, _and_ less readable and instructive. Type parameters seem to map so cleanly to the parameterization of Zp, it seems like a good case for demonstrating both.

> [@Gilles\_Dubois](#):
>
> What is the reason of your choice (I mean Number and not Integer)

The reason is arbitrary and not properly thought-out. I wanted `2.0 * z` and so on to work.

> [@Gilles\_Dubois](#):
>
> But a^0 and a^-1 lead (logically) to errors.

I get

```julia
jl> z = Z13(5)
5₁₃

jl> zz = Z13.(rand(0:12, 3, 3))
3×3 Matrix{Z13}:
 3₁₃ 5₁₃ 4₁₃
 1₁₃ 12₁₃ 8₁₃
 8₁₃ 0₁₃ 11₁₃

jl> z^0
1₁₃

jl> zz^0
3×3 Matrix{Z13}:
 1₁₃ 0₁₃ 0₁₃
 0₁₃ 1₁₃ 0₁₃
 0₁₃ 0₁₃ 1₁₃

```

Division or inversion don’t work:

```julia
jl> z^(-1)
ERROR: MethodError: no method matching AbstractFloat(::Z13)

```

You’ll have to teach Julia about the rules of division/inversion in modular arithmetic, or let it convert to floats.

[Previous page](https://discourse.julialang.org/t/is-julia-lazy/64192.md?page=2)

[Next page](https://discourse.julialang.org/t/is-julia-lazy/64192.md?page=4)
