Suzhou-Tongyuan/ObjectOriented.jl

[Documentation Troubleshooting]: Implementing if-else block in @mk gives `invalid construction statement ` error

Shuvomoy opened this issue · 2 comments

I am trying to implement the following Python class into equivalent Julia code using ObjectOriented.jl

## Python code
class MyType8:
    def __init__(self, a_input=30, b_input=50):
        # Clamping a_input within the range 0 to 100
        if a_input < 0:
            self.a = 0
        elif a_input > 100:
            self.a = 100
        else:
            self.a = a_input
            print("a_input is in the correct range")
        
        self.b = b_input

def myfun_type8(self):
    return self.a ** 2

def myfun2_type8(self, other):
    return self.a ** 2 + self.b ** 2 + other ** 2

# Creating instances
test1 = MyType8()

test2 = MyType8(a_input=200, b_input=50)

# Using the functions
result1 = myfun_type8(test2)
print("Result of myfun_type8(test2):", result1)

result2 = myfun2_type8(test2, 100)
print("Result of myfun2_type8(test2, 100):", result2)

It seems that ObjectOriented.jl does not accept if-else statement within an @mk block. For example the following code returns the error LoadError: invalid construction statement if a_input < 0:

## Julia code 
using ObjectOriented
@oodef mutable struct MyType8

    a
    b

    function new(; a_input = 30, b_input = 50)

        
        @mk begin
            if a_input < 0
                a = 0
            elseif a_input > 100
                a = 100
            else
                @info "a_input is in the correct range"
            end
            b = b_input
        end
     
    end

end

@mk is a shorthanded representation for something like a function call, where an LHS like a in a = 0 works like a keyword argument.

You may know the following 2 examples are not equivalent:

# case 1
a_input < 0  ? func(a = 1) : func(a = 100)

# case 2
func(a_input < 0 ? (a = 1) : (a=100))

The solution is to lift your if-else up:

@oodef mutable struct MyType8
  
    a  # I recommend you to use Generics or concrete types here
    b

    function new(; a_input = 30, b_input = 50)
        if a_input < 0
            a = 0
        elseif a_input > 100
            a = 100
        else
            @info "a_input is in the correct range"
            a = a_input
        end

        b = b_input;
        @mk begin
            a = a
            b = b
        end
    end
end

Writing the logics this way also helps me find out a potential bug (missing a when a_input in the correct range) in your example.

It makes sense, closing the issue. It may help to include similar examples in the documentation in the future. Thanks very much again!