mattmoore
06/26/2020, 3:25 AMmattmoore
06/27/2020, 4:54 PMdata class Person(val firstName: String, val lastName: String)
fun main(args: Array<String>) {
val person = Person("Matt", "Moore")
val result = when (person) {
Person(capturedFirstName, _) -> capturedFirstName
else -> "Not matched"
}
println(result)
}
Yields:
e: java.lang.ClassCastException: org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor cannot be cast to org.jetbrains.kotlin.descriptors.PropertyDescriptor
If I pull val person...
out of main
, then it works:
data class Person(val firstName: String, val lastName: String)
val person = Person("Matt", "Moore")
fun main(args: Array<String>) {
val result = when (person) {
Person(capturedFirstName, _) -> capturedFirstName
else -> "Not matched"
}
println(result)
}
I'm finally able to get back to this now.mattmoore
06/27/2020, 5:25 PMPatternMatchingPlugin.kt
file. I'm taking a look now through all the code and experimenting with it.mattmoore
06/27/2020, 5:25 PMshikasd
06/27/2020, 5:27 PMmattmoore
06/27/2020, 5:28 PMmain
now.mattmoore
06/27/2020, 5:29 PMshikasd
06/27/2020, 5:31 PMshikasd
06/29/2020, 2:35 PMPerson(_, capturedVariable)
to be converted into is Person -> { val captured = capturedVariable }
Not sure for how it'll go, just wanted to share things I am looking at.raulraja
06/29/2020, 10:26 PMcase
as marker to replace in the treeraulraja
06/29/2020, 10:26 PMshikasd
06/30/2020, 10:29 AMraulraja
06/30/2020, 11:39 AMraulraja
06/30/2020, 11:40 AMRachel
06/30/2020, 11:43 AMRachel
06/30/2020, 2:27 PMmaster
branch with all the changes to use latest versions:
- Branch upgrade-to-1.4-M3
for latest EAP 1.4-M3-eap-180
- Branch upgrade-to-1.4-dev
for latest DEV 1.4.20-dev-1427-233
mattmoore
06/30/2020, 7:38 PMcase
synthetic to act as a marker. In the current iteration, it's looking at when
subject, but we would also need to handle the expression when it's not a when
subject or even outside when
entirely. For example:
val matt = Person("Matt", "Moore")
val Person(_, lastName) = matt
Another example would be for matching on lists (though that's not quite in scope just yet, as there's more stuff to solve there).
I'll be able to experiment more with this tonight. Of course, I'm still new to the internal APIs so having your help, Raul's help, and everyone else on that has been a tremendous boost to this effort. So thank you for that! š If I'm able to figure out how to generalize the current version without when
expressly (so it'll work in more general cases) I'll push some code up. Unless you beat me to it š
Thanks @Rachel for looking into 1.4. I'm very eager to see 1.4 be finally ready, as I'm sure all of you are as well šshikasd
06/30/2020, 8:05 PMraulraja
07/01/2020, 11:11 PMraulraja
07/01/2020, 11:12 PMshikasd
07/02/2020, 12:07 AMjulian
07/02/2020, 12:07 AMmattmoore
07/02/2020, 3:03 AMshikasd
07/08/2020, 12:42 AMtodo
property in the prelude which serves as a placeholder to complete calls in PSI.
(also merged master, so sorry for a bit messy changeset)mattmoore
07/09/2020, 11:00 PMmattmoore
07/09/2020, 11:01 PMmattmoore
11/17/2020, 5:49 PMwhen
- but we want matching to be decoupled from that. So Iām inverting the process to start with the case
synthetic as the starting point, and attempting to only traverse up or down the tree if itās necessary to do so - but currently I donāt think it will be necessary. This would ensure that case
is adaptable outside of when
.
Iām not sure precisely when Iāll have code fully ready to share as this year has gotten incredibly busy. But I will have some more time freeing up in the next few weeks to devote more time to this and hopefully have an initial prototype working perhaps some time this year/early next on the latest Kotlin/Meta.
Iāll probably be in the #arrow-meta and #compiler channel as well asking questions there about new compiler design at some point.dephinera
02/02/2021, 11:58 AMwhen
like the ones in Swift?
let point = CGPoint(x: 7, y: 0)
switch (point.x, point.y) {
case (0,0): print("On the origin!")
case (0,_): print("x=0: on Y-axis!")
case (_,0): print("y=0: on X-axis!")
case (let x, let y) where x == y: print("On y=x")
default: print("Quite a random point here.")
}
AFAIK Swift language supports tuples and I suppose the construct here does a tuple comparison, but I don't see a reason why this shouldn't be just a syntax sugar for multiple if-elses or a when without a parameter and comparisons in each branch. One thing that I think might be an issue is if we want to match types, where we'd have something like this:
sealed class A {
class X : A()
class Y : A()
}
sealed class B {
class X : B()
class Y : B()
}
And then I guess there should be more syntax introduced, like this
...
fun foo(a: A, b: B) = when (a, b) {
(is A.X, is B.X) -> TODO()
(is A.Y, is B.Y) -> TODO()
}
Or if we want to match multiple types
...
fun foo(a: A, b: B) = when (a, b) {
(is A.X or is A.Y, is B.X) -> TODO()
(is A.Y or is A.X, is B.Y) -> TODO()
}
// or
fun foo(a: A, b: B) = when (a, b) {
(is (A.X | is A.Y), is B.X) -> TODO()
(is (A.Y | is A.X), is B.Y) -> TODO()
}
I hope I explained the idea well enough. So are there any limitations to make this possible? If not - should we expect something like this in the future? Do you think it's something that we actually need?mattmoore
03/11/2021, 4:31 PM_
and hereās where Iām at so far.
Iāve started moving pattern matching back to generalized case
expression as the resolution starting-point. From there it will check to see the context itās in (where
expression, if
expression, etcā¦) and then do the tree transform later in IR.
However, with 1.4 of the Kotlin compiler, after Iāve suppressed the āunresolvedā errors, Iām now receiving a āunbound symbols not allowedā error. Tracing this back I see this is where a check is done for context.symbolTable.allUnbound
https://github.com/JetBrains/kotlin/blob/v1.4.10/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt#L96
What would be the appropriate way to bind _
to another semantically valid symbol? Iām already using BindingContext
to do a record
(which then shows up in the binding context). Since the file above is called Psi2IrTranslator
and the function is generateModuleFragment
Iām guessing I need to either generate IR or map this to the IR that for the semantically valid symbols that Iām attempting to reference with _
.
In this scenario, I want the symbol _
to be bound to a KtNameReferenceExpression
, as it would refer to a data class argument.