title: Kotlin - Function's Invoke Operator Overloading
body: <p>I am currently studying <a href="https://kotlinlang.org/docs/reference/operator-overloading.html" rel="nofollow noreferrer">Kotlin - Operator Overloading</a> <br>
  I am trying to understand (with an example) how does operator overloading work for a function's <code>invoke()</code> function</p>
  
  <p><strong>The pre-test</strong></p>
  
  <ul>
  <li><p><a href="https://kotlinlang.org/docs/reference/extensions.html" rel="nofollow noreferrer">Kotlin's Extension Functions</a></p>
  
  <pre><code>fun exampleOfExtensionFunction() {
      fun Int.randomize(): Int {
          return Random(this.toLong()).nextInt()
      }
  
      val randomizedFive = 5.randomize()
      println("$randomizedFive")
  }
  </code></pre>
  
  <p>Prints :</p>
  
  <blockquote>
    <p>-1157408321</p>
  </blockquote></li>
  <li><p><a href="https://kotlinlang.org/docs/reference/lambdas.html#function-types" rel="nofollow noreferrer">In Kotlin, functions can be declared as variables with types</a></p>
  
  <pre><code>fun exampleOfFunctionType() {
      val printNumber: (number: Int) -&gt; Unit
      printNumber = { number -&gt;
          println("[$number = ${number.toString(16).toUpperCase()} = ${number.toString(2)}]")
      }
  
      printNumber(1023)
  }
  </code></pre>
  
  <p>Prints :</p>
  
  <blockquote>
    <p>[1023 = 3FF = 1111111111]</p>
  </blockquote></li>
  <li><p><a href="https://kotlinlang.org/docs/reference/operator-overloading.html#operator-overloading" rel="nofollow noreferrer">Kotlin allows operator overloading with both extension and member functions</a></p>
  
  <pre><code>fun exampleOfOperatorOverloadingUsingExtensionFunction() {
      class MyType() {
          val strings: ArrayList&lt;String&gt; = ArrayList&lt;String&gt;()
          override fun toString(): String {
              val joiner: StringJoiner = StringJoiner(" , ", "{ ", " }")
              for (string in strings) {
                  joiner.add("\"$string\"")
              }
              return joiner.toString()
          }
      }
  
      operator fun MyType.contains(stringToCheck: String): Boolean {
          for (stringElement in strings) {
              if (stringElement == stringToCheck) return true
          }
          return false
      }
  
      val myType = MyType()
      myType.strings.add("one")
      myType.strings.add("two")
      myType.strings.add("three")
      println("$myType")
      println("(myType.contains(\"four\")) = ${myType.contains("four")} , (\"three\" in myType) = ${"three" in myType}")
  }
  </code></pre>
  
  <p>Prints :</p>
  
  <blockquote>
    <p>{ "one" , "two" , "three" }<br>
    (myType.contains("four")) = false , ("three" in myType) = true</p>
  </blockquote></li>
  </ul>
  
  <p><strong>Test Attempt</strong><br>
  Based on the above. I tried to create an example of a function's <code>invoke()</code> operator overloading using the type <code>(Boolean, Boolean, Boolean) -&gt; Boolean</code> as a receiver type for an extension function <code>invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean)</code>. This however did not work as expected.</p>
  
  <pre><code>    fun attemptFunctionInvokeOperatorOverloading() {
          operator fun ((Boolean, Boolean, Boolean) -&gt; Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
              println("Overloaded invoke operator")
              return flag1 &amp;&amp; flag2 &amp;&amp; flag3
          }
  
          var func1: ((Boolean, Boolean, Boolean) -&gt; Boolean) = { flag1, flag2, flag3 -&gt;
              println("func1 body")
              flag1 &amp;&amp; flag2 &amp;&amp; flag3
          }
  
          fun func2(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
              println("func2 body")
              return flag1 &amp;&amp; flag2 &amp;&amp; flag3
          }
  
          func1(true, true, false)
          func2(true, true, true)
      }
  </code></pre>
  
  <p>Prints :</p>
  
  <blockquote>
    <p>func1 body<br>
    func2 body</p>
  </blockquote>
  
  <p>Expected :</p>
  
  <blockquote>
    <p>Overloaded invoke operator<br>
    Overloaded invoke operator</p>
  </blockquote>
  
  <p><strong>Another question</strong> :<br>
  What exactly is this? (If it isn't operator overloading)</p>
  
  <pre><code>        operator fun ((Boolean, Boolean, Boolean) -&gt; Boolean).invoke(flag1: Boolean, flag2: Boolean, flag3: Boolean): Boolean {
              println("Overloaded invoke operator")
              return flag1 &amp;&amp; flag2 &amp;&amp; flag3
          }
  </code></pre>