Conversation
Adds a type-safe enum for comparison operators (LT, LE, GT, GE) with a generic compare method that delegates to YawnRestrictions. This works around Kotlin's lack of higher-rank polymorphism on function types when passing comparison operators as parameters to helper functions that apply the same operator to columns with different generic types. Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
- Add YawnComparisonTest with 6 tests covering all enum variants - Fix compare() parameter from 'value: F' to 'value: F & Any' to match the YawnRestrictions method signatures Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
Include equality comparison alongside the ordering comparisons, delegating to YawnRestrictions.eq. Add corresponding test. Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
Replace mechanical delegation tests with tests that demonstrate the actual use case: a helper function that applies the same comparison operator to columns of different generic types (Int, String, Long). This is the pattern that Kotlin function references cannot express due to invariance of the type parameter F. Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
…ottom - Destructure results into named variables (amountCriterion, etc.) and assert each column's restriction type individually - Move private buildOrderCriteria helper to the bottom of the class - Return Triple instead of List to enable destructuring Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
Put each argument on its own line with named parameters to satisfy the ArgumentListWrapping lint rule. Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
Test YawnComparison against a real H2 database using the existing BookFixtures data. Includes tests for each comparison variant (LT, LE, GT, EQ) and two tests demonstrating the core use case: applying a single YawnComparison to columns of different types (Long and String) in the same query via a helper function. Co-authored-by: Nguyen Chinh Trung <chinhtrung596@gmail.com>
|
/poke 🙇♂️ |
Sorry, I didn't understand that. |
|
/poke |
Poked 1 reviewers for PR |
QuinnB73
left a comment
There was a problem hiding this comment.
Overall, this LGTM. However, I'm not sure that this should be part of Yawn's contract or if it should remain internal to our own usage of Yawn 🤔
I.e. are we adding too many ways to do things? Curious for your thoughts (and @luanpotter's as well of course!)
| } | ||
|
|
||
| @Test | ||
| fun `all comparison variants are present`() { |
There was a problem hiding this comment.
I don't think this test is all that valuable, it's subsumed by the restriction type test
|
@QuinnB73 I think it is worth if there is a good use case. I think the use case here is to provide generic functions that take an operator and do multiple operations using Yawn. but I guess my question is can't it just take the restriction lambda (ie YawnRestrictions.le) instead of an enum? is iterativability a concern? or the ability of having a function of shape |
Yeah that makes sense, worth trying @chinhtrung ! |
@QuinnB73 @luanpotter yeah, I gave that a try in this backend PR, but I think we couldn't just pass the operation |
I think Luan is saying that you can pass a lambda as a param |
@QuinnB73 @luanpotter, yes I got the idea of passing a lambda as a param too. However, I couldn't get to that solution because of the type checking in Kotlin. I also attempt with ai agent but it seems to mention similar things. Can you give it a try in this case? 🙏
|
|
could you do |

Follow up from this backend PR, we want to create a way to pass a typesafe comparison operators (EQ, LT, LE, GT, GE) as a parameter in Kotlin.
Summary
Adds a
YawnComparisonenum to thecom.faire.yawn.querypackage inyawn-api. This provides a type-safe way to pass comparison operators (EQ, LT, LE, GT, GE) as a parameter, working around Kotlin's lack of higher-rank polymorphism on function types.Motivation
When writing helper functions that apply the same comparison operator to multiple columns with different generic types (e.g.
ColumnDef<DateTime>andColumnDef<DateTime?>), you can't passYawnRestrictions::ledirectly as a function parameter becauseColumnDef<F>is invariant inFand Kotlin function types requireFto be fixed. An enum with a genericcomparemethod solves this —Fis resolved independently at each call site.Changes
yawn-api/src/main/kotlin/com/faire/yawn/query/YawnComparison.ktenum class YawnComparisonwith variantsEQ,LT,LE,GT,GEcomparemethod that delegates to the correspondingYawnRestrictionsmethodYawnRestrictionsandYawnQueryCriterionyawn-apiyawn-api/src/test/kotlin/com/faire/yawn/query/YawnComparisonTest.ktInt,String,Long)yawn-database-test/src/test/kotlin/com/faire/yawn/database/YawnComparisonDatabaseTest.ktYawnComparisonto columns of different types (LongandString) in the same query via a shared helper function