Making sense of Scala FP Libraries - scala

Just for the sake of quick clarity for someone who wants to start working with Scala FP library, on a journey to become better at pure FP.
Would someone clarify the difference/relation between Cats and Cats-Effect, Cats-Effects IO? On top of that, where does Zio, and Monix stand with respect to it? Finally, what would be the relation to ScalaZ 7/8?
So far based on what I have read, a good combination of the library to work with based on the documentation available and what they do would be Cats, then Cats-Effect, and ZIO which could be used with Cats-effects? But I can't quite understand well why and would like to set myself a good path to learn to be better FP programmer while remaining productive, and not having to finish "FP Programming in Scala" before I start making choices.

Scalaz started as an attempt to port to Scala some well-established abstractions from Haskell (like typeclasses for Monad, Functor and much more). Problem with it was, that it doesn't have great documentation, so basically, you needed to use documentation of Haskell libraries in order to understand how to use certain Scalaz resources.
Nowadays, you there's Sam Halliday’s Functional Programming for Mortals which you can use as a learning source for Scalaz.
Cats was created later, as essentially reimplementation what Scalaz provided. Cats has a lot better documentation than Scalaz, there is also great book Scala with Cats.
Scalaz and Cats might have very similar purposes, so they're competing as general purpose FP library for Scala. There are also libraries that serve as compatibility-layer between both libraries.
Cats-Effect is a library, which provides "standard" IO monad for Scala (again idea borrowed from Haskell (?)). It depends on code from Cats core library.
You can read more here why there is a need for IO monad for Scala, when there's standard's library Future.
Monix is another library, which provides an IO monad for Scala, but this time it's called Task. It was meant to be a more high-level abstraction and provide easier interop with code using standard library Future. In reality, it shares a lot of code with Cats-Effect and creator of Monix Alexandru Nedelcu is also one of the main contributors of Cats-Effect.
Here you may find more information about the differences between cats.effect.IO and monix.eval.Task, as well as some of the history of both.
Lastly, there is ZIO which started as an attempt to reimplement IO monad for Scalaz, but ended up as a completely separate library (so it does not depend on Scalaz codebase).
The great thing about all libraries is, they're all implementing typeclasses (like Sync or Concurrent) from Cats-Effect, so using pattern called tagless final you're able to switch between implementation.
That hierarchy of typeclasses also serve as an interpolation library between, many (all (?)) of the IO implementations (as by the time it was created there already were fs2.Task, monix.Task & scalaz.IO). Also, apparently, in a future the IO part may be moved into another module, leaving only the interoperability typeclasses.
If you don't use tagless final you can still use modules that provide interop between certain IO monads, for example zio-interop-cats (between ZIO and Cats-Effect or catnap for Monix-Cats-Effect.
For your information, I recently extended this answer into a full-fledged blog post.

Related

Scalaz vs ReactiveX

I´ve been working for a couple years with ReactiveX extension in Java, but now I move to scala, and I´ve seen that many people use the extension ScalaZ to perform more functional programing in Scala.
Is there´s any differences to use ScalaZ extension, or just adapt reactiveX to Scala which I did and I know is playing nice with Scala?.
And after read this blog https://medium.com/#luijar/the-observable-disguised-as-an-io-monad-c89042aa8f31 I though the observable was working as a IO monad as in Scalaz
Regards.
Scalaz and ReactiveX are completely orthogonal to one another.
Scalaz is focused on bringing Category theory à la Haskell to Scala. It brings tons of type classes with Monads and Monoids and other goodies.
ReactiveX on the other hand is more focused on bringing reactive programming concepts to the language. It comes with Observables and Observers.
You can even use RxScala in conjunction with Scalaz! There's a repo called RxScalaz providing some of the typeclass instances of Scalaz for RxScala. Check it out here: https://github.com/everpeace/rxscalaz
If you're happy with "only" using RxScala, then there's no "real" need to accomodate Scalaz into your project.

How to enforce Functional Programming on Scala

I'm starting to learn Functional Programming and would like to do so with Scala, not Haskell or Lisp.
But some people claim that learning Scala as the first functional language slows down your learning of Functional Programming, because Scala allows you to program both ways, and one tends to program the procedural way when confronted with a hard problem.
How can i make sure that 'm programming in a purely functional way? Maybe, due to not being able to properly distinguish both styles, I'll inadvertently program procedurally).
I know, for example, that I should only use vals and not vars.
The other answers have made some good points, but for an attempt to quickly get down some guidelines, here's how I'd start:
Firstly, some things to completely avoid:
Don't use the var keyword.
Don't use the while keyword.
Don't use anything in the scala.collection.mutable package.
Don't use the asInstanceOf method.
Don't use null. If you ever come across null (in someone else's code), immediately wrap it in a more appropriate datatype (usually Option will do nicely).
Then, a couple of things to generally avoid:
Be wary of calling anything with a return type of Unit. A function with a return type of Unit is either doing nothing, or acting only by side-effects. In some cases you won't be able to avoid this (IO being the obvious one), but where you see it elsewhere it's probably a sign of impurity.
Be wary of calling into Java libraries - they are typically not designed with functional programming in mind, and will often require you to abandon the functional approach.
Once you've avoided these things, what can you do to move your code to being more functional?
When you're performing direct recursion, look for opportunities to generalise it through the use of higher order combinators. fold is likely your biggest candidate here - most operations on lists can be implemented in terms of a suitable fold.
When you see destructuring operations on a data structure (typically through pattern matching), consider whether instead you can lift the computation into the structure and avoid destructuring it. An obvious example is the following code snippet:
foo match {
case Some(x) => Some(x + 2)
case None => None
}
can be replaced with:
foo map ( _ + 2 )
I dare say that your goal is already misleading:
I'm starting to learn Function Programming, and I really wanna learn
Scala, not Haskell or Lisp.
If you are really interested in learning concepts of function programming, then why not use a language such as Haskell that (more or less) does not allow you to use procedural or object-oriented concepts? In the end, the language is "just" a tool that helps you learning concepts of FP, you could just as well read loads of papers about FP. At least theoretically, I think it is usually easier to learn concepts of computer science with concrete tools at hand.
On the other hand, if you are interested in learning the language Scala, then why not use all features that it offers, regardless of whether they stem from the FP or the OO world?
In order to conclude with a somewhat practical advise: You could search for FP tutorials that use Scala or for blog entries etc. that describe how to realise certain FP-concepts in Scala and try to follow them. This way, it is less likely that you make use of non-FP concepts.
You don't buy a Ferarri to deliver furniture. Scala's fundamental strength is the fact that in your words, it goes both ways:). Whether or not you are programming in a functional style is decided by the techniques you use.
The best thing you can do is thoroughly review fundamental concepts of functional programming and seek the appropriate Scala implementation of the respective concepts. But if you want to program purely functional style, then go for Haskell, Lisp, Erlang, OCaml, or whatever other purely functional dialect.
Functional programming
Introduction
Functional thinking
Scala
If you want to learn Scala, then make sure to include both OO and FP in your learning curve. Lambda expressions + OO concepts + syntactic sugar made possible by IMHO the most advanced compiler on the face of the planet lead to something quite amazing. Take advantage of it!
I think learning is non linear process, it helps to see lots of ways of doing the same thing, also be opportunistic and use any learning resources that are available for you. For example Martin Odersky the creator of Scala offers a free course called "Functional Programming Principles in Scala" https://class.coursera.org/progfun-002/class/index there are some very high quality video lectures, and some really good assignments where the automated grader will tell you that your code is not functional enough and you loose style points because you are using var instead of val
I think the thing you want to focus on is learning the Functional Programming Paradigm and for me learning a paradigm is about learning what types of problems are easy to solve in one paradigm and are hard to solve in another paradigm. Focus on the paradigm and I think you will find that learning both about Haskell and Scala will teach you the functional paradigm faster, because you will be able to ask the question what are the common features between Scala and Haskell, what are the differences .... etc
I know, for example, that I should only use vals and not vars.
That's already a good start, other non-so-functional things to avoid are mutable collections and loops.
Have a look at immutable collections and recursion instead.
Of course, once you are familiar with the functional concepts, there might also be good reasons to use scala's non-functional features.

What well developed iteratee/pipes libraries are available for Scala?

Does Scala have any well developed libraries in the spirit of Haskell's pipes, or at least iteratee?
I found Play's iteratee library first, but I couldn't make it work, and it seems tightly coupled with Play's concurrency primitive Promise, which could be inappropriate in many cases.
Scalaz has some iteratee support (like IterV), but it seems there are only core classes with no additional support functions, predefined iteratees/enumerators etc. Also I couldn't find any documentation, even scaladoc is very sparse, so it's quite difficult to use properly.
And I couldn't find anything similar to pipes.
Building up on comments from Travis, currently there are:
Scalaz 7 iteratee package (iterv, you mentioned, is a compatibility layer with scalaz 6)
A port of Conduit library
Runar's scala-machines library (presentation, haskell version)

Why doesn't Scala have an IO Monad?

I'm wondering why Scala does not have an IO Monad like Haskell.
So, in Scala the return type of method readLine is String whereas in Haskell the comparable function getLine has the return type IO String.
There is a similar question about this topic, but its answer it not satisfying:
Using IO is certainly not the dominant style in scala.
Can someone explain this a bit further? What was the design decision for not including IO Monads to Scala?
Because Scala is not pure (and has no means to enforce that a function is pure, like D has) and allows side effects. It interoperates closely with Java (e.g. reuses big parts of the Java libraries). Scala is not lazy, so there is no problem regarding execution order like in Haskell (e.g. no need for >> or seq). Under these circumstances introducing the IO Monad would make life harder without gaining much.
But if you really have applications where the IO monad has significant advantages, nothing stops you from writing your own implementation or to use scalaz. See e.g. http://apocalisp.wordpress.com/2011/12/19/towards-an-effect-system-in-scala-part-2-io-monad/
[Edit]
Why wasn't it done as a lazy and pure language?
This would have been perfectly possible (e.g. look at Frege, a JVM language very similar to Haskell). Of course this would make the Java interoperability more complicate, but I don't think this is the main reason. I think a lazy and pure language is a totally cool thing, but simply too alien to most Java programmers, which are the target audience of Scala. Scala was designed to cooperate with Java's object model (which is the exact opposite of pure and lazy), allowing functional and mixed functional-OO programming, but not enforcing it (which would have chased away almost all Java programmers). In fact there is no point in having yet another completely functional language: There is Haskell, Erlang, F# (and other MLs) and Clojure (and other Schemes / Lisps), which are all very sophisticated, stable and successful, and won't be easily replaced by a newcomer.

Can you suggest any good intro to Scala philosophy and programs design?

In Java and C++ designing program's objects hierarchy is pretty obvious. But beginning Scala I found myself difficult to decide what classes to define to better employ Scala's syntactic sugar facilities (an even idealess about how should I design for better performance). Any good readings on this question?
I have read 4 books on Scala, but I have not found what you are asking for. I guess you have read "Programming in Scala" by Odersky (Artima) already. If not, this is a link to the on-line version:
http://www.docstoc.com/docs/8692868/Programming-In-Scala
This book gives many examples how to construct object-oriented models in Scala, but all examples are very small in number of classes. I do not know of any book that will teach you how to structure large scale systems using Scala.
Imperative object-orientation has
been around since Smalltalk, so we
know a lot about this paradigm.
Functional object-orientation on the
other hand, is a rather new concept,
so in a few years I expect books
describing large scale FOO systems to
appear. Anyway, I think that the PiS
book gives you a pretty good picture
how you can put together the basic
building blocks of a system, like
Factory pattern, how to replace the
Strategy pattern with function
literals and so on.
One thing that Viktor Klang once told me (and something I really agree upon) is that one difference between C++/Java and Scala OO is that you define a lot more (smaller) classes when you use Scala. Why? Because you can! The syntactic sugar for the case class result in a very small penalty for defining a class, both in typing and in readability of the code. And as you know, many small classes usually means better OO (fewer bugs) but worse performance.
One other thing I have noticed is that I use the factory pattern a lot more when dealing with immutable objects, since all "changes" of an instance results in creating a new instance. Thank God for the copy() method on the case class. This method makes the factory methods a lot shorter.
I do not know if this helped you at all, but I think this subject is very interesting myself, and I too await more literature on this subject.
Cheers!
This is still an evolving matter. For instance, the just released Scala 2.8.0 brought support of type constructor inference, which enabled a pattern of type classes in Scala. The Scala library itself has just began using this pattern. Just yesterday I heard of a new Lift module in which they are going to try to avoid inheritance in favor of type classes.
Scala 2.8.0 also introduced lower priority implicits, plus default and named parameters, both of which can be used, separately or together, to produce very different designs than what was possible before.
And if we go back in time, we note that other important features are not that old either:
Extractor methods on case classes object companions where introduced February 2008 (before that, the only way to do extraction on case classes was through pattern matching).
Lazy values and Structural types where introduced July 2007.
Abstract types support for type constructors was introduced in May 2007.
Extractors for non-case classes was introduced in January 2007.
It seems that implicit parameters were only introduced in March 2006, when they replaced the way views were implemented.
All that means we are all learning how to design Scala software. Be sure to rely on tested designs of functional and object oriented paradigms, to see how new features in Scala are used in other languages, like Haskell and type classes or Python and default (optional) and named parameters.
Some people dislike this aspect of Scala, others love it. But other languages share it. C# is adding features as fast as Scala. Java is slower, but it goes through changes too. It added generics in 2004, and the next version should bring some changes to better support concurrent and parallel programming.
I don't think that there are much tutorials for this. I'd suggest to stay with the way you do it now, but to look through "idiomatic" Scala code as well and to pay special attention in the following cases:
use case classes or case objects instead of enums or "value objects"
use objects for singletons
if you need behavior "depending on the context" or dependency-injection-like functionality, use implicits
when designing a type hierarchy or if you can factor things out of a concrete class, use traits when possible
Fine grained inheritance hierarchies are OK. Keep in mind that you have pattern matching
Know the "pimp my library" pattern
And ask as many questions as you feel you need to understand a certain point. The Scala community is very friendly and helpful. I'd suggest the Scala mailing list, Scala IRC or scala-forum.org
I've just accidentally googled to a file called "ScalaStyleGuide.pdf". Going to read...