# Inability to pass function with type parameters as an argument

**URL:** <https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843>\
**Category:** Language Support\
**Tags:** Motoko\
**Created:** [March 6, 2023, 5:57pm UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843 "2023-03-06T17:57:45Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![ZhenyaUsenko](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zhenyausenko/32/12200_2.png) [@ZhenyaUsenko](https://forum.dfinity.org/u/ZhenyaUsenko)\
**Post date:** [March 6, 2023, 5:57pm UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/1 "2023-03-06T17:57:45Z")

</div>

![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/2X/2/21860e543f8884b5eb322d2c27e2c6e7d8089360.png)

We have 2 functions

1. **identity** just returns its first argument
2. **test** accepts a **Nat → Nat** function and calls it

Why cannot we use **identity** as an argument for the **test** function?  
I am getting _“expression of type … cannot produce expected type”_ error.

---

<div class="post-metadata">

**Author:** ![Gekctek](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/gekctek/32/6863_2.png) [@Gekctek](https://forum.dfinity.org/u/Gekctek)\
**Post date:** [March 7, 2023, 12:01am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/2 "2023-03-07T00:01:53Z")

</div>

I cant speak to the technical reason but you can get around it with another function  
`ignore test(func (n: Nat) = identity<Nat>(n));`  
[https://m7sm4-2iaaa-aaaab-qabra-cai.ic0.app/?tag=1307026162](https://m7sm4-2iaaa-aaaab-qabra-cai.ic0.app/?tag=1307026162)

---

<div class="post-metadata">

**Author:** ![ZhenyaUsenko](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zhenyausenko/32/12200_2.png) [@ZhenyaUsenko](https://forum.dfinity.org/u/ZhenyaUsenko)\
**Post date:** [March 7, 2023, 11:10am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/3 "2023-03-07T11:10:34Z")

</div>

It is a good thing there is a way to get around it, yet still I hope we’d be able to do it the correct way one day

I think it works in the example you shared because we explicitly specify `<Nat>` parameter  
On the other hand, if we don’t call the **identity** function (just pass it around, as in my example), there is no way to explicitly specify the parameter

---

<div class="post-metadata">

**Author:** ![ZhenyaUsenko](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zhenyausenko/32/12200_2.png) [@ZhenyaUsenko](https://forum.dfinity.org/u/ZhenyaUsenko)\
**Post date:** [March 8, 2023, 4:09pm UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/4 "2023-03-08T16:09:51Z")

</div>

@claudio What do you think about the error above? Are there any plans to support it in the future?

---

<div class="post-metadata">

**Author:** ![timo](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/timo/32/5543_2.png) [@timo](https://forum.dfinity.org/u/timo)\
**Post date:** [March 9, 2023, 6:14am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/5 "2023-03-09T06:14:49Z")

</div>

Do you mean you want to be able to write:

```auto
ignore test(identity<Nat>);

```

?

---

<div class="post-metadata">

**Author:** ![ZhenyaUsenko](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zhenyausenko/32/12200_2.png) [@ZhenyaUsenko](https://forum.dfinity.org/u/ZhenyaUsenko)\
**Post date:** [March 9, 2023, 9:20am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/6 "2023-03-09T09:20:57Z")

</div>

Hopefully, It works even without `<Nat>`. But `identity<Nat>` would be a good workaround

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [March 9, 2023, 9:41am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/7 "2023-03-09T09:41:40Z")

</div>

I sympathize with this and it is definitely what users expect from ML-like languages (SML, OCaml, F#, Haskell).

Unfortunately, it might actually be problematic for the subtyping we use in Motoko, i.e. it is possible it makes subtyping undecidable. Would need to look at the literature to be sure.

---

<div class="post-metadata">

**Author:** ![ZhenyaUsenko](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zhenyausenko/32/12200_2.png) [@ZhenyaUsenko](https://forum.dfinity.org/u/ZhenyaUsenko)\
**Post date:** [March 9, 2023, 11:48am UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/8 "2023-03-09T11:48:56Z")

</div>

It is strange that inline function works here even without specifying parameter type and return type  
`ignore test(func(n) = identity(n));` (modified @Gekctek’s suggestion)  
but we still can not pass a function with type parameters directly

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [May 22, 2023, 1:35pm UTC](https://forum.dfinity.org/t/inability-to-pass-function-with-type-parameters-as-an-argument/18843/9 "2023-05-22T13:35:46Z")

</div>

Type instantiation is part of function call syntax in Motoko, it does not exist as a stand-alone thing – dually, you cannot introduce generic parameters without function parameters, and there are no generic types independent from functions. It behaves similar to most conventional languages rather than ML-style ones in that regard.

There are a few technical reasons for this, which have to do with compilation, side effects, and the lack of partial application in Motoko. FWIW, I don’t think subtyping poses a problem here, it primarily comes down to a form of currying (with runtime type passing, it literally is), but Motoko does not support that either.

@ZhenyaUsenko, this is no different from regular parameters, where you cannot pass a two-argument function `f` as `test(f(3))`, but have to write `test(func(n) = f(3, n))` instead.
