In Scala, we generate quite a lot of code. A lot of that involves the compiler generating so-called type class instances. This mechanism is quite widespread, yet, very few people actually understand it. As a result, we, the community, settled for suboptimal practices, resulting in suboptimal performance and user experience.
Scala gives us a lot of power. We can easily model things with classes and OOP, we can pull in functional libraries and model everything with functions and values, we can implement a stateless monolith or a distributed system. And today we have a lot of books and tutorials that cover these topics: how to glue the code together to create a maintainable application with raw Futures/Akka/Cats ecosystem/Zio ecosystem/Scala as typed Python.
In many discussions about FP - especially about purely functional programming - there are talks about IO monad, IO type and so on. Its users argue that it is better than your standard imperative approach, that it helps reason, encapsulate side-effects and design more elegant programs. On the other hand, its opponents argue that programs are side-effectful by nature, so you would end up with something that needs IO for like 80% of the codebase while learning curve for newcomers would go up, so what’s the benefit? Let’s try to figure out.
So, we parsed an input - file, stream of characters or string - and we got nicely structured data in the form of a tree and/or an algebraic data type. What now?
Whether you have to do with data in the form of CSV, JSON or a full-blooded programming language like C, JavaScript, Scala, or maybe a query language like SQL, you always transform some sequence of characters (or binary values) into a structured representation. Whatever you’ll do with that representation depends on your domain and business goals, and is quite often the core value of whatever you are doing. With a plethora of tools doing the parsing for us (including the error-handling), we might easily overlook how complex and interesting a process it is.
Algebraic data structures are invaluable in functional programming. With immutable data structures reasoning about the code is easy. Concurrency requires little effort as you don’t have to be worried about locking, mutexes and semaphores - nobody can change your data anyway. If you need to update something you can just create an updated copy and use it from now on. Except if you have a nested structure and need to update something deep, deep inside.
As soon as you start mentioning functional programming, monads pop out as something that you have to know. However, hardly anyone is good at explaining what a monad is. That is why we’ll try to get some intuition about it without defining it.
While algebras are something we (programmers) rely on in our everyday work, we don’t always use them knowingly. Functional programming, however, has a relatively high number of programmers who care about correctness and mathematical formalism, that leads to it. It is no surprise that it was FP that explored the idea that if you perceive your program as a pipeline of operations, you could provide stronger guarantees if you had tools to define such pipelines mathematically.
If you work with anything that can be modeled mathematically, you most likely know that many things you work on can be expressed with algebras. However, if you are not a graduate of a computer science course or similar you might not know how ubiquitous they are and how often you rely on some of them. (And I don’t mean F-algebras and FP-concepts). So what are algebras and where can we meet some most common of them?
In FP we talk a lot about algebras, functions, and types. But types are sets, and functions are also sets. Algebras are types with operations that fulfill some conditions, which means they are also sets. So how low should we get if we want to start from the beginning? I would say we should start with finitary relations.
What would you say if I told you that in math everything is a set? That, whatever mathematical object you name, it can be defined using sets? And not sets that contain some special ingredient somewhere deep inside - but by basically wrapping up empty sets and merging them with more wrapped empty sets in various degrees of wrapping?
In the previous post, we understood how parametric types work, which lets us cover most of the cases we’ll have in our everyday coding. However, there are some interesting concepts, which, while not so heavily used, can come in handy at times.
In the previous post, we laid the foundation for understanding the type system in Scala. But concrete types only would be too little to make the language truly expressive. So, now we’ll try to parametrize it.
When I try to explain to someone why I prefer Scala to Java, and why functional programming works better with Scala, one of the arguments is that it has a better type system. But what exactly does it mean? What advantage does it have over the static type systems of languages like Java or Go?
As far as I can tell, Swagger has two main use cases: it’s a specification you can use to scaffold your client and server, or live documentation generated from an existing implementation. I have an issue with the latter when it comes to Akka HTTP.
In previous posts, we covered the most popular implicit use cases. What is left to complete the picture is the mechanics of implicits itself.
In previous posts, we covered the most basic use cases of implicits. However, to complete the image we not only need to understand how they can provide instances but also how they can transform them. Once we understand that, we can talk a bit about some patterns that combine both implicit parameters and conversions.
In the previous post, we learned a bit about type classes, as they were the major reason for introducing the mechanism. We could see that it is a great way of implementing the open-closed principle in a functional way: while the existing implementations are unchanged we can extend the behavior for new types. We haven’t seen though how to address one issue with them: how to provide behavior for potentially thousands of cases?
Implicits. For some people, they are an indispensable feature of Scala that allows them to achieve otherwise impossible things. For others, they are the sole reason to avoid using the language. As far as I can tell, the majority of the latter never really learned how to use them right.
At some point, Typelevel decided to fork Scala in order to test features that its members found useful and get feedback on these features without the need to wait for the next official Scala release. The latest such version was Typelevel Scala 4 based on Lightbend Scala 2.12.4, which I decided to use at some point. Now that everyone is migrating to 2.12.6 I can tell what TL Scala gave me for all that time.
In previous posts (#1, #2) I described a bit of theory about using sbt. However, besides long, heavy topics, there are also some smaller pieces of knowledge that you can find useful. Most of them should be obvious for people who have been using sbt a little longer, but I decided to gather these tips here nonetheless.
Scala is not the fastest language to compile. sbt adds its own overhead. So in the life of most (every?) business applications written in Scala, CI builds are so long that after git push you can go watch the next episode of a TV show. Local changes take ages, even with Zinc. And you don’t want to rewrite half the stuff nor do you have the budget to consider things like Triplequote Hydra. What then?
When I started to learn sbt, I noticed that there is a huge gap between how I’m told to write builds for simple projects and how I have to write them when I maintain a complex multi-module monstrosity. After a while I came to the conclusion that very often the way we are writing build.sbt is just cargo-cult programming.
A long time ago in the land of Scala emerged a new type-safe way of dependency injection. In the long run, it brings more trouble than it is worth.
When I browse Reddit, read Hacker News comments or google for Scala-related topics I sometimes find some misconceptions. These are not about: what is a monad or how to start using Cats, as people asking this kind of questions already have some basic knowledge about what they want to learn.
I first heard about custom Predef from Paweł Szulc. I don’t remember exact circumstances, but I think it was soon after he started working at Slam Data on Quasar. Apparently, in all of their projects, they decided to use their own Predef instead of Scala’s built-in. But what does that mean? Why would one consider it, and what would the consequences be?
When we want to better describe our domain, at some point we might want to start using types for describing what each value means. String, Int, or Double tell us everything about what we can do with a value, but do they really explain the context?
I had an issue when I had to modify some values on my test server. I could log in directly to the database, but I didn’t want to. I could use the REST API, but not all services are mapped to endpoints (and for a good reason!). Nonetheless, sometimes I needed to call them.
When you live far away from some of your best friends, you want to find some reasonable ways to stay in touch. After a while, we found out that social media and instant messaging apps are not really an answer to our needs, so we decided to give a chance to something that easily engages everyone. Most, if not all, of us know about Slack and how it (usually) improves communication within teams that use it. However, if you want to fully own your data and, for example, have access to all archives without paying high prices, you might start with some cheaper alternative. It appears there is one: Mattermost Team Edition. And that’s what we decided to try out.
Hello. In this post I’d like to describe my experiences with Android, Scala, and SBT. I will cover the goals I wanted to achieve, issues I encountered and the results I reached in the end.
I believe that the work on keeping quality high should start from the very beginning of the project. When it comes to actual implementation, setting up the build configuration is the very first thing one does. The choice of tools has a huge impact on the process and results.