Strange behaviour with if-else-Statements

Hello,

I’m new to Julia and working with Julia/JuMP for optimization purposes. I want to use if-else-statements in the constraints I’m defining to write them more compact. When trying so I ran in some strange behaviour.

Im using Julia v1.5.1 and JuMP v0.21.3.

1.) Just Julia: Writing the following into a .jl and running with include()

if 1 == 2
    1
end
+ 5

returns the correct value 5 .

But writing the following into a .jl and running with include() gives an error.

if 1 == 2  1  end + 5

The Error is: ERROR: LoadError: MethodError: no method matching +(::Nothing, ::Int64)

2.) Using Julia and JuMP: When defining the following function Test() the resulting constraint con in the .lp file is not like you would expect it

using JuMP

m = Model()

function Test(m::Model,set_constr::Int64)

    @variable(m, x[1:5]>=0)

    @constraint(m,con, 
                if set_constr == 1  
                    x[1]
                else 
                    if set_constr == 2
                        0.1*x[2]
                    end
                    +
                    x[4]
                    +
                    if set_constr == 3
                        x[5]
                    else 0 end
                end
                <= 0)

    JuMP.write_to_file(m, "model.lp")
    empty!(m)   
end 

For Test(m,1) we get: con: 1 x_1_ <= 0 like we want to have.

For Test(m,2) we get: con: <= 0 while we would like to get con: 0.1 x_2_ + x_4_ <= 0

For Test(m,3) we get con: 1 x_5_ <= 0 while we would like to get con: x_4_ + x_5_ <= 0

Is my understanding of the if-else-statement false here or is this a bug?

Thanks for your help and kind regards

Konstantin

1 Like

This is not a bug. Starting a line with + doesn’t connect it with the previous line.

julia> 5
5

julia> +5
5

julia> 5 + 5
10

This is what’s happening

julia> if true
           10
       end + 5
15

julia> if false
           10
       end + 5
ERROR: MethodError: no method matching +(::Nothing, ::Int64)

You’re hitting the else case (i.e. your condition is false) which returns nothing. Nothing + Int is an error. The reason putting +5 on a new line works is because it’s parsed as

nothing # this line does nothing
+5 # +5 === 5, coincidentally this is what you wanted, but not for the right reason

You can use ternary expressions for compact if statements

x = 1 == 2 ? 15 : 10

Or you can use the boolean to do something directly if that makes sense in context

x = 10 + 5 * (1 == 2)
8 Likes

By the way, if for some reason you really want to write it that way, you can always just stick in a semi-colon to act as a newline:

julia> if false
           10
       end; + 5
5
2 Likes

It seems, as tomerarnon mentioned, a + in the beginning of a line in Julia does not represent a continuation of the line before. See:

Parentheses (or + at the end of the line) allows Julia to recognize the multiline code.

2 Likes

Thank you very much for your reply and the explanation! I see the problem with what I wrote.

1 Like