diff --git a/README.md b/README.md index 0eb76cf79..90c3bc444 100644 --- a/README.md +++ b/README.md @@ -354,17 +354,17 @@ In Scala 2, `kyo-direct` draws its macro implementation inspiration from [Monadl ### Defining an App -`kyo.apps.App` offers a structured approach similar to Scala's `App` for defining application entry points. However, it comes with added capabilities, handling a suite of default effects. As a result, the `run` method within `kyo.apps.App` can accommodate various effects, such as IOs, Fibers, Resources, Clocks, Consoles, Randoms, Timers, and Aspects. +`KyoApp` offers a structured approach similar to Scala's `App` for defining application entry points. However, it comes with added capabilities, handling a suite of default effects. As a result, the `run` method within `KyoApp` can accommodate various effects, such as IOs, Fibers, Resources, Clocks, Consoles, Randoms, Timers, and Aspects. ```scala -import kyo.apps._ +import kyo._ import kyo.clocks._ import kyo.consoles._ import kyo.randoms._ import kyo.resources._ import kyo.concurrent.fibers._ -object MyApp extends App { +object MyApp extends KyoApp { // Only return pending `Fibers`, `Resources`, `Consoles` and `Tries`. // Handle other effects like `Options` before returning. def run: String > (Fibers with Resources with Consoles with Tries) = @@ -382,7 +382,7 @@ object MyApp extends App { } ``` -While the companion object of `App` provides utility methods to run isolated effectful computations, it's crucial to approach these with caution. Direct handling of effects like `IOs` through these methods can compromise referential transparency, an essential property for functional programming. +While the companion object of `KyoApp` provides utility methods to run isolated effectful computations, it's crucial to approach these with caution. Direct handling of effects like `IOs` through these methods can compromise referential transparency, an essential property for functional programming. ```scala import kyo.concurrent.fibers._ @@ -394,11 +394,11 @@ val a: Int > IOs = // Avoid! Run the application with a specific timeout val b: Int = - App.run(2.minutes)(a) + KyoApp.run(2.minutes)(a) // Avoid! Run the application without specifying a timeout val c: Int = - App.run(a) + KyoApp.run(a) ``` ## Core Effects @@ -456,7 +456,7 @@ val c: Int > IOs = IOs.fail(new Exception) ``` -Users shouldn't typically handle the `IOs` effect directly since it triggers the execution of side effects, which breaks referential transparency. Prefer `kyo.apps.App` instead. +Users shouldn't typically handle the `IOs` effect directly since it triggers the execution of side effects, which breaks referential transparency. Prefer `KyoApp` instead. In some specific cases where Kyo isn't used as the main effect system of an application, it might make sense for the user to handle the `IOs` effect directly. The `run` method can only be used if `IOs` is the only pending effect. @@ -464,10 +464,10 @@ In some specific cases where Kyo isn't used as the main effect system of an appl val a: Int > IOs = IOs(42) -// ** Avoid 'IOs.run', use 'kyo.apps.App' instead. ** +// ** Avoid 'IOs.run', use 'KyoApp' instead. ** val b: Int = IOs.run(a).pure -// ** Avoid 'IOs.run', use 'kyo.apps.App' instead. ** +// ** Avoid 'IOs.run', use 'KyoApp' instead. ** ``` The `runLazy` method accepts computations with other effects but it doesn't guarantee that all side effects are performed before the method returns. If other effects still have to be handled, the side effects can be executed later once the other effects are handled. This a low-level API that must be used with caution. @@ -483,11 +483,11 @@ val a: Int > (Options with IOs) = } } -// ** Avoid 'IOs.runLazy', use 'kyo.apps.App' instead. ** +// ** Avoid 'IOs.runLazy', use 'KyoApp' instead. ** // Handle the 'IOs' effect lazily val b: Int > Options = IOs.runLazy(a) -// ** Avoid 'IOs.runLazy', use 'kyo.apps.App' instead. ** +// ** Avoid 'IOs.runLazy', use 'KyoApp' instead. ** // Since the computation is suspended with the // 'Options' effect first, the lazy 'IOs' execution @@ -496,7 +496,7 @@ val c: Option[Int] = Options.run(b).pure ``` -> IMPORTANT: Avoid handling the `IOs` effect directly since it breaks referential transparency. Use `kyo.apps.App` instead. +> IMPORTANT: Avoid handling the `IOs` effect directly since it breaks referential transparency. Use `KyoApp` instead. ### Envs: Dependency Injection @@ -1084,7 +1084,7 @@ val i: Fiber[Int] > IOs = a.transform(v => Fibers.value(v + 1)) ``` -Similarly to `IOs`, users should avoid handling the `Fibers` effect directly and rely on `kyo.apps.App` instead. If strictly necessary, there are two methods to handle the `Fibers` effect: +Similarly to `IOs`, users should avoid handling the `Fibers` effect directly and rely on `KyoApp` instead. If strictly necessary, there are two methods to handle the `Fibers` effect: 1. `run` takes a computation that has only the `Fibers` effect pending and returns a `Fiber` instance without blocking threads. 2. `runBlocking` accepts computations with arbitrary pending effects but it handles asynchronous operations by blocking the current thread. @@ -1107,7 +1107,7 @@ val c: Int > IOs = Fibers.runBlocking(a) ``` -> Note: Handling the `Fibers` effect doesn't break referential transparency as with `IOs` but its usage is not trivial due to the limitations of the pending effects, especially `IOs`. Prefer `kyo.apps.App` instead. +> Note: Handling the `Fibers` effect doesn't break referential transparency as with `IOs` but its usage is not trivial due to the limitations of the pending effects, especially `IOs`. Prefer `KyoApp` instead. The `Fibers` effect also offers a low-level API to create `Promise`s as way to integrate external async operations with fibers. These APIs should be used only in low-level integration code.