Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 13:19
    danicheg transferred #6592
  • 13:19
    danicheg edited #724
  • 13:19
    kamilkloch opened #724
  • Aug 13 17:50
    emogua starred http4s/http4s
  • Aug 13 17:15
    mergify[bot] labeled #6611
  • Aug 13 17:15
    mergify[bot] labeled #6611
  • Aug 13 17:15
    cgoldammer edited #6611
  • Aug 13 17:15
    cgoldammer edited #6611
  • Aug 13 17:15
    cgoldammer opened #6611
  • Aug 13 04:53

    github-actions[bot] on gh-pages

    deploy: 977a734d2649460b2a64256… (compare)

  • Aug 13 04:48

    armanbilge on 0.23

    fix delayed websocket frame pro… apply sbt quicklint fixes fix Scala 2.12 compilation error and 5 more (compare)

  • Aug 13 04:48
    armanbilge closed #6558
  • Aug 13 04:48
    armanbilge closed #6587
  • Aug 13 04:41
    tarmath starred http4s/http4s
  • Aug 12 20:33
    armanbilge review_requested #6587
  • Aug 12 17:34
    buntec synchronize #6587
  • Aug 12 13:47
    wjoel commented #6201
  • Aug 12 13:39
    wjoel commented #6201
  • Aug 12 13:31
    TimWSpence synchronize #6610
  • Aug 12 13:20
    sideeffffect commented #6201
Fabio Labella
@SystemFw
(not arguing, just need a quick summary)
Christopher Davenport
@ChristopherDavenport
For defaults, I can do it with a partially applied trick. But its dirty. We do this with things like Logger where we take a Option[String => F[Unit]], and if not supplied one we get the default using the sync instance internally.
Fabio Labella
@SystemFw
because at some point I did various tricks, whose implementations are awful, but managed to encode a lot of these weird requirements, so I'd like to play with that
Christopher Davenport
@ChristopherDavenport
But that’s just a workaround for implicit position.
Ross A. Baker
@rossabaker
Add an argument to BlazeClientBuilder in F that defaults to F.delay(...) and you'll get a taste of the problem being discussed. Though that can minimize to other toy examples quite readily.
Every time I've wanted to do that I've later refactored away from it. Maybe it's good that we can't.
Fabio Labella
@SystemFw
I think that's enough
def foo[F[_]: Sync](log: String => F[Unit] = (x: String) => F.delay(println(x)): Thing
that's the problem right?
Ross A. Baker
@rossabaker
I wish we had a failsafe way to create an SSLContext, although the only way to do so would be if we could create one that was guaranteed to fail, in which case it's not too different from an Option... or a lazily guarded one. It's all in the message.
Yeah, that's another variant.
Fabio Labella
@SystemFw
you also want named arguments, or is withLog enough?
Ross A. Baker
@rossabaker
Because the Sync[F] is really in a parameter list after the log.
Uh... withLog would be sufficient for this use case.
Christopher Davenport
@ChristopherDavenport
def logMe[F[_]: Sync](s: String, logAction: Option[String => F[Unit]]): F[Unit] = {
    val log = logAction.getOrElse({s => Sync[F].delay(println(s))})
    log(s)
  }
Option variant
Ross A. Baker
@rossabaker
All of our other configs are inspectable before they're built, so I don't really like the laziness/optionality of it.
Fabio Labella
@SystemFw
you could build a bunch of different apis.
thing.withFoo(...).withBar(...)
thing { builder => builder(foo = myFoo, bar) }
Christopher Davenport
@ChristopherDavenport
def logMe[F[_]: Sync] = new logMePartiallyApplied[F]
private class logMePartiallyApplied[F[_]: Sync]{
    def apply(s: String, logAction: String => F[Unit] = {s => Sync[F].delay(println(s))}) = 
      logAction(s)
  }
Partially applied approach.
Ross A. Baker
@rossabaker
I'd like to be able to have a default argument that might fall through to an implementation of last resort, but Java doesn't let us define that for this type.
Fabio Labella
@SystemFw
right, ok
Christopher Davenport
@ChristopherDavenport
The intriguing part to me, is that due to the implicit nature, that partially applied variant is always equivalent.
Fabio Labella
@SystemFw
@ChristopherDavenport I'm not sure the partially applied works, you need a different name
as it stands, logMe[IO]("hello") will think that "hello" is Sync[F]
iirc I did make something similar work at some point, with apply, but it's more horrendous in implementation
like you need a magnet and so on
Christopher Davenport
@ChristopherDavenport
:scream: It gets worse.
Fabio Labella
@SystemFw
 found   : String("hello")
[error]  required: cats.effect.Sync[cats.effect.IO]
[error]   logMe[IO]("hello")
yep
Gavin Bisesi
@Daenyth
needs moar scala3 :p
Fabio Labella
@SystemFw
well, an easy fix for your code is renaming apply to of or build
(fun fact, when I originally suggested HttpRoutes.of I got the name while hacking on this exact problem)
(I mean the name HttpRoutes.of, not the idea, ofc)
Christopher Davenport
@ChristopherDavenport
Right, but what I really want is a rather simple syntactic change, and should be able to be automated somehow.
Fabio Labella
@SystemFw
heh, I'm not sure it's that simple, all things considered
Christopher Davenport
@ChristopherDavenport
Well noA => B => C => D to C => B => A => D should be doable.
Due to the implicit nature that’s the rearrangement, but it is baked into the language semantics that the transformation is not simple.
Fabio Labella
@SystemFw
there was a discussion a few days ago about supporting context bounds in higher-rank functions in scala 3, which was touching on a similar problem
I can see a few issues trying to implement mixing of implicits and not implicits lists. Not saying that is nonsensical or impossible, but it doesn't strike as particularly trivial, especially if you want to allow seamless explicit passing of implicit parameters as well
Fabio Labella
@SystemFw
@ChristopherDavenport if you want to indulge in evil
  def logMe[F[_]]: Magnet[F] = new Magnet[F]

  class Magnet[F[_]]
  object Magnet {
    implicit def conv[F[_]: Sync](m: Magnet[F]): LogMePartiallyApplied[F] =
      new LogMePartiallyApplied[F]

    class LogMePartiallyApplied[F[_]: Sync] {
      def apply(s: String, logAction: String => F[Unit] = { s =>
        Sync[F].delay(println(s))
      }) =
        logAction(s)
    }
  }

  def yolo = logMe[IO]("hello")
  // scala> yolo.unsafeRunSync
  // hello
tbh for a builder it's not that bad
changing names a bit
Christopher Davenport
@ChristopherDavenport
:100:
Luka Jacobowitz
@LukaJCB
How did you even come up with that :smile:
Fabio Labella
@SystemFw
I have this small library called eidos to encode IDs
mostly useless but I've learned a lot about bending scala to my will ;)
some of the stuff I have in a branch is truly crazy
like adding some sane error messages to that thing above
Christopher Davenport
@ChristopherDavenport
Sane error messaging, that seems unreasonable.
This is FP. 234sekjfasdf or it didn’t happen.
Fabio Labella
@SystemFw
with just that code if you do logMe("hello") you get "Magnet[F] does not get parameters"
let me see if I can remember how to fix that