Skip to content

Conventional object-oriented programming in Julia without breaking Julia's core design ideas

License

Notifications You must be signed in to change notification settings

Suzhou-Tongyuan/ObjectOriented.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

89 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ObjectOriented

Stable Dev Build Status

ObjectOriented.jl is a mechanical OOP programming library for Julia. The design is mainly based on CPython OOP but adapted for Julia.

The supported features:

  • multiple inheritances
  • using dot operators to access members
  • default field values
  • overloaded constructors and methods
  • Python-style properties (getters and setters)
  • generics for the OOP system
  • interfaces

Check out our documentation.

We recommend you to read How to Translate OOP into Idiomatic Julia before using this package. If you understand your complaints about Julia's lack of OOP come from your refutation of the Julia coding style, feel free to use this.

For people who want to use this package in a more Julian way, you can avoid defining methods (and Python-style properties) with @oodef.

Preview

@oodef mutable struct MyClass <: MySuperClass
    a::Int
    b::Int

    function new(a::Integer, b::Integer)
        self = @mk
        self.a = a
        self.b = b
        return self
    end

    function compute_a_plus_b(self)
        self.a + self.b
    end
end

julia> inst = MyClass(1, 2)
julia> inst.compute_a_plus_b()
3

A more concise rewrite using @mk is:

@oodef mutable struct MyClass <: MySuperClass
    a::Int
    b::Int

    function new(a::Integer, b::Integer)
        @mk begin
            a = a
            b = b
        end
    end

    function compute_a_plus_b(self)
        self.a + self.b
    end
end

julia> inst = MyClass(1, 2)
julia> inst.compute_a_plus_b()
3

Hints For Professional Julia Programmers

As the dot method (self.method()) is purely a syntactic sugar thing, using the idiomatic Julia code like method(self) is usually better. Using the idiomatic Julia methods, method ambiguity can be avoided, which is of course better than OOP in this case.

You can avoid defining dot methods as shown below:

@oodef struct MyType
    field1::Int
    field2::Int
    function new(a, b)
        @mk begin
            field1=a
            field2=b
        end
    end

    #= not Julian:
    function some_func(self)
       return self.field1 + self.field2
    end
    =#
end

# Julian way:
function some_func(self :: @like(MyType)) # @like(...) accepts subtypes
    self.field1 + self.field2
end

@oodef struct MyDerivedType <: MyType
    c::Int
    function new(a, b, c)
        @mk begin
            MyType(a, b)
            c = c
        end
    end
end

some_func(MyType(1, 2)) # 3
some_func(MyDerivedType(1, 2, 3)) # 3

Troubleshooting

  1. The integrated debugger implemented in Julia-VSCode cannot handle @generated functions, which causes a bug when entering @mk expressions. A workaround can be made as follows:

    @oodef mutable struct YourClass
         x::Int
         y::Int
         function new(x, y)
             # you can debug here
             self = @mk begin
                 # you can debug here
                 x = x
                 # you can debug here
                 y = y
                 # do not reach here!
                 # please jump over the end of '@mk' expression!
             end
             # you can debug here
             return self
         end
    end

About

Conventional object-oriented programming in Julia without breaking Julia's core design ideas

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published