Infix fun Shape.union(Shape)

I noticed that Shape extension functions like union, intersection and so on are not marked as infix. I really see no reason why not though? And I’m guessing this applies to some other similar functions too.

1 Like

Hi! For those who don’t know the infix notation, the idea is to be able to write

val c = a union b

instead of

val c = a.union(b)

right?

Do you prefer the first syntax and if so, do you know why?

For me infix makes sense with operators like + and * (instead of using .plus() and .times() ) but for other cases I’m not so sure. I do like to experiment with it on my own code though.

I asked Edwin and he said

Whenever I come back to code that I made using infix functions I wonder why it had to be so different

If I look at the source code, I see infix used in openrndr a few times, mostly with Vector types.

2 Likes

Here is my reasoning:

  1. I believe this case is basically what infix functions were introduced for – an alternative for custom operators

  2. Logically union is basically same as ‘+’, so it makes sense to use the two in a similar way

  3. Infix functions can still be called as normal, it’s just that IDEA will suggest to use it as infix

Now why do I personally prefer this syntax: when I read a.f(b), I get a sense that a and b are not things of the same kind. It feels like there is some sort of hierarchy between them. So IMO, when some f requires exactly two parameters of the same nature, it should be written as either f(a, b) or in case with operators a f b.

3 Likes

OPENRNDR ought to follow the conventions of Kotlin in general so people can rely on those conventions. In Set-operations for the Kotlin-standard library such operations are marked as infix. People can use the one that they prefer, but I very strongly feel that infix usage should at least be permitted.

Personally I like the infix options as they make more sense to me as that’s how you write them out in set theory when doing math on paper. I strongly prefer infix operations (and usage of +, -, etc) in vectors for similar reasons. In fact, being able to write vectors like we do in math is one of the reasons I like OPRNDR so much. It’s much easier to read, esp. if you’re maybe referencing actual math material.

Funnily enough, this reminded me of back when I was first learning Kotlin (in around 2013-2014). I was kinda learning Kotlin on the side at the same time we where learning set theory at university, so I played around with implementing sets in Kotlin. I went really far in making in look like math, because I wanted something that looked like the union character we use in actual math: let a = b ∪ c, so I set up an infix for just the letter u so I could write: val a = b u c. I think that’s going way to far though, but just writing union in-between reads fairly well to me anyway, that is: val a = b union c.

1 Like
  1. Logically union is basically same as ‘+’, so it makes sense to use the two in a similar way

Sorry to nitpick, but + does have meanings with collections that is quite different from union in Kotlin. Using + between ordered collections like lists is concatenation (like with strings), so the order very much matters. This really matters, because you can do Set operations on collections that aren’t strictly speaking sets.

Consider the following:

val a = listOf(1, 2, 3)
val b = listOf(2, 3, 4)

val x = a union b // [1, 2, 3, 4]
val y = b union a // [1, 2, 3, 4]
val z = a + b // [1, 2, 3, 2, 3, 4]
val w = b + a // [2, 3, 4, 1, 2, 3]

Again, sorry to nitpick, I just think stuff like this can cause confusion if we aren’t clear about it. And I completely agree with your overall point!

1 Like