Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 05:16
    NthPortal commented #8932
  • Jan 16 22:06
    SethTisue commented #1336
  • Jan 16 22:01
    griggt commented #1336
  • Jan 16 21:43
    griggt commented #1336
  • Jan 16 20:05
    SethTisue commented #1336
  • Jan 16 20:04
    SethTisue commented #1336
  • Jan 16 19:37
    SethTisue commented #1336
  • Jan 16 19:35
    SethTisue commented #1336
  • Jan 16 17:29
    sparamonov opened #1900
  • Jan 16 16:59
    SethTisue commented #1336
  • Jan 16 16:57
    SethTisue commented #1336
  • Jan 16 16:56
    SethTisue commented #1336
  • Jan 16 16:56
    SethTisue commented #1336
  • Jan 16 16:55
    SethTisue commented #1336
  • Jan 16 16:48
    SethTisue commented #1336
  • Jan 16 16:48
    SethTisue commented #1336
  • Jan 16 15:10
    SethTisue commented #1336
  • Jan 16 15:10
    SethTisue commented #1336
  • Jan 16 08:19
    martijnhoekstra edited #9365
  • Jan 16 05:52
    SethTisue commented #1336
trepidacious
@trepidacious
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
Fabio Labella
@SystemFw
just pass an f: (Int, Int) => Int
and yield f(x, y)
exactly, so by doing this refactoring you are kinda "cheating"
RoelofWobben
@RoelofWobben
oke, then it let it be
I do not like cheating
Marcin Sokrates
@marcinsokrates_twitter
@avremel you should refactor to get rid of Future[Try[Option[Double]]] because it's redundant, Future.fromTry lets you skip the Try
RoelofWobben
@RoelofWobben
thanks all
time for the chapter about the for/yield and Option
Avremel Kaminetzky
@avremel
@marcinsokrates_twitter interesting. I was using toOption.flatten to remove the Try
  private def calculateShippingPriceRedo(cookie: String, country: Option[String], state: Option[String], shippingMethodId: Option[Int] = None): Future[Option[Double]] = {
    val countryWithDefault = country.getOrElse("US")

    shippingOptionsFull(cookie, country=countryWithDefault, state).map{ opt => opt.map{ rows =>
      shippingMethodId.flatMap{ id =>
          rows.find(_.shippingSpeedType === id ).orElse(rows.headOption).map(_.charge)
        }
      }.toOption.flatten
    }
  }
Derek Wickern
@dwickern
it depends what you want
Avremel Kaminetzky
@avremel
How would I use Future.fromTry?
Derek Wickern
@dwickern
do you want a successful future with None when the Try fails
Rob Norris
@tpolecat
Future[Try is usually wrong because Future already has the bulletproof behavior.
Derek Wickern
@dwickern
or a failed future