Implementing Object Methods and Events?

I’m completely new to Julia (started learning it in my off-time a week ago), and one thing that I’ve had a LOT of trouble finding documentation about is Objects, Methods and Events. By a lot of trouble, what I mean is that I can’t really find anything.

For reference, I’m coming from VB/C# – where you can essentially just do, for example, a class “car” with a method “vroom”, and then you’d declare something like “var X = new Car(); X.vroom()”.
I haven’t really found much similar for Julia, which is a little troubling, since so many things are made easier through objects and become extremely difficult to do without proper object implementation. Similarly, I couldn’t find much on Events (like for example if I have a text area, I can have a handler for a Keypress event so that if someone presses a key, and EventArgs.KeyChar = 1 → do some code, so I can prevent someone from entering, say, a letter in a number field and vice versa).

This is pretty troubling for me because not having access to objects would just make everything so, so much harder for anything beyond small projects. Is there documentation I’ve missed or something?

Those are both concepts from Object Oriented Programming, which Julia doesn’t subscribe to. But don’t worry, they aren’t as important as you think they are.

In most languages I’ve worked with, obj.method(x) is just a convenience for method(obj, x). In single dispatch this makes sense, because the first argument is more important than the second. But Julia has multiple dispatch, so which method is called depends on the typeof both obj and x. In short, just define function(obj, x), you’ll be fine.

When it comes to events, that’s just a function that is called at a specific moment, right? I’m sure whichever GUI framework you use has a guide on how theirs work.

Edit:

You can add functions as fields in a struct (“class”), but that’s not quite the same, because it’s a function handle specific to the instance. It will very rarely be what you want.

1 Like

So, for example, I would do something that looks like this, right?

struct dummyclass
     property1
     property2
     property3
end

function foo(dummyclass)
     x = dummyclass.property1 * 2
     return x
end

However, that brings me another question; this seems… very, very verbose. So is the only faster way to write it out to be [the following]

function foo(x)
     if(typeof(x) == dummyclass)
          <code>
     end
end

I don’t think that’ll do quite what you think. It’s standard (but not required) to capitalize types in julia, and I will do so here to clarify.

struct MyType
    prop1
    prop2
    prop3
end

function f(x::MyType)
    return 2*x.prop1
end

# or the equivalent, less verbose version
f(x::MyType) = 2*x.prop1

This essentially means “if x is a MyType, use this method.” (Where “method” means “specific implementation of a function”, i.e. the version of a function for a specific signature)

2 Likes

Thank you for taking the time to reply! I’ll go test things out :slight_smile:

one insight I got for you is, if X::Car, then X.f() in julia just means you have a function f(x::Car), and if you have X.f(z), then it just means you have a function f(x::Car, z). My point is that it’s just a syntax. think of all your python OOP member function starts with a mandatory self argument, here you just have to define that self explicitly.

The difference is of course that in Julia you can dispatch on the set of all arguments, in OOP you’re restrict to the one argument, i.e.

# 3+5 is actually
3.add(5)
# and then you realize
3.add(5.0) #doesn't make sense because 5.0 and 5 are different types 
#so how does this really work?

where in Julia +(x::Int, y::Int) and +(x::Int, y::Float64) can be two different methods, which of course is silly in this specific case, but you get my idea hopefully

1 Like

One more small thing that you might expect from OOP is class properties, where a class (not just its instances) can hold values. This is not a thing in julia. It’s also pretty meaningless. You can define something like speed(::Type{Horse}) = "Fast" so that speed(Horse) can be used to query the speed of the type Horse, if this is something you really need.

2 Likes