# 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:** 2

<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 7, 2021, 3:18pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/21 "2021-07-07T15:18:35Z")

</div>

> [@Gilles\_Dubois](#):
>
> As a rule, the better the code the more difficult to read.

I don’t think so, better code should be very easy to read.

It’s only hard to read because I went by trial and error. And some of it is really much simpler than writing out everything by ‘special case’. Extending the `show` method, for example, is so much easier and more powerful than writing a loop over an array. The subscript business is just an extra flourish, not needed.

If you remove the second type parameter, because it’s not needed, the code isn’t that complex.

But using a type parameter for the base is definitely the way to go.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 7, 2021, 3:47pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/22 "2021-07-07T15:47:16Z")

</div>

> [@Gilles\_Dubois](#):
>
> As far as I know Julia function can return instances of of a given struct but not struct themselves (Python can, Julia macros can).

By the way, this is not true at all:

```julia
julia> struct MyStruct
         x::Int
       end

julia> function f()
         return MyStruct
       end
f (generic function with 1 method)

julia> f()
MyStruct

julia> f()(5)
MyStruct(5)

```

> [@Gilles\_Dubois](#):
>
> Solutions based on ‘static variables’ (data belonging to the whole class, and not to instances) are difficult to find too.

Yes, the _type_ of a struct is not generally used as a container for data in Julia in the same way you might use a class-level method or value in Python. However, it’s easy to recreate this effect with multiple dispatch:

```julia
julia> function my_property(::MyStruct)
         return 5 # always 5 for any instance of `MyStruct`, effectively a static constant for this type
       end
my_property (generic function with 1 method)

julia> my_property(MyStruct(1))
5

```

---

<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 7, 2021, 4:19pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/23 "2021-07-07T16:19:54Z")

</div>

> [@Gilles\_Dubois](#):
>
> I will study this in detail for myself. I don’t think I will use it on my site, because for education I don’t take care about power, performance, elegance, I privilege ‘readability’ that’s why my first choice was Python.

So, it never really occurred to me that elegance was the enemy of true mathematics 🙃 But anyway, I just wanted to show a simpler example:

```julia
struct Z{P} <: Integer
    x::Int
    Z{P}(n::Integer) where {P} = new{P}(mod(n, P))
end

Base.promote_rule(::Type{<:Number}, ::Type{Z{P}}) where {P} = Z{P}
Base.show(io::IO, z::Z) = show(io, z.x)

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)
Base.div(a::Z{P}, b::Z{P}) where {P} = Z{P}(a.x ÷ b.x) # I don't think this is needed, really

```

Now you can

```julia
jl> z = zeros(Z{7}, 3, 3)
3×3 Matrix{Z{7}}:
 0 0 0
 0 0 0
 0 0 0

jl> one(z)
3×3 Matrix{Z{7}}:
 1 0 0
 0 1 0
 0 0 1

jl> z = Z{11}.(rand(0:10, 3, 3))
3×3 Matrix{Z{11}}:
  3 3 4
  3 4 5
 10 4 10

jl> z.^2 .+ 1
3×3 Matrix{Z{11}}:
 10 10 6
 10 6 4
  2 6 2

jl> maximum(z.^2 .+ 1)
10

jl> (2 + 3im) * Z{11}(2)
4 + 6im

# etc.

```

I think comparison and random sampling is really neat, but whatever.

```julia
Base.:<(a::Z{P}, b::Z{P}) where {P} = (a.x < b.x)
Base.:<=(a::Z{P}, b::Z{P}) where {P} = (a.x <= b.x)
function Random.rand(rng::AbstractRNG, ::Random.SamplerType{Z{P}}) where {P}
    return Z{P}(rand(rng, 0:P-1))
end

```

Anyway, if you are teaching this to students, you shouldn’t drag macros into it, and for all that is holy, don’t use `global`(!)

---

<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 7, 2021, 5:16pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/24 "2021-07-07T17:16:15Z")

</div>

Thank you for this valuable information.

---

<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 7, 2021, 5:17pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/25 "2021-07-07T17:17:47Z")

</div>

But can you define struct inside body of f?

---

<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 7, 2021, 5:25pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/26 "2021-07-07T17:25:00Z")

</div>

With experience of other languages behaviour, it’s natural to ask if a new one can do the same and how. But of course I agree that C++ is C++ and Julia is Julia. And in turn I can ask the question : How Julia knows (guesses) that I want the sum and product of matrices with coeffs in F\_p be the ‘usual’ sum and product of matrices?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [July 7, 2021, 5:30pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/27 "2021-07-07T17:30:32Z")

</div>

All of the Julia matrix code boils down to operations on the elements. When you use a new element type, Julia will use the appropriate definitions for + and \* for that element type. The reason Julia uses multiple dispatch is that it causes stuff like this to “just work”

---

<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 7, 2021, 5:34pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/28 "2021-07-07T17:34:51Z")

</div>

Exactly. Julia knows how to sum over a matrix: start with the first element, add the second, then the third. And we have just shown Julia how to add integer modulo `P`.

Same with matrix product: start at one end, multiply, add, repeat. There’s nothing more to it. To improve performance, maybe a specialized matrix product is called for, but that’s just an optimization.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 7, 2021, 5:38pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/29 "2021-07-07T17:38:08Z")

</div>

> [@Gilles\_Dubois](#):
>
> But can you define struct inside body of f?

You can, using `eval()`, but it’s pretty rare to actually need to do so. Do you have a specific use in mind?

---

<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 7, 2021, 5:57pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/30 "2021-07-07T17:57:25Z")

</div>

Pure curiosity

---

<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 7, 2021, 6:06pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/31 "2021-07-07T18:06:37Z")

</div>

> [@rdeits](#):
>
> You can, using `eval()` , but it’s pretty rare to actually need to do so. Do you have a specific use in mind?

Usually you use named tuples if you want anonymous (on the fly) struct types.

---

<div class="post-metadata">

**Author:** ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)\
**Post date:** [July 7, 2021, 6:10pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/32 "2021-07-07T18:10:36Z")

</div>

If we can create anonymous struct types in functions, why not named struct types?

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [July 7, 2021, 6:27pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/33 "2021-07-07T18:27:31Z")

</div>

I’m not sure, but it is probably related to dispatch. You can dispatch on a type, while a named tuple will dispatch as named tuple.

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [July 7, 2021, 6:58pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/34 "2021-07-07T18:58:35Z")

</div>

> [@jzr](#):
>
> If we can create anonymous struct types in functions, why not named struct types?

My guess is that it has to do with subtyping. You could imagine creating a struct at the top level, that is a “named struct type” that still allows dispatching on the name of the struct:

```julia
struct NamedTupleWithName{N, FN, FT}
    name::N
    fields::NamedTuple{FN, FT}
end

function make(name::Symbol)
    NamedTupleWithName(Val(name), (x=1, y=2))
end

function property(s::NamedTupleWithName{Val{:Foo}})
    s.fields.x + s.fields.y
end

function property(s::NamedTupleWithName{Val{:Bar}})
    s.fields.x * s.fields.y
end

```

```julia
julia> property(make(:Foo))
3

julia> property(make(:Bar))
2

```

What you don’t have here is a way to encode a subtype relation between different types. For example, I don’t know how you would encode `getx` from below in the above scheme

```julia
abstract type Nonce end
struct Foo <: Nonce
    x
    y
end

struct Bar <: Nonce
    x
    y
end

function property(s::Foo)
    s.x + s.y
end

function property(s::Bar)
    s.x * s.y
end

function getx(s::Nonce)
    s.x
end

```

---

<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 7, 2021, 7:57pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/35 "2021-07-07T19:57:15Z")

</div>

> [@Sukera](#):
>
> This should be adding a method to `Base.iszero` instead.

Yes, I tried, what is the interest ?  
test nul(k) replaced by iszero(k) ???  
In any case k==0 not understood after such overload. I tried just in case.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [July 7, 2021, 8:00pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/36 "2021-07-07T20:00:05Z")

</div>

`k==0` will not call `iszero`. I think the suggestion is to replace `k == 0` with `iszero(k)`.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [July 7, 2021, 8:02pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/37 "2021-07-07T20:02:57Z")

</div>

> [@Gilles\_Dubois](#):
>
> Yes, I tried, what is the interest ?  
> test nul(k) replaced by iszero(k) ???  
> In any case k==0 not understood after such overload. I tried just in case.

What I meant was that I think your `nul(k)` function is a check for whether or not `k` is zero or not. Julia already has a generic method for this, which is called `iszero`. This `iszero` is used throughout `Base` in various library functions, so if you want to allow them to work with your number type, you can overload `Base.iszero(k::F_p) = k.x == 0` instead.

---

<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 7, 2021, 11:00pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/38 "2021-07-07T23:00:04Z")

</div>

Thank you for your example.  
I understand that it’s the way to do it.  
I’m not used to this syntax yet and BTW I still have some problems with Julia types.  
I have to work on this ; for the moment it’s pure magic.  
I hope you won’t mind if I come back to you for a few comments.

---

<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, 4:55am UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/39 "2021-07-08T04:55:27Z")

</div>

Sure, no problem.

---

<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:09pm UTC](https://discourse.julialang.org/t/is-julia-lazy/64192/40 "2021-07-08T12:09:42Z")

</div>

I think you spent already some time writing your examples. Since you accept to answer some questions I will ask one by one to reach a final comprehension of your code.  
Till now I am making some experiments with it, changing this and that trying to generate errors and to interpret these errors. It’s an useful job, but I cannot make everything clear from such experiments.  
I would like to be able to write again such kind of code understanding exactly what I’m doing and why.  
So first let’s take the first line to begin with :  
`struct Z{P} <: Integer`  
By this you describe type Z{P} to be a sub-type of Integer which is an abstract type.  
Here are my questions :

1. What is the benefit doing this ?
2. What do you loose if you don’t do it ?
3. What if instead of Integer you choose something higher in the hierarchy such as Real or Number ?
4. What if you choose instead a primitive concrete type such as Int64 for example ?  
Have a nice day !

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

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