# No method matching problem in optimization in nested function definition

**URL:** <https://discourse.julialang.org/t/no-method-matching-problem-in-optimization-in-nested-function-definition/92298>\
**Category:** General Usage\
**Tags:** question, optimization\
**Created:** [December 30, 2022, 12:33am UTC](https://discourse.julialang.org/t/no-method-matching-problem-in-optimization-in-nested-function-definition/92298 "2022-12-30T00:33:24Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![csmarra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/csmarra/32/45480_2.png) [@csmarra](https://discourse.julialang.org/u/csmarra)\
**Post date:** [December 30, 2022, 12:33am UTC](https://discourse.julialang.org/t/no-method-matching-problem-in-optimization-in-nested-function-definition/92298/1 "2022-12-30T00:33:24Z")

</div>

Hello everybody,  
I am new to Julia and I am struggling to understand the behaviour of the following code, in which I perform the minimization of a function using the package BlackBoxOptim.

```julia
function includeProof(z::Real, x::Real)
    RangePoints=(-5.0, 5.0)
    function ToMin(y::Real)
        (1.0 - z*x)^2 + 100.0 * (x - (y+x)^2)^2
    end
    res = bboptimize(ToMin; SearchRange = RangePoints, NumDimensions=1)
end

```

```julia
see = includeProof(1.1,1.1)

```

In particular, I would expect that this piece of code returned the output of res.  
However, the following error appears

```julia
MethodError: no method matching (::var"#ToMin#2"{Float64, Float64})(::Vector{Float64})
Closest candidates are:
  (::var"#ToMin#2")(::Real) at In[4]:3

Stacktrace:
 [1] fitness(x::Vector{Float64}, p::FunctionBasedProblem{var"#ToMin#2"{Float64, Float64}, ScalarFitnessScheme{true}, ContinuousRectSearchSpace, Nothing})
   @ BlackBoxOptim ~/.julia/packages/BlackBoxOptim/I3lfp/src/problem.jl:61
 [2] setup_problem(func::Function, parameters::ParamsDictChain)
   @ BlackBoxOptim ~/.julia/packages/BlackBoxOptim/I3lfp/src/bboptimize.jl:37
 [3] bbsetup(functionOrProblem::Function, parameters::Dict{Symbol, Any}; kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:SearchRange, :NumDimensions), Tuple{Tuple{Float64, Float64}, Int64}}})
   @ BlackBoxOptim ~/.julia/packages/BlackBoxOptim/I3lfp/src/bboptimize.jl:111
 [4] bboptimize(functionOrProblem::Function, parameters::Dict{Symbol, Any}; kwargs::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:SearchRange, :NumDimensions), Tuple{Tuple{Float64, Float64}, Int64}}})
   @ BlackBoxOptim ~/.julia/packages/BlackBoxOptim/I3lfp/src/bboptimize.jl:92
 [5] includeProof(z::Float64, x::Float64)
   @ Main ./In[4]:6
 [6] top-level scope
   @ In[5]:1
 [7] eval
   @ ./boot.jl:368 [inlined]
 [8] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base ./loading.jl:1428

```

I do not get why there is a method error and, in particular, where does this piece

```julia
 (::var"#ToMin#2"{Float64, Float64})(::Vector{Float64})

```

come from.  
Thanks a lot!

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [December 30, 2022, 12:59am UTC](https://discourse.julialang.org/t/no-method-matching-problem-in-optimization-in-nested-function-definition/92298/2 "2022-12-30T00:59:51Z")

</div>

> [@csmarra](#):
>
> `function ToMin(y::Real)`

Never worked with `BlackBoxOptim.jl`, but I guess the error message is telling you that it cannot work with `ToMin`. Maybe just try

```julia
function ToMin(y)
        (1.0 - z*x)^2 + 100.0 * (x - (y[1]+x)^2)^2
end

```

As a general rule for programming in Julia:

- Keep function definitions as **general** as possible,
- but make type definitions as **strict** as possible. (not shown in this example)

---

<div class="post-metadata">

**Author:** ![uniment](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/uniment/32/24532_2.png) [@uniment](https://discourse.julialang.org/u/uniment)\
**Post date:** [December 30, 2022, 3:58am UTC](https://discourse.julialang.org/t/no-method-matching-problem-in-optimization-in-nested-function-definition/92298/3 "2022-12-30T03:58:39Z")

</div>

> [@csmarra](#):
>
> where does this piece
> 
> ```julia
> (::var"#ToMin#2"{Float64, Float64})(::Vector{Float64})
> 
> ```
> 
> come from.

When you declare a function `ToMin` in the local scope of `includeProof`, it is actually hoisted to global scope for compilation (this is what allows returned functions to exist beyond the scope of the function that created them). To avoid name collisions, it is given an auto-generated unique identifier like `var"#ToMin#2"`. Within local scope it’s a named function accessed by the identifier `ToMin`, but in global scope it’s anonymous. The identifier increments every time you compile `includeProof`.

Consider this simple example:

```julia
julia> function f(x)
           g() = x
       end
f (generic function with 1 method)

julia> f(42)
(::var"#g#1"{Int64}) (generic function with 1 method)

julia> typeof(f(42))
var"#g#1"{Int64}

julia> f(42)()
42

julia> f(42) === f(42)
true

julia> f(42) === f(69)
false

julia> typeof(f(42)) === typeof(f(69))
true

```

Notice that the type of object returned is `var"#g#1"{Int64}`. This signifies that the function is actually an object with a single `Int64` field storing a value (in this case 42, which gets loaded into the struct whenever `f` is called on that value). (Notably, in Julia, functions are objects and [objects are functions](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects).)

You can actually access the type `var"#g#1"` from global scope. It’s not very useful, because no constructor is provided, but we can see its structure:

```julia
julia> typeof(var"#g#1"{Int64})
DataType

julia> dump(var"#g#1"{Int64})
var"#g#1"{Int64} <: Function
  x::Int64

```

Conceptually, it’s as if the following code had been executed:

```julia
struct var"#g#1"{T}<:Function
    x::T
end
(g::var"#g#1")() = g.x

```

and calling `f` constructs such an object and returns it.

To explore how it works, we can add methods:

```julia
julia> (g::var"#g#1"{Int64})(y) = g.x + y

julia> f(42)
(::var"#g#1"{Int64}) (generic function with 2 methods)

julia> f(42)(27)
69

```

we can also hack it so that it doesn’t work properly anymore:

```julia
julia> (::var"#g#1"{Int64})() = 69

julia> f(42)()
69

```

None to worry, if we force `f` to recompile then we get a new identifier and it works how it did before our hacking:

```julia
julia> function f(x)
           g() = x
       end
f (generic function with 1 method)

julia> f(42)
(::var"#g#2"{Int64}) (generic function with 1 method)

julia> f(42)()
42

```

You’re never going to want to do this to anonymous functions of course, because their name changes every time you recompile, but that should answer your question.

The error you see indicates that `bboptimize` is trying to call `ToMin` on a `Vector` of `Float64`’s, but you declared `ToMin` to instead take a single `Real`. Unsurprisingly, it throws an error.

* * *

As an aside, it’s considered un[idiomatic](https://docs.julialang.org/en/v1/manual/style-guide/#Use-naming-conventions-consistent-with-Julia-base/) to use CamelCase for the names of functions and objects; you should instead use snake\_case, and reserve CamelCase for type and module names. Consider renaming your functions to `include_proof` and `to_min`, and your object to `rangepoints`.
