# Can FunctionWrappers.jl express higher order functions?

**URL:** https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404
**Category:** General Usage
**Tags:** type, functions
**Created:** [August 14, 2021, 9:03pm UTC](https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404 "2021-08-14T21:03:03Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)
#### Post date: [August 14, 2021, 9:03pm UTC](https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404/1 "2021-08-14T21:03:03Z")

</div>

I’m looking into FunctionWrappers.jl which provides functionality similar to function pointers in C and `std::function` in C++. Suppose a function accept two arguments, where the first argument has type Int, and the second argument is a function of signature Int → Int, e.g. x-\>x+1. Can I wrap the “outer” function in a type-stable manner? Since I need to specify the type signature of both the outer function and the inner function that appears as an argument, this seems impossible unless FunctionWrappers can be used in a nested manner?

---

<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: [August 14, 2021, 9:11pm UTC](https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404/2 "2021-08-14T21:11:18Z")

</div>

Yup, that should just work, although admittedly the syntax is pretty verbose:

```julia
julia> using FunctionWrappers: FunctionWrapper

julia> g = FunctionWrapper{Int, Tuple{Int}}(x -> x + 1)
FunctionWrapper{Int64, Tuple{Int64}}(Ptr{Nothing} @0x00007fe8068f8700, Ptr{Nothing} @0x00007fe854eacb90, Base.RefValue{var"#9#10"}(var"#9#10"()), var"#9#10")

julia> f = FunctionWrapper{Int, Tuple{Int, FunctionWrapper{Int, Tuple{Int}}}}((y, g) -> g(y))
FunctionWrapper{Int64, Tuple{Int64, FunctionWrapper{Int64, Tuple{Int64}}}}(Ptr{Nothing} @0x00007fe8068f9b40, Ptr{Nothing} @0x00007fe854eacbb0, Base.RefValue{var"#11#12"}(var"#11#12"()), var"#11#12")

julia> f(1, g)
2

```

---

<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: [August 14, 2021, 9:56pm UTC](https://discourse.julialang.org/t/can-functionwrappers-jl-express-higher-order-functions/66404/4 "2021-08-14T21:56:10Z")

</div>

By the way, this overly verbose syntax is a great excuse to write a macro:

```julia
using MacroTools
using FunctionWrappers: FunctionWrapper

wrapperize(x) = esc(x)

function wrapperize(expr::Expr)
	if expr.head == :block
		return Expr(:block, wrapperize.(expr.args)...)
	elseif expr.head == :tuple
		return Expr(:tuple, wrapperize.(expr.args)...)
	elseif @capture(expr, (inputs__,) -> output_)
		return :(FunctionWrapper{$(wrapperize(output)), Tuple{$(wrapperize.(inputs)...)}})
	elseif @capture(expr, (input_) -> output_)
		return :(FunctionWrapper{$(wrapperize(output)), Tuple{$(wrapperize(input))}})
	else
		error("I can only handle expressions of the form `(inputs...) -> output`")
	end
end

macro fn(expr)
	wrapperize(expr)
end

```

Examples:

```julia
julia> @fn Int -> Int
FunctionWrapper{Int64, Tuple{Int64}}

julia> @fn (Int, Float64) -> Int
FunctionWrapper{Int64, Tuple{Int64, Float64}}

julia> @fn (Float64, Int -> Int) -> String
FunctionWrapper{String, Tuple{Float64, FunctionWrapper{Int64, Tuple{Int64}}}}

```
