# Intialize types and define operators within them

**URL:** <https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435>\
**Category:** New to Julia\
**Created:** [September 24, 2018, 7:51pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435 "2018-09-24T19:51:29Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 24, 2018, 7:51pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/1 "2018-09-24T19:51:29Z")

</div>

Dear all, I have two questions concerning composite types:

1. Is it possible to set a variable to a type without initializing all its values? For example

```julia
type test
    a :: Int64
    b :: Float64
end
x = test()

```

(that does not work - and coudn’t find the answer in the manuals, I suppose that  
is possible, or at least set the variable with default values).

1. Is it possible to define operators acting on types, such as custom “\<”, “==”, etc?

For instance, I use to do something like this in fortran:

```julia

type test
   a :: Int64
   b :: Float64
end

x = test(1,2.e0)
y = test(2,3e0)

if x < y 
   do something

```

but where the “\<” is something I defined, such as

`x.a < y.a && x.b < y.b`

(of course it is easy to define a function isless(…), but for clarity reasons sometimes  
it is nice to define the meaning of the operators).

Thank you.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 24, 2018, 7:59pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/2 "2018-09-24T19:59:16Z")

</div>

```julia
julia> struct test
           a :: Int64
           b :: Float64
           c :: String
           test() = new()
           test(a,b,c) = new(a,b,c)
       end

julia> test()
test(4586250192, 1.5e-323, #undef) # garbage data in isbits fields

julia> test()
test(4493813616, 0.0, #undef) # garbage data in isbits fields

julia> test(1,2,"foo")
test(1, 2.0, "foo")

julia> Base.:<(x::test, y::test) = x.a < y.a && x.b < y.b

julia> test(1,2,"a") < test(3,2,"b")
false

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 24, 2018, 8:25pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/3 "2018-09-24T20:25:33Z")

</div>

Just adding information for my own ignorance. Of course, when I thought to define the variable without defining its values, I was willing to define the values afterwards using

```julia
x = test()
x.a = 1

```

in which case, I find now, I need to define a “mutable struct” instead:

```julia
mutable struct test
  a :: Int64
  test() = new()
# test() = new(4) # could be used to start with a default value
  test(a) = new(a)
end

```

Thank you.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 25, 2018, 5:25am UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/4 "2018-09-25T05:25:29Z")

</div>

> [@kristoffer.carlsson](#):
>
> julia\> Base.:\<(x::test, y::test) = x.a \< y.a && x.b \< y.b

An elegant way (I think) of defining methods for operators is

```julia
julia> import Base.<

julia> struct test
                  a :: Int64
                  b :: Float64
                  c :: String
                  test() = new()
                  test(a,b,c) = new(a,b,c)
              end

julia> x::test < y::test = x.a < y.a && x.b < y.b
< (generic function with 71 methods)

julia> test(1,2,"a") < test(3,2,"b")
false

```

Note that the operator must be imported (or qualified like in Kristoffers example) to be extended.

---

<div class="post-metadata">

**Author:** ![BeastyBlacksmith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/beastyblacksmith/32/4741_2.png) [@BeastyBlacksmith](https://discourse.julialang.org/u/BeastyBlacksmith)\
**Post date:** [September 25, 2018, 9:34am UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/5 "2018-09-25T09:34:40Z")

</div>

you can also take a look at the Paramters package ([https://github.com/mauro3/Parameters.jl](https://github.com/mauro3/Parameters.jl)) which allows to define default values for immutable `struct`s via the `@with_kw` macro.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 12:12pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/6 "2018-09-25T12:12:32Z")

</div>

Adding some more information. I am not a huge fan of saving keystrokes :-). The redefinition of the “\<” operator can be done using the following, which allows for any complexity of the definition of the operator:

```julia
function Base.:<( x::test, y::test )
  if x.a < y.a
    return true
  else
    return false
  end
end

```

Additionally, I found out that any function can be used in this way (this is pretty cool):

```julia
function in( x::Int64, y::test )
  if x == y.a || x == y.b 
    return true
  end
  return false
end
struct test
  a :: Int64
  b :: Int64
end
x = test(1,3)

julia> 2 in x 
false
julia> 3 in x
true

```

EDIT: In consideration of the comment below, the “in” function can be written in concise notation using:

```julia
in(x::Int64, y::test) = x == y.a || x == y.b

```

---

<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:** [September 25, 2018, 12:49pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/7 "2018-09-25T12:49:29Z")

</div>

> [@lmiq](#):
>
> ```julia
> function Base.:<( x::test, y::test )
> if x.a < y.a
> return true
> else
> return false
> end
> end
> 
> ```

I don’t get it. How is this better than

```julia
Base.:<( x::test, y::test ) = x.a < y.a

```

I think all the redundant code obscures what is going on.

Same thing for the `in` function.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 1:00pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/8 "2018-09-25T13:00:33Z")

</div>

I didn’t say it is better, it is just another way to write the same thing.

For this specific example of course the concise notation is very nice. But I was thinking on the possibility where the result of the “x \< y” involves a complex code, in which case knowing that the same thing can be written as any standard function is good, I think.

For example, it could be that evaluating “x \< y” involved solving an optimization problem.

---

<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:** [September 25, 2018, 1:24pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/9 "2018-09-25T13:24:37Z")

</div>

I didn’t really understand the point, I guess. But you mean to point out that you can write it in the ‘standard function format’, like this:

```julia
function Base.:<( x::test, y::test )
    ...
end

```

?

It’s just that I’ve seen before quite a few people write things similar to what you did, such as

```julia
if x == true
    return true
elseif x == false
    return false
end

```

instead of `return x`, and it just seems so _wrong_, I _have_ to say something.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 25, 2018, 1:41pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/10 "2018-09-25T13:41:04Z")

</div>

> [@baggepinnen](#):
>
> An elegant way (I think) of defining methods for operators is
> 
> …

I much prefer prefixing with the module when extending methods. It makes it clear from local context what method you are extending (no need to dig through the source code after import statements).

Also, using infix definition is also scary in my opinion, especially in combination with importing,

```julia
julia> import Base.<

julia> a < b = 3 # typo, should have been ==
Error showing value of type typeof(<):
SYSTEM: show(lasterr) caused an error
TypeError(:parseint_preamble, "if", Bool, 3)

```

and julia crashes

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 2:52pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/11 "2018-09-25T14:52:25Z")

</div>

@DNF Ah, ok. No, I was just trying to point out the structure, and perhaps the example was too simplistic. I am sorry for posting this long code, I don’t know if in general people think that is helpful.

What I meant is something, lets say, like:

```julia
struct quadratic # structure of the data set
  # ax^2 + bx + c
  a::Float64
  b::Float64
  c::Float64
end

function F( f :: quadratic, x :: Float64 ) # F to evaluate the function at x
  return f.a*x^2 + f.b*x + f.c
end 

# the f1 < f2 operation will be true if there is x0 such 
# that f1(x0) < f2(x) for all x.
function Base.:<( f1::quadratic , f2::quadratic )
  if f1.a < 0. && f2.a > 0. # f1 is concave downward, but not f2
    return true
  end
  xmin1 = -f1.b/(2*f1.a) # x that minimizes f1
  xmin2 = -f2.b/(2*f2.a) # x that minimizes f2
  if F(f1,xmin1) < F(f2,xmin2)
    return true
  end
  return false
end

f1 = quadratic(1.,0.,0.)
f2 = quadratic(1.,0.,-1.)
println( f1 < f2 )
println( f2 < f1 )

```

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [September 25, 2018, 5:11pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/12 "2018-09-25T17:11:16Z")

</div>

> [@lmiq](#):
>
> x = test() x.a = 1

Btw, I was using this pattern a lot when coming to Julia - and completely stopped using it over the time.  
I try to avoid initializing empty structs and setting up the fields afterwards as much as I can by now.  
It just doesn’t look as nice, fragments the initialization code of your struct making it harder to read, makes it impossible to use immutables - and worst of all: you may end up with garbage.

So I usually just define a couple of convenience constructors with reasonable default values - and usually I can stop right there since my use cases are covered.  
If that’s not the case for you, the already mentioned [https://github.com/mauro3/Parameters.jl](https://github.com/mauro3/Parameters.jl)) seems like a good solution.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 5:21pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/13 "2018-09-25T17:21:38Z")

</div>

> [@sdanisch](#):
>
> define a couple of convenience constructors with reasonable default values

By that you mean something like this?

```julia
mutable struct test
  a :: Int64
  b :: Float64
  test() = new(1,1.e0) # this line
  test(a,b) = new(a,b)
end

```

---

<div class="post-metadata">

**Author:** ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)\
**Post date:** [September 25, 2018, 5:23pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/14 "2018-09-25T17:23:31Z")

</div>

Yeah something like that… Just usually then as an immutable!  
And quite often I will use keyword arguments for the fields, that I don’t often change!

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 5:39pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/15 "2018-09-25T17:39:05Z")

</div>

> [@sdanisch](#):
>
> use keyword arguments for the fields

Uhm… not sure what that means. I thought you meant something like

```julia
mutable struct test(;a=0,b=1.e0)
   a::Int64
   b::Float64
end
x = test(a=1)

```

as can be done in function, but that seems not to work for structs.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 25, 2018, 5:41pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/16 "2018-09-25T17:41:19Z")

</div>

You put the keywords on the constructor, which is a function (or use [https://github.com/mauro3/Parameters.jl](https://github.com/mauro3/Parameters.jl)).

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 25, 2018, 6:16pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/17 "2018-09-25T18:16:53Z")

</div>

Got it! Make sense! Thank you! (I keep putting the examples, for ignorants like me).

```julia
mutable struct test

  a :: Int64
  b :: Float64
  test(a,b) = new(a,b) # without keywords
  test(;a=1,b=2.e0) = new(a,b) # with keywords (both work!)

end

x = test(a=4,b=5.e0)
println(x)

y = test()
println(y)

z = test(3,5.e0)
println(z)

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [September 25, 2018, 6:34pm UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/18 "2018-09-25T18:34:06Z")

</div>

I would write this as

```julia
mutable struct Test
    a::Int64
    b::Float64
end

Test(; a=1, b=2.0) = Test(a, b) # with keywords (both work!)

```

Capital `T` on struct to comply with style guidelines, no need for `.e0`, and avoiding inner constructors (unless there is a good reason)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [September 26, 2018, 10:57am UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/19 "2018-09-26T10:57:11Z")

</div>

That last example is very clean, but it led me to a think about the possible problems in being able to define a function with the same name of the struct. For example, in this case below, the result is that the first call to test results in defining x as of type test, but the second results in a function value.

Isn’t this problematic, as I could define a new function with the name of a previously defined struct from some module I am using, without knowing it?

(curiously, Julia returns an error if I try to define the struct after the function).

```julia
struct test
  a :: Int64
end

function test(;a=3)
  return a
end

x = test(2)
println(x)
> test(2)

x = test()
println(x)
> 3

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [September 26, 2018, 11:13am UTC](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435/20 "2018-09-26T11:13:38Z")

</div>

> [@lmiq](#):
>
> Isn’t this problematic, as I could define a new function with the name of a previously defined struct from some module I am using, without knowing it?

I don’t think you can, unless you `import` it or qualify it with a module name.

[Next page](https://discourse.julialang.org/t/intialize-types-and-define-operators-within-them/15435.md?page=2)
