Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Jan 02 23:58
    @SethTisue banned @fakubishes:nerdsin.space
  • Dec 15 2021 05:01
    som-snytt commented #12516
  • Dec 15 2021 04:38
    SethTisue edited #1312
  • Dec 15 2021 04:38
    SethTisue opened #2273
  • Dec 15 2021 04:31
    jackkoenig opened #12516
  • Dec 15 2021 04:29
    SethTisue edited #1312
  • Dec 15 2021 04:28
    SethTisue edited #1312
  • Dec 15 2021 04:27
    SethTisue labeled #9831
  • Dec 15 2021 04:27
    scala-jenkins milestoned #9831
  • Dec 15 2021 04:27
    SethTisue labeled #9831
  • Dec 15 2021 04:27
    SethTisue opened #9831
  • Dec 15 2021 03:35
    som-snytt commented #11339
  • Dec 15 2021 03:27
    som-snytt labeled #12494
  • Dec 15 2021 03:07
    SethTisue edited #1312
  • Dec 15 2021 03:07
    SethTisue edited #1312
  • Dec 15 2021 03:05
    SethTisue edited #1312
  • Dec 15 2021 03:05
    SethTisue edited #1312
  • Dec 15 2021 03:05
    SethTisue edited #1312
  • Dec 15 2021 02:58
    SethTisue edited #1312
  • Dec 15 2021 02:58
    SethTisue synchronize #1312
Peter Aaser
@PeterAaser
For instance, if you want to do something if the option isn't empty, and supply a default if it's not there, you're actually after .map(f).getOrElse(replacement) instead of primitively matching the types
Looks like code sir
zygfryd
@zygfryd
I often do the latter because why would I allocate two closures for such a simple operation
Peter Aaser
@PeterAaser
Depends if it's hot or just a simple config step or something
Tim
@tirumalesh123
What is lifting in map
Fabio Labella
@SystemFw
@tirumalesh123 can you add a bit more context?
Tim
@tirumalesh123
Let's say I have a method which returns optional if I want to get the value inside optional should I use lifting functions
Above context I got from functional programming in scala
Marcin Sokrates
@marcinsokrates_twitter
Is there a way to circumvent sound generic typing and pass a type argument to a function expecting a type argument with a different bound, like asInstanceOf allows us to do with values?
I mean I have a foo[T: ClassTag] and want to specialize it dynamically to call bar[T <: Bar] if it knows it can; the proper way would be to introduce a typeclass I know, but it's so much boilerplate
Luciano
@lJoublanc
you can look at shapeless.Typeable. That, as you say, is a typeclass, and allows you to pattern match / extract your type without any isInstanceOf business. @marcinsokrates_twitter
vimalaguti
@vimalaguti
if I set trait F[-A] there is an ambiguous choice between F[B] and F[C] when I do new C.list
Fabio Labella
@SystemFw

@tirumalesh123 lift is just another name for map, with a slightly rearranged signature.
map normally looks like def map(fa: F[A])(f: A => B): F[B]. If you rearrange the arguments you get def lift(f: A => B): F[A] => F[B], so you can look at Functor as the api for lifting functions of one argument in F. This extends to Applicative, which lets you lift functions of multiple arguments into F, and ultimately into Monad, which gives you the ability to change the structure of one computation based on the result of another.

et's say I have a method which returns optional if I want to get the value inside optional should I use lifting functions

yeah, pretty much. You should just map (or flatMap) and transform the Option that way. I don't particularly like saying "the value inside the F" because it's misleading in the long run, but it's a decent approximation at first

Daniel Sebban
@dsebban_twitter
@SystemFw Are you saying this because of other Monads like State and IO that are not containers as opposed to List and Option ?
Peter Aaser
@PeterAaser
@dsebban_twitter many functors aren't containers
not just monads
take for instance a deserializer, aka Deserializer[A](run: Array[Byte] => A)
it has a map operator A => B giving us a Deserializer[B]
And it's very interesting close relative Serializer[A]
and the more mysterious contramap
Peter Aaser
@PeterAaser
You can even make a completely useless functor!
Lockna
@Lockna_gitlab
Hi! I'm new to Scala and want to programm a project to train my skills. Has anyone a good idea for a such project? (No swing please)
Rob Norris
@tpolecat
Write a command-line app to look for words in files in a given directory.
It's a good short exercise that gives a lot of design decisions to think about.
Lockna
@Lockna_gitlab
You mean, I say for which word he should look in a given directory? Am I right?
Long Cao
@longcao
I think @tpolecat means something like grep - you have a word/some words that you want to search for in a directory
Ghost
@ghost~54f4b69115522ed4b3dcb16d
I think you forgot to say no command-line apps.
Seth Tisue
@SethTisue
maybe those aren’t “projects”, but they’re good for learning language fundamentals and the collections API. is that what you currently want to learn?
trying to build some kind of actual useful thing (whether it’s command line, web, desktop, or whatever) usually involves learning a bunch of APIs at the same time you’re trying to learn fundamentals,which can be pretty distracting
Rob Norris
@tpolecat
Right. Commandline is the simplest of those if you want to write an interactive program.
But otherwise yeah what Seth said. Go through some exercises. It really doesn't matter which.
Lockna
@Lockna_gitlab
Thank you very much! @SethTisue @tpolecat @longcao @som-snytt
Fabio Labella
@SystemFw

@dsebban_twitter

Are you saying this because of other Monads like State and IO that are not containers as opposed to List and Option

yes

and even List or Option can be viewed as either containers or computations. Also, I'm actually quite keen on explaining the datatypes (State, IO, List, Option) and the idea of higher-kinded types to represent computation separately (and before) from whatever algebra they happen to form (e.g. Monad). Consequently, I don't like (when teaching) saying that IO or Option are monads. They form a Monad. This might seem pedantry but it's actually quite important for a few reasons imho (which I might expand on if you care). Obviously I probably do say "the IO monad" a bunch of times when talking casually, but I consider that an abuse of notation, for brevity only
Rob Norris
@tpolecat
:+1:
Daniel Sebban
@dsebban_twitter
Interesting , please expand :)
Rob Norris
@tpolecat
As a data type List is a container, but as a computation it can model an all-possible-worlds kind of nondeterminism.
As a data type Either is a simple disjunction, but as a computation it can model exception-handling.
Etc.
@SystemFw likely has a more fundamental take, I just felt like butting in ;-)
Ghost
@ghost~54f4b69115522ed4b3dcb16d
I thought it forms a burrito.
Marcin Sokrates
@marcinsokrates_twitter
Has using a variable branching factor in Vectors, so small Vectors weren't as huge compared to their payload, been explored?
Fabio Labella
@SystemFw
@dsebban_twitter well, I personally have a fairly precise path for explaining the mindset behind those abstractions, although that path is tuned for completeness of understanding, not necessarily ramp up time, so it's not for everyone
Fabio Labella
@SystemFw

but basically it starts from thinking about what types are for (and not what they are against, to quote Connor McBride), to the fact that they are given meaning and semantics not by their underlying representation, but by the operations you define on them (let's say just functions for now).


The second step would be defining algebras as specifications of part of the behaviour of a data type. This works really well with typeclasses, which give you an has a, rather than the is a relationship you typically get from OO style interfaces. The result of this thought process is that given a datatype, part of what it can do is specified by operations that are unique to that type, and part by algebras (i.e. Monoid, Functor, and so on). This kind of reasoning can be explained with simple types and lower kinded typeclasses only.


Then, you move on to explaining how types of higher kind can be used not just for containers, but for computations as well: List and Option are interesting because they can be viewed both ways, but there are somethings that really only make sense as computations (like State or IO).


At this point you can actually explain F-A-M as algebras that specify part of the behaviour of higher kinded types:

  • Functor lifts functions of one argument into F
  • Applicative lifts functions of n arguments into F
  • Monad gives you context sensitivity: the ability to change the structure of a computation based on the result of a previous one

The final bit is learning how to operate on types based on their algebras and operations only, while being agnostic to their representation (e.g avoiding pattern matching on Option): this is propedeutic to learning about types which either have an opaque representation (IO) or a very complex one (fs2.Stream). It also means that you can tackle a new library which exposes different types, and basically know most of what you need to do to use it once you know which algebras it forms (e.g. doobie ConnectionIO).


I guess the main problem with this approach is that it requires some upfront motivation, and ideally a mentor to give you clear explanations and "unstuck" you along the way

@dsebban_twitter

Daniel Sebban
@dsebban_twitter
I think completeness of understanding is important, shallow understanding for these concepts will limit you and eventually make you give up on FP. I appreciate the answers, piecing together data types -> hkt ->computation -> algebras -> monad is indeed the clearest explanation I have seen so far
Fabio Labella
@SystemFw
yeah, imho is the best way of explaining things but it doesn't fare very well in "what's the point of monads" pub conversations (or reddit flamewars) :P
note that the fact that algebras only describe part of the behaviour of a data type really is crucial: if you understand that, you realise that "how do I extract a value out of a monad" is a question that literally makes no sense on multiple levels : the monad is the algebra, not the type, and extraction appears nowhere in the definition of monad, although it might be part of the behaviour of a given datatype which also happens to form a monad (like State), but makes no sense for others (like IO)
Seth Tisue
@SethTisue
@marcinsokrates_twitter if nobody answers here about Vector branching factor, you might try the scala/contributors room, and/or https://contributors.scala-lang.org
Josh
@joshlemer
I did recently ask about making Vectors of size < 32 use arrays of exactly that size rather than of size 32, @Ichoran responded something to the effect of that allocating the extra bytes are very likely cheaper than the additional logic of handling different array sizes