Conditional function implementation

Please have a look at the code below.

#!/usr/bin/env julia

bad_func()::Nothing = println("Default") # Commented in: Case A. Commented out: Case B.

function conditional_implementation(choice::Int64)::Nothing
	println("conditional_implementation(...): Started. choice $choice")
	bad_func()::Nothing = println("Inner definition") # Commented in: Case P. Commented out: Case Q.

	if choice == 1
		bad_func()::Nothing = println("Defined for choice is 1")
		bad_func()
	elseif choice == 2
		bad_func()::Nothing = println("Defined for choice is 2")
		bad_func()
	elseif choice == 3
		bad_func()::Nothing = println("Defined for choice is 3")
		bad_func()
	end
	
	return nothing
end

# bad_func()::Nothing = println("Another default")
conditional_implementation(1)
conditional_implementation(2)
conditional_implementation(3)

This defines four cases: AP, AQ, BP and BQ. It is also interesting to play with commenting out the last four lines but that makes this posting very complex.

Case AP:

WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:7 overwritten at /tmp/conditional_function_impl.jl:10.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:10 overwritten at /tmp/conditional_function_impl.jl:13.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:13 overwritten at /tmp/conditional_function_impl.jl:16.
conditional_implementation(...): Started. choice 1
Defined for choice is 3
conditional_implementation(...): Started. choice 2
Defined for choice is 3
conditional_implementation(...): Started. choice 3
Defined for choice is 3

Case AQ:

WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:10 overwritten at /tmp/conditional_function_impl.jl:13.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:13 overwritten at /tmp/conditional_function_impl.jl:16.
conditional_implementation(...): Started. choice 1
Defined for choice is 3
conditional_implementation(...): Started. choice 2
ERROR: LoadError: UndefVarError: `bad_func` not defined
Stacktrace:
 [1] conditional_implementation(choice::Int64)
   @ Main /tmp/conditional_function_impl.jl:14
 [2] top-level scope
   @ /tmp/conditional_function_impl.jl:24
in expression starting at /tmp/conditional_function_impl.jl:24

Case BP:

WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:7 overwritten at /tmp/conditional_function_impl.jl:10.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:10 overwritten at /tmp/conditional_function_impl.jl:13.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:13 overwritten at /tmp/conditional_function_impl.jl:16.
conditional_implementation(...): Started. choice 1
Defined for choice is 3
conditional_implementation(...): Started. choice 2
Defined for choice is 3
conditional_implementation(...): Started. choice 3
Defined for choice is 3

Case BQ:

WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:10 overwritten at /tmp/conditional_function_impl.jl:13.
WARNING: Method definition bad_func() in module Main at /tmp/conditional_function_impl.jl:13 overwritten at /tmp/conditional_function_impl.jl:16.
conditional_implementation(...): Started. choice 1
Defined for choice is 3
conditional_implementation(...): Started. choice 2
ERROR: LoadError: UndefVarError: `bad_func` not defined
Stacktrace:
 [1] conditional_implementation(choice::Int64)
   @ Main /tmp/conditional_function_impl.jl:14
 [2] top-level scope
   @ /tmp/conditional_function_impl.jl:24
in expression starting at /tmp/conditional_function_impl.jl:24

All of the variants use the last implementation of bad_func. Some variants (AQ, for instance) crash although bad_func is clearly defined and even succesfully called before. What are the reasons behind this behavior?

To be more precise, there’s only 1 inner function. It’s the methods you’re trying to make conditional, and that isn’t supported well in Julia in order to allow the enclosing function to be optimized when compiled. If possible, then do what you intend with conditional functions, separate ones.

You’re running into disallow methods of local functions in different blocks · Issue #15602 · JuliaLang/julia · GitHub and this is also warned against in the docs.

3 Likes