10000 avoid lifting modules (like Abort.type/Var.type, ...) by ahoy-jon · Pull Request #1291 · getkyo/kyo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

avoid lifting modules (like Abort.type/Var.type, ...) #1291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 30, 2025

Conversation

ahoy-jon
Copy link
Collaborator
@ahoy-jon ahoy-jon commented Jun 27, 2025

Plain solution about this problem. There is probably a better way.

@johnhungerford that's what I understood from: "Could we use implicit evidence to exclude certain objects from lifting?", you tell me!

- [x] add extends KyoModule to all the companion object of effects

Updating WeakFlat => CanLift with a macro to not lift modules in kyo. that are not a case object.

@ahoy-jon ahoy-jon requeste 8000 d review from fwbrasil and johnhungerford June 27, 2025 21:11
@ahoy-jon ahoy-jon force-pushed the feat/avoid-lifting-modules branch from 3379a70 to 623963e Compare June 27, 2025 21:14
@ahoy-jon ahoy-jon requested a review from johnhungerford June 27, 2025 23:39
@ahoy-jon ahoy-jon force-pushed the feat/avoid-lifting-modules branch 2 times, most recently from bae49d9 to d4e0715 Compare June 28, 2025 21:37
@fwbrasil
Copy link
Collaborator

I don't like the overall approach since it pollutes the codebase and we can forget to add the marker to new code. How about renaming WeakFlat to CanLift and disallowing lifting of any companion object in the macro itself?

@ahoy-jon
Copy link
Collaborator Author

@fwbrasil

I don't like the overall approach since it pollutes the codebase

True 💯

How about renaming WeakFlat to CanLift and disallowing lifting of any companion object in the macro itself?

Like in this PR : #1285 with lift as a macro? or CanLift as a macro?

@ahoy-jon ahoy-jon force-pushed the feat/avoid-lifting-modules branch from d4e0715 to 4363329 Compare June 29, 2025 13:19
@ahoy-jon ahoy-jon requested a review from fwbrasil June 29, 2025 13:20
@ahoy-jon
Copy link
Collaborator Author

@fwbrasil reworked it as a macro, for CanLift

Comment on lines +33 to +42
object CanLiftMacro:
inline given derived[A](using inline ng: NotGiven[A <:< (Any < Nothing)]): CanLift[A] = ${ liftImpl[A] }
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

circular references don't help with the macro:

  • NotGiven[A <:< (Any < Nothing)] is better than doing it in the macro.
  • the macro have to be isolated from inline given CanLift[Nothing], hence the CanLiftMacro, then an export.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not inspect the A type for nesting in the macro code? There's also Expr.summon I think that can be used in the macro but avoiding another implicit search could be good for compilation times.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not inspect the A type

It was not working a all, with painful compile errors due to cyclic definitions.

Now it could be working and make PendingTest.scala crash with 32 compile errors:

[error] -- Error: /Users/jon/Documents/GitHub/kyo/kyo-kernel/shared/src/test/scala/kyo/kernel/PendingTest.scala:456:48 
[error] 456 |                TestEffect1(1).map(_ => Kyo.lift(TestEffect2("hello")))
[error]     |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[error]     |Type '<' may contain a nested effect computation.
        if tpe <:< TypeRepr.of[Any < Nothing] then
            report.errorAndAbort(s"""Type '${sym.name}' may contain a nested effect computation.
                                   |
                                   |This usually means you have a value of type 'X < S' where you need a plain value.
                                   |To fix this, you can:
                                   |
                                   |1. Call .flatten to combine the nested effects:
                                   |     (x: (Int < S1) < S2).flatten  // Result: Int < (S1 & S2)
                                   |
                                   |2. Split the computation into multiple statements:
                                   |     val x: Int < S1 = computeFirst()
                                   |     val y: Int < S2 = useResult(x)""".stripMargin)
        end if

It's better to not change this part now, and have a discussion when possible to plan the work on lift.

@ahoy-jon ahoy-jon force-pushed the feat/avoid-lifting-modules branch from 2b8580e to 05391eb Compare June 29, 2025 16:20
@ahoy-jon ahoy-jon requested a review from hearnadam June 29, 2025 16:29
@ahoy-jon
Copy link
Collaborator Author
< 8000 /table>

With the current implementation

Branch Run User Time System Time CPU Usage Total Time
feat/avoid-lifting-modules 1 527.57s 20.68s 441% 2:04.24
feat/avoid-lifting-modules 2 513.18s 19.29s 453% 1:57.41
main 1 521.05s 19.72s 420% 2:08.75
main 2 521.46s 19.44s 456% 1:58.40
v match
case kyo: Kyo[?, ?] => Nested(kyo)
case _ => v.asInstanceOf[A < S]

implicit inline def liftUnit[S1, S2](inline v: Unit < S1): Unit < S2 = ${ liftUnitImpl[S1, S2]('v) }
implicit inline def liftAnyVal[A <: AnyVal, S](inline v: A): A < S = v.asInstanceOf[A < S]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need CanLift? Technically you could put an AnyVal around a computation, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, what do you mean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should do a call on the rest, their are a lot of interesting things to do with lift.

Eg. optimizing all the Const[A <: AnyVal][?] could be a huge improvement (perf / bytecode). as far as I see, they are not using liftAnyVal, and it's use a lot in ArrowEffect.

@ahoy-jon
Copy link
Collaborator Author

Bench result, from #1300

  • improved throughput in general by 4–11%
  • reduced memory allocation in general by 1–2%

the most improved case: filterMapVarStreamAbstractBench

Metric Before After Δ
Throughput 435±10 ops/s 483±7 ops/s +11%
Allocation 10.16MB±56KB 9.56MB±31KB -6%

pipe-benchmark.jmh-result.json
benchmark-1291.jmh-result.json

@ahoy-jon ahoy-jon force-pushed the feat/avoid-lifting-modules branch from 3fb1f12 to 6410c5b Compare June 30, 2025 20:08
@fwbrasil fwbrasil merged commit 70ecb90 into getkyo:main Jun 30, 2025
2 of 5 checks passed
@ahoy-jon ahoy-jon mentioned this pull request Jul 1, 2025
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0