# Can a function returns a partial function?

**URL:** <https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413>\
**Category:** New to Julia\
**Created:** [December 18, 2019, 12:14am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413 "2019-12-18T00:14:07Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![tog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tog/32/11858_2.png) [@tog](https://discourse.julialang.org/u/tog)\
**Post date:** [December 18, 2019, 12:14am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/1 "2019-12-18T00:14:07Z")

</div>

Hi,  
I am new to Julia coming from Python. In Python we have the “partial” function that allow to derive a function by fixing some arguments. Can we do something similar in Julia?  
I would like to do something like:

function f(x, y, z)  
x + y + z  
end

and then create a function g(x) = f(x, y=computed\_y(), z=computed\_z())

I can obviously define f as f(x; y…, z=…) and then call f(x) but I have the feeling that computed\_y and computed\_z are called very time I call f while I would like them to be computed once only.

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [December 18, 2019, 12:45am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/2 "2019-12-18T00:45:10Z")

</div>

How about this?

```julia
f(x, y, z) = x + y + z

computed_y() = (println("y_comp"); 2)
computed_z() = (println("z_comp"); 3)

g = let y, z
    y = computed_y()
    z = computed_z()
    g(x) = f(x, y, z)
end

g(1) == 6

```

Maybe a little bit awkward.

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [December 18, 2019, 1:04am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/3 "2019-12-18T01:04:14Z")

</div>

See this discussion [Is there a package to that can make partial functions automatically?](https://discourse.julialang.org/t/is-there-a-package-to-that-can-make-partial-functions-automatically/31292)

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [December 18, 2019, 4:39am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/4 "2019-12-18T04:39:04Z")

</div>

I think this is much better:

```julia
f(x, y, z) = x + y + z

computed_y() = (println("y_comp"); 2)
computed_z() = (println("z_comp"); 3)

@eval g(x) = f(x, $(computed_y()), $(computed_z()))

g(1) == 6

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 18, 2019, 7:16am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/5 "2019-12-18T07:16:14Z")

</div>

You should not need `eval` for this. A closure is fine, eg

```julia
f(x, y, z) = x + y + z
y, z = 2, 3
g = x -> f(x, y, z)
g(1)

```

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [December 18, 2019, 7:23am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/6 "2019-12-18T07:23:07Z")

</div>

The reason is…@tog seems to want one liner, plus he seems to like to know how to interpolate computed\_y() stuff into the arguments once and for all, not every time of invocation. Practically, you are right. 🙂

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 18, 2019, 7:34am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/7 "2019-12-18T07:34:12Z")

</div>

> [@Sijun](#):
>
> interpolate computed\_y() stuff into the arguments once and for all, not every time of invocation

I am not sure I understand what is meant here.

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [December 18, 2019, 7:47am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/8 "2019-12-18T07:47:47Z")

</div>

When we define g(x) in this way:  
`g(x) = f(x, computed_y(), computed_z())`

Everytime we call g(x), computed\_y() and computed\_z() will have to be calculated.

What if we seek for an expression that looks very much like `g(x) = f(x, computed_y(), computed_z())` but that takes the values of computed\_x() and computed\_y() only at the time of defining g(x)? I thought this was what @tog was really curious about, and `@eval g(x) = f(x, $(computed_y()), $(computed_z()))` may be close to what he looks for.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [December 18, 2019, 8:17am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/9 "2019-12-18T08:17:43Z")

</div>

You definitely don’t need and should not use `eval` for this, a simple closure will do. Eg

```julia
let y, z = computed_y(), computed_z()
    x -> f(x, y, z)
end

```

or similar.

---

<div class="post-metadata">

**Author:** ![Sijun](https://avatars.discourse-cdn.com/v4/letter/s/b2d939/32.png) [@Sijun](https://discourse.julialang.org/u/Sijun)\
**Post date:** [December 18, 2019, 8:23am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/10 "2019-12-18T08:23:30Z")

</div>

I agree eval should be used with care since its evaluation goes into global scope. Definitely the kind of expression I suggested should be discouraged.

---

<div class="post-metadata">

**Author:** ![tog](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tog/32/11858_2.png) [@tog](https://discourse.julialang.org/u/tog)\
**Post date:** [December 19, 2019, 12:22am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/11 "2019-12-19T00:22:25Z")

</div>

@Sijun and @Tamas_Papp  
I think you have understood what I want to do i.e not recompute y & z each time the one argument instance is called.  
I am not sure I understand what you meant by global scope. I am not sure it is a good idea to make visible to new variables y & z as proposed initially by @Tamas_Papp  
I need to understand the let construct does it create the y & z variables and leave only visible inside the let ? are they recomputed each time I call g(something) ?

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [December 19, 2019, 12:49am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/12 "2019-12-19T00:49:23Z")

</div>

> [@tog](#):
>
> does it create the y & z variables and leave only visible inside the let

Yes, that’s right. For example:

```julia
julia> let x = 1, y = 2
         println("inside the let block, we can see x and y: ", x, " ", y)
       end
inside the let block, we can see x and y: 1 2

julia> x
ERROR: UndefVarError: x not defined

julia> y
ERROR: UndefVarError: y not defined

```

> [@tog](#):
>
> are they recomputed each time I call g(something) ?

No, and we can show it by making the `computed_x` and y function print something every time they are called, as @Sijun did.

For example:

```julia
julia> f(x, y) = x + y
f (generic function with 1 method)

julia> function computed_y()
         println("computing y")
         2
       end
computed_y (generic function with 1 method)

julia> const y = computed_y()
computing y
2

julia> g(x) = f(x, y)
g (generic function with 1 method)

julia> g(1)
3

```

Notice how `computing y` is only printed once when we define the variable `y`. If you want to avoid making the `y` variable visible, you can hide it in a `let` block, as suggested above:

```julia
julia> const g2 = 
         let y2 = computed_y()
           x -> f(x, y2)
         end
computing y
#3 (generic function with 1 method)

julia> g2(1)
3

```

Again, `computing y` is only printed once, when you define the function g2.

And in this case, `y2` is only visible inside the `let` block:

```julia
julia> y2
ERROR: UndefVarError: y2 not defined

```

---

<div class="post-metadata">

**Author:** ![rvignolo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rvignolo/32/33498_2.png) [@rvignolo](https://discourse.julialang.org/u/rvignolo)\
**Post date:** [December 19, 2019, 1:19am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/13 "2019-12-19T01:19:36Z")

</div>

Hi @tog, welcome. Regarding your question:

> [@tog](#):
>
> and then create a function g(x) = f(x, y=computed\_y(), z=computed\_z())

Yes, you can create the function `g(x)`. However, in Julia, this is called a `closure` and you can check what it does in the documentation, [here](https://docs.julialang.org/en/v1/devdocs/functions/#Closures-1).

You can read about global scope in [here](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope-1), it is important.

Once you figure out the global scope meaning, you will see that the closure must not use global variables, because of performance issues (see [here](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-captured-1)).

Following all these documents you will see why @Tamas_Papp example is correct:

> [@Tamas\_Papp](#):
>
> let y, z = computed\_y(), computed\_z() x → f(x, y, z) end

Or why @rdeits is using `const`:

> [@rdeits](#):
>
> julia\> const y = computed\_y() computing y 2

etc…

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [December 19, 2019, 1:50am UTC](https://discourse.julialang.org/t/can-a-function-returns-a-partial-function/32413/14 "2019-12-19T01:50:05Z")

</div>

Correctly using closure in global scope to get Python semantics of default arguments is rather cumbersome as you need to use the `global` keyword

```julia
let y, z
    y = computed_y()
    z = computed_z()
    global g(x) = f(x, y, z)
end

```

Note that, without `global`, you can’t add methods to `g`.

Comparing this to `@eval g(x) = f(x, $(computed_y()), $(computed_z()))`, I don’t think it’s necessary bad to use `@eval`, provided that you understand why you need it.
