Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Sep 05 2019 14:43
    @typelevel-bot banned @jdegoes
  • Jan 31 2019 21:17
    codecov-io commented #484
  • Jan 31 2019 21:08
    scala-steward opened #484
  • Jan 31 2019 18:19
    andywhite37 commented #189
  • Jan 31 2019 02:41
    kamilongus starred typelevel/cats-effect
  • Jan 30 2019 00:01
    codecov-io commented #483
  • Jan 29 2019 23:51
    deniszjukow opened #483
  • Jan 29 2019 23:37
  • Jan 29 2019 23:22
  • Jan 29 2019 20:26
    Rui-L starred typelevel/cats-effect
  • Jan 29 2019 18:01
    jdegoes commented #480
  • Jan 29 2019 17:04
    thomaav starred typelevel/cats-effect
  • Jan 28 2019 17:43
    asachdeva starred typelevel/cats-effect
  • Jan 28 2019 07:12
    alexandru commented #480
  • Jan 28 2019 05:45
    codecov-io commented #482
  • Jan 28 2019 05:35
    daron666 opened #482
  • Jan 27 2019 13:56
    codecov-io commented #481
  • Jan 27 2019 13:46
    lrodero opened #481
  • Jan 27 2019 05:47
    codecov-io commented #460
  • Jan 27 2019 05:37
    codecov-io commented #460
Rohde Fischer
@rfftrifork
understandable :) had to wrap my head a bit, but thanks to Fabio Labella's talk it became a lot easier :)
Ross A. Baker
@rossabaker
Usually the next part of the lecture is to send people to Fabio. :)
Rohde Fischer
@rfftrifork
xD makes sense
is there a point to prefer def foo[F[_]: Sync[F]]() = ??? over def foo[F[_]]()(implicit F: Sync[F]) I kind of like the flexibility by the implicit setup, but I was wondering because the tutorial use the former version. Am I doing it bad, is it taste, or?
Rohde Fischer
@rfftrifork
sorry [F[_]: Sync] of course :)
Ross A. Baker
@rossabaker
I think the context bound makes the signature more readable, and the named implicit makes the implementation more readable.
Fabio Labella
@SystemFw
I start from F[_]: Sync] and switch over to implicit F: Sync[F] if the body contains too many Sync[F].delay
Gabriel Volpe
@gvolpe
I prefer context bound as well whenever possible.
If you have some spare time I wrote about the different approaches and its performance implications @rfftrifork.
(shameless plug 😄)
Rohde Fischer
@rfftrifork
@gvolpe nice, will take a look :)
@SystemFw and @rossabaker good points, thanks for the input :)
anil chalil
@capacman
Hi all, i am writing a simple program that access to db via jdbc but i currently i dont want to use doobie. In my code i prepared a small utility like below. Is it enougn to handle local transactions or is there any edge cases that i miss? Thank you in advance:
implicit class richIODatasource[D <: DataSource, F[_]:Sync](val ids: F[D]) extends AnyVal {
    import cats.effect.ExitCase.{Completed, Error, Canceled}

    def use[T](f: Connection => F[T]): F[T] =
      Resource.fromAutoCloseable[F, Connection](ids.map(_.getConnection())).use(c => f(c))

    def transaction[T](f:Connection => F[T]):F[T] = use{ c =>
      Sync[F].bracketCase(Sync[F].pure(c).map{c =>
        c.setAutoCommit(false)
        c
      })(f){
        case (in, Canceled | Error(_)) =>Sync[F].delay(in.rollback())
        case (in,Completed) => Sync[F].delay(in.commit())
      }
    }
  }
Rohde Fischer
@rfftrifork
@capacman I'm fairly new to effects, but to me it looks correct. I'm wondering though if you'd need a begin transaction call. I seem to recall the ExitCase of bracket is a sealed trait, so I think you'll get a compiler warning if you don't cover all cases possible, but if I remember wrong then you might consider a default case where you do a rollback. Also slightly beside your point, I'll strongly urge you to log errors, including the input that cause them ;)
anil chalil
@capacman
Hi @rfftrifork , thank you for comments. Yes some logging absolutely necessary. I just wonder what happens in case of a exception in bracketcase? Because in documentation it say behavior depends on impl of F. Probably i need to write a test. Thanks again
Rohde Fischer
@rfftrifork
@capacman I think it will work, but I agree, a test is a very good idea, especially because then you have a chance of finding out if the behavior breaks
Rohde Fischer
@rfftrifork

hmm does anyone have some advice/experience/best practices with how to write better tests with effects? Currently I'm doing mixing of for comprehensions and unsafeRunSync, but it feels kind of awkward, I just cannot see how else to do it, e.g.:

"My app" should "do bar" in {
val barsF = for {
    foo <- foo()
    bars <- foo.bars()
} yield bars

val bars = barsF.unsafeRunSync

// tests go here

I'm struggling a bit, because in a way the cleanest would be to do the tests as F[_]s too, such that they are just a part of the for comprehension, but in a way it also feels slightly off/awkward to me

Georgi Krastev
@joroKr21
If you're using scalatest, it supports tests returning futures as well. Check the Async* styles. I guess it's not too difficult to add utilities for IO or for any F[_]: Effect. There is a lot of chatter about pure FP testing frameworks recently but idk if there is anything ready to be used.
Rohde Fischer
@rfftrifork
@joroKr21 thanks, will look into that, I am indeed using scalatest
Daniel Spiewak
@djspiewak

Opinion time! What should the following be?

F.racePair(F.raiseError(e), fb)

The choices here:

  1. F.raiseError(e)
  2. fb.map(b => Right((F.raiseError(e).start, b)))
I'm leaning towards the latter since it gives more power, particularly when you consider how it interacts with race, but it's actually unspecified right now
I would guess that everyone just picks 2 without realizing it
also @rfftrifork you may be interested in this: https://github.com/djspiewak/cats-effect-testing
Rohde Fischer
@rfftrifork
@djspiewak thanks a lot, will take a look once I'm over my current hurdle :)
Fabio Labella
@SystemFw
@djspiewak do you mean do start fb as well in no 2?
Daniel Spiewak
@djspiewak
@SystemFw yeah I do. I missed a flatMap there; adjusting
F.raiseError(e).start.flatMap(f => fb.map(b => Right((f, b))))
Fabio Labella
@SystemFw
well, my expectation is that both sides in a race are started, for fairness
Daniel Spiewak
@djspiewak
right, they would be
I'm just clarifying the outcome
Fabio Labella
@SystemFw
ah, ok, sorry
Daniel Spiewak
@djspiewak
:thumbsup:
Fabio Labella
@SystemFw
anyway yes, you wouldn't want raiseError to always win by default like in 1
or at least I wouldn't :P
Daniel Spiewak
@djspiewak
yeah
it'd be weird
but I noticed it wasn't actually codified by laws
Julien Truffaut
@julien-truffaut
Hi all, do you know where could I find a sketch of IO implementation including Async? It doesn't have to be stack safe or efficient, it is more to understand how the run loop works
Gavin Bisesi
@Daenyth
I'd peek at pre-0.10 versions of cats-effect
Fabio Labella
@SystemFw
@Daenyth the runloop works differently now though
one of the ideas for when the days have 36 hours is a series of blog posts about a real world (so concurrency, interruption and so ) version of IO that prioritises code clarity over performance for ease of understanding
@julien-truffaut not as nice as having a code sketch, but do feel free to ask questions instead
Gavin Bisesi
@Daenyth
ah
Fabio Labella
@SystemFw
the advice of looking at the old cats-effect is still valid though, and I am giving a talk on fibers which should bring more light on the internals (and Async is in many ways the key for everything)
Luka Jacobowitz
@LukaJCB
Man I can’t wait for days to have 36 hours
I’m gonna get so much done
Just need to figure out how to slow earth’s rotation somehow
Daniel Spiewak
@djspiewak
@julien-truffaut so conceptually, you can get an idea for the model by implementing something like type Task[A] = EitherT[ContT[Free[() => ?, ?], Unit, ?], Throwable, A],
more abstractly, IO is two free monads glued together with an interpreter that can sequence back and forth between them. Cont is itself a free monad for a coalgebra, while Free is obviously… uh, Free, and we instantiate it with a trivial algebra
the run loop today behaves radically different than this though