Use a method as an arguement without invoking it


#1

foo(bar.howdy)

Is there a way to pass howdy without invoking it, other than assigning a closure to a variable?


#2

A closure is the way to go here.

Assuming a foo() similar to this:

(() String code)
  [
  // early stuff...
  use_string(code())
  // later stuff...
  ]

Then you could call it like this:

foo[bar.howdy] // infers parameters () String

// Or like any of these:
foo(()[bar.howdy])  // Infers String return
foo(^[bar.howdy])   // Infers parameters () String
foo(^bar[howdy])    // uses bar as `this`


// Passing as a variable
// - would be more complex if it had parameters
!howdy1: ()[bar.howdy]
!howdy2: ^[bar.howdy]
!howdy3: ^bar[howdy]

foo(howdy1)
foo(howdy2)
foo(howdy3)

The first foo[bar.howdy] uses Closure tail arguments such as Integer@do() - 5.do[bar.howdy]

Just so you know, if howdy() were called on the current object this.howdy() then it would look like this:

foo[howdy] // infers parameters () String

// Or like any of these:
foo(()[howdy])  // Infers String return
foo(^[howdy])   // Infers parameters () String


// Passing as a variable
// - would be more complex if it had parameters
!howdy1: ()[howdy]
!howdy2: ^[howdy]

foo(howdy1)
foo(howdy2)

You may only need to pass in a single expression rather than several lines of code so you might be wondering if a closure is overkill. :face_with_raised_eyebrow:

We can optimize this internally to take advantage of the fact that it is only as singe expression. So it shouldn’t be a big deal. :madsci:


There is also a proposed closure routine expression that works with a single expression and no brackets (plus a few other advantages) that would look like this:

foo(^@bar.howdy)

Again if you were trying to call this.howdy(), it would look like this:

foo(^@.howdy)

Executing SK coroutines from UE