Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 19:47
    eed3si9n edited #8591
  • 19:28

    SethTisue on 2.13.x

    2.12: new Scala SHA 2.12: update expected-failure l… add akka-http-webgoat (#1017) and 1 more (compare)

  • 19:08

    SethTisue on 2.11.x

    sbt version bump (1.3.3->1.3.4)… 2.12: new Scala SHA 2.12: update expected-failure l… and 3 more (compare)

  • 19:04
    SethTisue commented #8545
  • 19:03
    som-snytt commented #11824
  • 18:54
    som-snytt labeled #11824
  • 18:54
    som-snytt commented #11824
  • 18:46
    som-snytt review_requested #8591
  • 18:46
    scala-jenkins milestoned #8591
  • 18:46
    som-snytt opened #8591
  • 18:38
    SethTisue milestoned #3237
  • 18:38
    SethTisue assigned #9386
  • 18:38
    SethTisue milestoned #9386
  • 15:21
    som-snytt commented #8590
  • 14:50
    lrytz commented #8588
  • 13:12

    lrytz on 2.13.x

    Avoid length of list Lint confusing by-name conversi… Lint by-name conversion of bloc… and 1 more (compare)

  • 13:12
    lrytz closed #8590
  • 13:12
    lrytz closed #9386
  • 13:12
    lrytz closed #3237
  • 09:36
    dwijnand commented #1016
Fabio Labella
@SystemFw
the implementation of interruption in cats-effect currently checks the interrupt flag at async boundaries
which are introduced by several operations
Marcin Sokrates
@marcinsokrates_twitter
Turning asynchronous OS signals into exceptions is possible, you can do it in C++/GCC, the JVM does it for NPEs I think, but I'm sure there are lots of things to consider while doing that
Fabio Labella
@SystemFw
there's also another whole bunch of complexity that comes with the interaction with resource safety and finalisers
Josh
@joshlemer
hmm having trouble finding a good article
Fabio Labella
@SystemFw
but that being said, both fs2 and cats-effect, and Monix ( as well as Twitter futures iirc) are cancelable
Josh
@joshlemer
Basically, Rust futures are pull- (aka poll-) based not push-based, which means that to cancel it, children just have to stop polling their parents
Fabio Labella
@SystemFw
I'm not sure how exactly that maps to IO and/or Stream (Streamis pull-based for example)
I think IO will map to pull-based as well
trepidacious
@trepidacious
@SystemFw @martijnhoekstra Yes, it's pretty clear it's one of those areas where a lot of complexity is covered up by a short description :)
Fabio Labella
@SystemFw
@joshlemer one immediate question for example is deciding when do you want to check the interrupt flag
trepidacious
@trepidacious
@SystemFw @martijnhoekstra Makes me think of real-time C where you handle these things in processor interrupts to be able to do non-cooperative threading, I have no idea what the VM equivalent of that is. I guess there is also a pretty significant tradeoff between latency and throughput.
Fabio Labella
@SystemFw
if you're interested I'd read about how Haskell does it. The fact the runtime controls both evaluation of pure code as well as IO and concurrency means you have a lot more control about what you can do
srimugunthan
@srimugunthan
trepidacious
@trepidacious
@SystemFw I should stop being surprised when it turns out Haskell does something more elegantly :)
Maybe I'll use it one day :)
Marcin Sokrates
@marcinsokrates_twitter
Oh, the JVM actually has Thread.stop(), but they deprecated it for fear of inconsistent state in interrupted lock-protected code sections
trepidacious
@trepidacious
@marcinsokrates_twitter Yes that's what I was thinking of. Maybe if you have pure code that definitely doesn't use locks you could use it... ;)
Marcin Sokrates
@marcinsokrates_twitter
I wish they just added a mechanism for suspending interrupts in critical sections instead
Josh
@joshlemer
@SystemFw cancelling, here, ends up meaning to just not poll any more
the work is driven through the polling method. When a child is polled, it polls its parent etc
if no polling happens, no work gets done
Fabio Labella
@SystemFw

cancelling, here, ends up meaning to just not poll any more

@joshlemer I don't think that says the whole story, let me expand, because I feels like this is similar to how cats-effect (or Monix) work

Josh
@joshlemer
although I wonder if this means they are not stack-safe...
Fabio Labella
@SystemFw

@joshlelemer
basically the way IO works is by constructing a datatype, which contains all the info to then interpret the IO (e.g. the constructor for side effecting code takes an => A, the constructor for flatMap takes IO[A] and A => IO[B], and they get stored in cases of an ADT). This datatype is then interpreted by the runloop once you unsafeRunSync at the end of world (typically the top of the call chain, in main).


The way the interpreter works is basically a while loop over two vars, the current IO[Any], and a Stack[Any => IO[Any]], you get the current, dispatch on its constructors and do what you need to do (e.g. evaluate the => A) and keep going with the next. This is a powerful approach because manipulating the stack allows you to implement complex features (e.g. you can shift to a trampoline every n calls to solve the stack safety problem you would otherwise have). It's also similar to what you mean by "polling": if you don't fetch the next thing off the stop, things just stop executing.


However, the crucial detail is that this by itself is not Interruption, it's suspension: i.e. you have defined a mechanism for an IO to suspend itself and give control back to the main thread (which is how fiber level concurrency is implemented), but interruption means that another IO needs to stop you.
So you need to have a shared (volatile, at the very least) variable which is the interrupt flag, the other IO sets it when it wants to interrupt you, and in your runloop you need to check this variable, and only then suspend yourself when the variable is true.


And that indeed brings up back to the initial question: how often do you check it? And there are different choices: you can check it at every flatMap, that's very fine grained but also quite expensive. The current choice in IO is to check it at every async boundary. And as I said, there's another whole bunch of complexity (in library code, not user code) to make sure things are resource safe and finalisers are registered and run correctly, in all scenarios

RoelofWobben
@RoelofWobben
How do I refractor the whole flatMap thing here :
sealed trait Expression{

  def eval: Sum[String, Double] = this match {

    case Addition(left, right) => left.eval flatMap { x => right.eval flatMap(y => Success(x + y))}
    case  Subtraction(left, right) => left.eval flatMap { x => right.eval flatMap(y => Success(x - y))}
}
Gavin Bisesi
@Daenyth
what monad is left/right/Success in?
RoelofWobben
@RoelofWobben
Sorry, monads are not explained yet. That will be in the cats book
RoelofWobben
@RoelofWobben
@Daenyth
Bastin Orar
@bastinOrar_twitter
I want a link to any beginner ML post with scala
Rob Norris
@tpolecat
@RoelofWobben assuming your result type acts like Either you can probably say for { x <- right.eval; y <- left.eval } yield x + y for example. That's probably where they are headed.
Gavin Bisesi
@Daenyth
@tpolecat I would have said that also except that he has a flatMap there on Success, so the yield is wrong
but that feels weird
@RoelofWobben what type are you calling flatMap on? Success is one of the members and left and right both have that type
Fabio Labella
@SystemFw
why do you find it weird?
Rob Norris
@tpolecat
I think that's like flatMap into pure … consider e.flatMap(a => Right(f(a))) which is e.map(f)
Fabio Labella
@SystemFw
yes
that's it
it's a map, so yield
Avremel Kaminetzky
@avremel
I have values in Future[Try[Option[Double]]] and Future[Option[Double]]. How can I add them? Should I be using Future.sequence?
RoelofWobben
@RoelofWobben
bad luck for me , yield is also not explained
Avremel Kaminetzky
@avremel
Or is there a way to use Future[Try[Option[Double]]] as Future[Option[Double]]?
RoelofWobben
@RoelofWobben
so there is no way I can refractor the this part out :
left.eval flatMap { x => right.eval flatMap(y
Gavin Bisesi
@Daenyth
@RoelofWobben
for {
  x <- left.eval
  y <- right.eval
} yield x + y
RoelofWobben
@RoelofWobben
oke, and I can put that into a function and call it
Fabio Labella
@SystemFw
I think the reason those things are not explained is that they are using the exercises to build the intuition you need to understand for/yield, once they do get there
RoelofWobben
@RoelofWobben
nope, in the other where I use it , it's x - y
so that code is not working
Fabio Labella
@SystemFw
it is
RoelofWobben
@RoelofWobben
@SystemFw for /yield is explained in the next chapter