A 3-day bug hunt on a 3-person team costs up to β¬7,200 in lost engineering time. This workshop teaches you to prevent that β unit tests, data tests, and integration tests for PySpark and Databricks Lakeflow, including Spark Declarative Pipelines.
This post begins the series of posts about Scala's features called "One Scala feature per week". Every week one particular Scala's functionality will be covered. This beginning post will explain context bound.
Scala has a rich type system and one of interesting features are type bounds.
Scala is a hybrid language implementing both functional and object-oriented features. One of them that merits to be analyzed is currying.
In the occasion of the post about currying I mentioned shortly the existence of similar concept called partially applied functions. This idea will be explained in this post.
Recently in this series about Scala features I covered the partially applied functions. At first glance we could think they are the same as partial functions. But it's not really true and this post will explain why.
Scala has a lot of syntactic sugar. Despite the fact that most of times it pretty simply understandable, it occurs often that it increases the learning curve. One of symbols widely used in Scala and hard to understand at first contact is the underscore.
I am a class storing a single public and immutable value and at runtime I'm allocated on stack. What's my name ?
Lower and upper bounds are not a single Scala feature related to the types. Another one is the variance.
Scala has a rich types ecosystem with sometimes almost philosophical categories. One of such categories is the one of existential types.
Types and type-safety in Scala have a special privileged place. But this wide range of techniques to deal with them makes the language discovery more difficult. And at first glance one of difficult type-related concepts are higher-kinded types, covered in this post.
When a programming language provides operator overloading, the learning curve increases most of the time because of the syntactic sugar it brings. After all more of operations will be expressed as not meaningful (at least in first approach) symbols. Scala also comes with its own syntactic sugar that can be applied in a lot of places: sequences, functions or conversion.
Multiple inheritance can lead to a lot of issues and one of the most known is the diamond problem where the compiler doesn't know which of inherited methods use. However in Scala we can use another structure to compose a class with several different classes, keeping us far away of the diamond problem. This structure is called mixin.
Some time ago I covered in this blog the complexity of Scala immutable collections, explaining a little what happened under-the-hood. Now it's a good moment to back to this topic and apply it for mutable collections.
Scala implicits have many drawbacks but in some cases their use is justified. They remain though one of the advanced concepts for a lot of newcomers and it's worth explaining them a little bit more in details.
Scala's apply method is a convenient way to create objects without the use of new operator and thus, to reduce the verbosity just a little. Often, as for instance in the case of case classes, apply is accompanied by its opposite, unapply, used in its turn to build extractors.
At first glance Scala's pattern matching looks similar to Java's switch statement. But it's only the first impression because after analyzing the differences we end up with some smarter idea.
For loop was maybe the most used iterative structure in Java before the introduction of lambda expressions. With this loop we're able to write everything - starting with a simple mapping and terminating with a more complex "find-first element in the collection" feature. In Scala we can made these operations with monads and despite that, for loop is a feature offering a lot of possibilities.
Scala's lazy instances generation can be helpful in a lot of places. It simplifies writing since we can declare an instance at right and common place and delay its physical creation up to its first use. In Java we've this possibility too, though, it's much more verbose than in Scala.
In one of previous posts we've discovered Scala's laziness expressed with lazy operator. However it's not a single solution to implement it. Another one uses evaluation strategies covered in below paragraphs.
If you're reading this blog, you've certainly noticed its big interest for Apache Spark. One of first problems we encounter with this data processing framework is a "Task not serializable" error that is caused by a not serializable closure. In this post, outside of Spark's context, we'll focus on these specific functions.
Apache Spark inspired not only the last week's post about closures but also the one you're reading about quasiquotes - a mysterious Scala experimental feature those existence we can difficulty suspect in the first months of work with the language.
Scala is known as more concise language than Java. One of points showing this characteristics are classes constructors that can be defined with a single line, alongside of class name definition.
Who didn't encounter a question about helper classes ? For ones, creating them isn't legitimate since everything we can link to an object. For the others they're fully legal because they help to keep code base understandable. Scala comes with an idea that can make both sides agree - package objects.
At first glance, the try-catch block seems to be the preferred approach to deal with exceptions for the people coming to Scala from Java. However, in reality, this approach is not a single one available in Scala.
Checked exceptions don't exist in Scala. However thanks to functional data structures we can manipulate expected errors differently.
Scala doesn't come with static keyword as Java does. However, with object singleton type it allows to define static properties and methods. It goes even further and thanks to object "class" lets us to build an instruction called companion objects.
Duck typing and Scala aren't the words going well together. However with a special kind of types we can achieve similar effect that in dynamically typed languages.
Before I went to Scala I had never imagined that we could do such many things nothing but with a types system. Aside of higher-kinded types or type boundaries that we can easily find in other languages, Scala offers more advanced type features as path-dependent types covered below.
The series about Scala types system continues. After last week's article about path-dependent types, it's time to discover another type-related feature - self-types.
With increasing number of computation power, the parallel computing gained the popularity during the last years. Java's concurrent package is one of the proofs for that. But Scala, even though it's able to work with Java's concurrent features, comes also with its own mechanisms. Futures are one of them.
Have you ever wondered why in Scala we can directly reverse a String and in Java we must use a StringBuilder especially for it? If yes, this post provides a little bit more explanation by focusing on Scala's data types equivalents to Java's primitives (+ String) called rich wrappers.
I've always found concatenating Strings with "+" a laborious task. Hence when I've discovered Scala and its text construction methods I was immediately convinced. And as you can imagine, this topic merits its own short post in the Scala category.
Nowadays a lot of SDKs and libraries are written with Java. Fortunately dealing with Java code in Scala is possible and even in case of collections.
Even though the regular expressions look similarly in a lot of languages, each of them brings some own constructs. Scala is not an exception for this rule and we'll try to see it in this post.
Some people coming from Java are often confused about enumerations. In Java, they're often used not only to enumerate things as in dictionaries but also to create singletons. In Scala, the latter use case is much more reserved to objects and apparently, only the former one remains. We'll see through this post whether it's true or not.
During the years Java was much more verbose than its JVM-based colleagues (Clojure, Groovy, Scala, ...). But it changed with Java 8 and its Lambda expressions. However the years of the verbosity brought some patterns into Java-based applications. One of them is known as SAM and fortunately it can be easily used with Scala.
Scala Stream offers something we have not a habit to see in other languages - lazy computation of the values alongside the memoization. However it's sometimes misleading and some people think about Streams as about iterators, i.e. a data structure computing and forgetting about the results. Such thinking can often lead to memory problems, especially with infinite streams.
As a former Java engineer, when I have started to work with Scala, I was very early punished for my bad habits about mutable collections. In this post I will show you the story which learned me to prefer the immutability everywhere it's possible.
When I was analyzing one of Apache Spark GraphX functions for the first time I faced a class annotated with @specialized annotation. Since then I decided to find more information about it and share them with you in this post.
When I was reading about the Await implementation in Scala, I found a method called blocking. At that time I've read some articles to understand it but I hadn't a chance to play with it. Now it's the case and I will share my findings with you.
When I was working with Java and Spring framework, the annotations were my daily friend. When I have started to work with Scala, I haven't seen them a lot. It was quite surprising at the beginning. But with every new written line of code, I have started to see them more and more. After that time it's a good moment to summarize the experience and focus on the Scala annotations.
The Futures appear as the first element to learn of Scala's asynchronous world. They're quite simple and probably exist in the languages you have been working on before. But they're not the single asynchronous types in Scala because they are accompanied by Promises covered in this post.
When we come to Scala and see the sealed keyword, we often wonder "why". After all, having all subclasses defined in one or more files shouldn't be a big deal. For us, programmers, it's not but for the compiler, it has an importance. In this post, I will try to show the sealed class use cases.