Is any way call infix function without 'this' caller


#1

I am trying to custom an infix function for a class, and i want to call the function without ‘this’ in this class. like this :

infix fun plus(a: Int){...}

this plus 3 // work well

plus 3 // compile error  

Infix function in receivers
#2

No, this is not possible. By definition. the infix call is sometimes that goes between the receiver and the argument.


#3

It seems possible -> https://github.com/eugenkiss/kotlinfx/wiki

But I think it is somehow done with traits which are deprecated.


#4

@fluxparticle If you are speaking about +something than this is not infix function. It is just operator fun Seomthing.unaryPlus().


#5

No… It is used to add a Rectangle as a child to the Pane… So there must be an access to the ‘this’ of the Pane.

I think this is the code that makes it work:

But I don’t understand how… And if it would still work in Kotlin 1.2


#6

The current versions of Kotlin don’t have traits, the code is thus invalid. It may be possible to replace it with default implementations on an interface. In that case you have access to both the receiver of the function as well as the actual owner (the interface implementing object).


#7
plus(3)

#8

@fluxparticle This is possible with extension function in class. You can see worked example here:
https://htmlpreview.github.io/?https://raw.githubusercontent.com/snrostov/ui-dsl/master/index.html#hello-world

class Node(childrenBuilder: NodeListBuilder.() -> Unit = {})
class NodeListBuilder {
  val list = mutableListOf<Node>()
  operator fun Node.unaryPlus() = list.add(this) 
}

fun test() {
   Node {
     +Node()
     +Node {
       +Node()
       +Node()
     }
   }
}

#9

Yes… I build it similar… But without traits I’m afraid I have to inherit every container class in JavaFX

interface ParentBuilder {

    fun getChildren(): ObservableList<Node>

    operator fun Node.unaryPlus() = getChildren().add(this)

}

class PaneBuilder : Pane(), ParentBuilder
class HBoxBuilder : HBox(), ParentBuilder
class VBoxBuilder : VBox(), ParentBuilder

fun pane(block: PaneBuilder.() -> Unit): Pane = PaneBuilder().apply { block() }
fun hbox(block: HBoxBuilder.() -> Unit): HBox = HBoxBuilder().apply { block() }
fun vbox(block: VBoxBuilder.() -> Unit): VBox = VBoxBuilder().apply { block() }

#10

Hmm… I’m don’t see how traits (with ability to require base class) helps this. The only thing is fun getChildren(): ObservableList<Node> in ParentBuilder. Can you show what code will be with traits?