<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="https://feeds.feedblitz.com/feedblitz_rss.xslt"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:webfeeds="http://webfeeds.org/rss/1.0"  xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
<channel>
	<title>Baeldung - Scala</title>
	<atom:link href="https://www.baeldung.com/scala/feed" rel="self" type="application/rss+xml" />
	<link>https://www.baeldung.com/scala</link>
	<description>Learn about Scala in practice</description>
	<lastBuildDate>Tue, 15 Apr 2025 12:17:12 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
<meta xmlns="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
<item>
<feedburner:origLink>https://www.baeldung.com/scala/csv-files-read-write</feedburner:origLink>
		<title>CSV Files in Scala</title>
		<link>https://feeds.feedblitz.com/~/915283508/0/baeldung/scala~CSV-Files-in-Scala</link>
		
		<dc:creator><![CDATA[Emmanouil Varvarigos]]></dc:creator>
		<pubDate>Sat, 22 Mar 2025 04:15:40 +0000</pubDate>
				<category><![CDATA[Libraries]]></category>
		<category><![CDATA[Scala Numbers]]></category>
		<category><![CDATA[Scala Strings]]></category>
		<category><![CDATA[csv]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/csv-files-read-write</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" fetchpriority="high" /><p>Learn how to read and write CSV files with Scala.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/915283508/0/baeldung/scala~CSV-Files-in-Scala">CSV Files in Scala</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/915283508/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-11-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/number-formats">Different Ways to Format Numbers in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/cats-effect-ioapp">IOApp in Cats Effect</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/remove-first-n-digits">Remove the First n Digits of a Number in Scala</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11.jpg 1200w" sizes="(max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>In this tutorial, we&#8217;ll demonstrate different ways to read and write <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/java-csv">CSV files</a> in Scala. Of course, our demonstration wouldn&#8217;t be complete if we didn&#8217;t explore some of the most popular libraries that provide CSV read and write capabilities.</p>
<p>Hence, we included sections for <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://github.com/tototoshi/scala-csv">Scala CSV</a>, <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/opencsv">Open CSV</a>, and <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/apache-commons-csv">Apache Commons CSV</a> libraries.</p>
<h2 id="bd-building-blocks" data-id="building-blocks">2. Building Blocks</h2>
<div class="bd-anchor" id="building-blocks"></div>
<p>To make our examples comparable and easier to work with, let&#8217;s define two Scala traits that every CSV library will implement, namely the <em>CommaSeparatedValuesWriter</em> and the <em>CommaSeparatedValuesReader</em>.</p>
<p>Specifically, the <em>CommaSeparatedValuesWriter</em> defines a method that yields a convenient CSV file digest<em>:</em></p>
<pre><code class="language-scala">trait CommaSeparatedValuesReader {
  def read(file: File): CSVReadDigest
}</code></pre>
<p>The <em>CSVReadDigest, </em>which is the return type of the read function, contains headers and rows as properties:</p>
<pre><code class="language-scala">case class CSVReadDigest(headers: Seq[String], rows: Seq[Seq[String]])</code></pre>
<p>Equally with the <em>CommaSeparatedValuesWriter,</em> the <em>CommaSeparatedValuesWrites</em> defines a method that writes headers and rows to a given file:</p>
<pre><code class="language-scala">trait CommaSeparatedValuesWriter {
  def write(
    file: File,
    headers: Seq[String],
    rows: Seq[Seq[String]]
  ): Try[Unit]
}</code></pre>
<h2 id="bd-printwriter-and-bufferedreader" data-id="printwriter-and-bufferedreader">3. <em>PrintWriter</em> and <em>BufferedReader</em></h2>
<div class="bd-anchor" id="printwriter-and-bufferedreader"></div>
<p>Before we import any external libraries, it&#8217;s useful to showcase how we can write and read a CSV file using readily available Java tools, the <em>PrintWriter</em> and <em>BufferedReader</em>.</p>
<h3 id="bd-1-write" data-id="1-write">3.1. Write</h3>
<div class="bd-anchor" id="1-write"></div>
<p>The <em>SimpleCSVWriter</em> prints the file contents by iterating through the input data and appending them to the underlying <em>PrintWriter</em>:</p>
<pre><code class="language-scala">class SimpleCSVWriter extends CommaSeparatedValuesWriter {
  override def write(
    file: File,
    headers: Seq[String],
    rows: Seq[Seq[String]]
  ): Try[Unit] = Try {
    val writer = new PrintWriter(file)
    writer.println(headers.mkString(","))
    rows.foreach(row =&gt; writer.println(row.mkString(",")))
    writer.close()
  }
}</code></pre>
<h3 id="bd-2-read" data-id="2-read">3.2. Read</h3>
<div class="bd-anchor" id="2-read"></div>
<p>The <em>SimpleCSVReader</em> reads a file&#8217;s contents by leveraging the <em>BufferedReader</em> interface. Additionally, the file contents are exhausted by recursively calling the <em>readLinesRecursively</em> method, which invokes the <em>BufferedReader</em> <em>readline</em> method for each line until the end of the file is reached:</p>
<pre><code class="language-scala">class SimpleCSVReader extends CommaSeparatedValuesReader {
  override def read(file: File): CSVReadDigest = {
    val in = new InputStreamReader(new FileInputStream(file))
    val bufferedReader = new BufferedReader(in)
    @tailrec
    def readLinesRecursively(
      currentBufferedReader: BufferedReader,
      result: Seq[Seq[String]]
    ): Seq[Seq[String]] = {
      currentBufferedReader.readLine() match {
        case null =&gt; result
        case line =&gt;
          readLinesRecursively(
            currentBufferedReader,
            result :+ line.split(",").toSeq
          )
      }
    }
    val csvLines = readLinesRecursively(bufferedReader, List())
    bufferedReader.close()
    CSVReadDigest(
      csvLines.head,
      csvLines.tail
    )
  }
}</code></pre>
<h2 id="bd-scala-csv" data-id="scala-csv">4. Scala CSV</h2>
<div class="bd-anchor" id="scala-csv"></div>
<p>Scala CSV is a Scala library that provides traits with methods that accept and return Scala data structures making CSV handling less cumbersome since no Java-to-Scala conversions are needed.</p>
<h3 id="bd-1-write-1" data-id="1-write-1">4.1. Write</h3>
<div class="bd-anchor" id="1-write-1"></div>
<p>The library&#8217;s trait that provides CSV read capabilities is the <em>CSVWriter</em>. The <em>ScalaCSVWriter</em> wraps the <em>CSVWriter</em> which trivializes the task of writing lines to a CSV file by exposing functions that accept <em>Seq[Any]</em> arguments:</p>
<pre><code class="language-scala">class ScalaCSVWriter extends CommaSeparatedValuesWriter {
  override def write(
    file: File,
    headers: Seq[String],
    rows: Seq[Seq[String]]
  ): Try[Unit] = Try {
    val writer = CSVWriter.open(file)
    writer.writeRow(headers)
    writer.writeAll(rows)
    writer.close()
  }
}</code></pre>
<h3 id="bd-2-read-1" data-id="2-read-1">4.2. Read</h3>
<div class="bd-anchor" id="2-read-1"></div>
<p>Likewise, reading a file with ScalaCSV <em>CSVReader</em> is straightforward. The reader&#8217;s method <em>all</em> returns the file as a <em>List[List[String]]</em> hence the <em>ScalaCSVReader</em> wrapper implementation is quite short:</p>
<pre><code class="language-scala">class ScalaCSVReader extends CommaSeparatedValuesReader {
  override def read(file: File): CSVReadDigest = {
    val reader = CSVReader.open(file)
    val all = reader.all()
    reader.close()
    CSVReadDigest(all.head, all.tail)
  }
}</code></pre>
<h2 id="bd-opencsv" data-id="opencsv">5. OpenCSV</h2>
<div class="bd-anchor" id="opencsv"></div>
<p>OpenCSV is a popular and widely used Java library for reading and writing CSV files thus we&#8217;ll proceed to create our own Scala wrapper implementations to showcase it.</p>
<h3 id="bd-1-write-2" data-id="1-write-2">5.1. Write</h3>
<div class="bd-anchor" id="1-write-2"></div>
<p>To use the OpenCSV <em>CSVWriter&#8217;s</em> interface <em>writeAll</em> method, our input must be first transformed to a Java <em>Iterable. </em>Let&#8217;s write the <em>OpenCSVWriter:</em></p>
<pre><code class="language-scala">class OpenCSVWriter extends CommaSeparatedValuesWriter {
  override def write(
    file: File,
    headers: Seq[String],
    rows: Seq[Seq[String]]
  ): Try[Unit] = Try(
    new CSVWriter(new BufferedWriter(new FileWriter(file)))
  ).flatMap((csvWriter: CSVWriter) =&gt;
    Try {
      csvWriter.writeAll(
        (headers +: rows).map(_.toArray).asJava,
        false
      )
      csvWriter.close()
    }
  )
}</code></pre>
<p>Furthermore, the OpenCSV <em>CSVWriter</em> interface includes methods that accept <em>java.sql.ResultSet</em> arguments, thus making it extremely useful when dealing with data fetched from databases.</p>
<h3 id="bd-2-read-2" data-id="2-read-2">5.2. Read</h3>
<div class="bd-anchor" id="2-read-2"></div>
<p>Similar to the <em>SimpleCSVReader</em>, the <em>OpenCSVReader</em> uses recursion to read a file&#8217;s contents. The recursive method <em>readLinesRecursively</em> returns the CSV rows by using the <em>readNext</em> <em>CSVReader</em>&#8216;s function as an iterator:</p>
<pre><code class="language-scala">class OpenCSVReader extends CommaSeparatedValuesReader {
  override def read(file: File): CSVReadDigest = {
    val reader = new CSVReader(
      new InputStreamReader(new FileInputStream(file))
    )
    @tailrec
    def readLinesRecursively(
      currentReader: CSVReader,
      result: Seq[Seq[String]]
    ): Seq[Seq[String]] = {
      currentReader.readNext() match {
        case null =&gt; result
        case line =&gt; readLinesRecursively(currentReader, result :+ line.toSeq)
      }
    }
    val csvLines = readLinesRecursively(reader, List())
    reader.close()
    CSVReadDigest(
      csvLines.head,
      csvLines.tail
    )
  }
}</code></pre>
<h2 id="bd-apache-commons-csv" data-id="apache-commons-csv">6. Apache Commons CSV</h2>
<div class="bd-anchor" id="apache-commons-csv"></div>
<p>The Apache Commons CSV library enables us to read and write CSV files in various formats. It&#8217;s been evolving since 2014 and is widely used, mainly by Java projects.</p>
<h3 id="bd-1-write-3" data-id="1-write-3">6.1. Write</h3>
<div class="bd-anchor" id="1-write-3"></div>
<p>In contrast with the other implementations we&#8217;ve provided in our examples, the Apache Commons <em>CSVWriter</em>&#8216;s format is configured using a second argument, the <em>CSVFormat</em>. The <em>CSVFormat </em>builder allows us to choose a format and configure it by overriding any property that suits us. In our example, namely the <em>ApacheCommonsCSVWriter</em>, we override the <em>headers</em> property of the default <em>CSVFormat</em>:</p>
<pre><code class="language-scala">class ApacheCommonsCSVWriter extends CommaSeparatedValuesWriter {
  override def write(
    file: File,
    headers: Seq[String],
    rows: Seq[Seq[String]]
  ): Try[Unit] = Try {
    val csvFormat = CSVFormat.DEFAULT
      .builder()
      .setHeader(headers: _*)
      .build()
    val out = new FileWriter(file)
    val printer = new CSVPrinter(out, csvFormat)
    rows.foreach(row =&gt; printer.printRecord(row: _*))
    printer.close()
  }
}</code></pre>
<h3 id="bd-2-read-3" data-id="2-read-3">6.2. Read</h3>
<div class="bd-anchor" id="2-read-3"></div>
<p>The <em>CSVFormat</em> is also used for CSV parsing but in a different way. Let&#8217;s notice that in our implementation, the empty <em>setHeader</em> method call is the Apache Commons CSV way of telling the parser to automatically parse the headers from the first line of the file. The call to the <em>parse</em> function of the <em>CSVFormat</em> yields the <em>CSVParser</em> interface, which provides a variety of methods for reading the lines of the input file. So, let&#8217;s write our example without forgetting that the returned objects need Java-to-Scala transformations:</p>
<pre><code class="language-scala">class ApacheCommonsCSVReader extends CommaSeparatedValuesReader {
  override def read(file: File): CSVReadDigest = {
    val in = new InputStreamReader(new FileInputStream(file))
    val csvParser = CSVFormat.DEFAULT
      .builder()
      .setHeader()
      .build()
      .parse(in)
    val result = CSVReadDigest(
      csvParser.getHeaderNames.asScala.toSeq,
      csvParser.getRecords.asScala.map(r =&gt; r.values().toSeq).toSeq
    )
    csvParser.close()
    result
  }
}</code></pre>
<h2 id="bd-csv-delimiters" data-id="csv-delimiters">7. CSV Delimiters</h2>
<div class="bd-anchor" id="csv-delimiters"></div>
<p><strong>Before we conclude our short tutorial, it&#8217;s crucial to mention the most frequent issue encountered in a CSV dataset is the comma presence in the delimited values leading to parse errors and wrong results.</strong></p>
<p>A good compromise is the choice of a delimiter that is very unlikely to be present in our data such as a special character or a complex sequence of characters. Alternatively, some use quotes but then quotes must be escaped as well.</p>
<p>To conclude, we suggest that we should have a good knowledge of the data contents of our files before choosing a delimiter for our dataset.</p>
<h2 id="bd-conclusion" data-id="conclusion">8. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this short tutorial, we demonstrated how to read and write CSV files with Scala.</p>
<p>Additionally, we included some examples with Scala and Java libraries for good measure. In the end, we emphasized the common delimiter issue that developers usually have to provide a solution for.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/csv-files-read-write">CSV Files in Scala</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/915283508/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/915283508/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-11-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/915283508/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/number-formats">Different Ways to Format Numbers in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/cats-effect-ioapp">IOApp in Cats Effect</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/remove-first-n-digits">Remove the First n Digits of a Number in Scala</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/gatling-load-testing</feedburner:origLink>
		<title>Testing With Gatling Using Scala</title>
		<link>https://feeds.feedblitz.com/~/914402537/0/baeldung/scala~Testing-With-Gatling-Using-Scala</link>
		
		<dc:creator><![CDATA[Stelios Anastasakis]]></dc:creator>
		<pubDate>Fri, 07 Mar 2025 22:49:20 +0000</pubDate>
				<category><![CDATA[Scala Web]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Gatling]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/?p=55837</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" /><p>See how to easily write scenarios to performance test your REST application using Gatling with Scala.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/914402537/0/baeldung/scala~Testing-With-Gatling-Using-Scala">Testing With Gatling Using Scala</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/914402537/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-eventually-block">eventually Block In ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-ignore-conditionally">Ignore Tests Conditionally in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/zio-test-aspects">Test Aspects in ZIO Test</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/introduction-to-gatling">Gatling</a> is a load-testing framework mainly used to test REST APIs. It&#8217;s designed to be easy to use and maintain. This is why the testing scenarios can be written using code and configuration files. It&#8217;s a free tool, but it also offers an enterprise edition.</p>
<p><strong>Gatling is an open-source tool written in Scala, but lately, it also supports Java sources to make it easier for the Java community to use</strong>. The API is almost the same between Java and Scala, so it&#8217;s easy to use if we&#8217;re familiar with any of those languages. <strong>But because Gatling was originally shipped with Scala, we might run into the need to maintain or extend Scala implementations more often</strong>.</p>
<p><strong>In this tutorial, we&#8217;ll explore Gatling using Scala</strong>. We&#8217;ll see how to easily write scenarios to performance test our REST application, no matter the application&#8217;s implementation language. Also, the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/load-test-a-website-with-gatling">basic concepts of Gatling</a> are discussed, so we won&#8217;t go into much detail about them.</p>
<h2 id="bd-create-requests-in-gatling-using-scala" data-id="create-requests-in-gatling-using-scala">2. Create Requests in Gatling Using Scala</h2>
<div class="bd-anchor" id="create-requests-in-gatling-using-scala"></div>
<p>In order to test a REST API, we need to define the REST requests in Gatling. But first, we need to implement the endpoint against which we want to run performance tests.</p>
<h3 id="bd-1-the-rest-service-api" data-id="1-the-rest-service-api">2.1. The REST Service API</h3>
<div class="bd-anchor" id="1-the-rest-service-api"></div>
<p>Testing different REST operations in Gatling is done in a pretty similar way. So, for our examples, we&#8217;re going to use a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/play-rest-api">REST API</a> with a simple GET request, but POST, DELETE, etc. should be similar.</p>
<p>We use Scala Play, but any framework and any language can be used instead. We&#8217;ll be testing the <em>TodoListController</em>, which has an endpoint <em>todo()</em>, returning a simple 200 response. The path to reach this endpoint is <em>/todo</em>.</p>
<h3 id="bd-2-the-galting-request-in-scala" data-id="2-the-galting-request-in-scala">2.2. The Galting Request in Scala</h3>
<div class="bd-anchor" id="2-the-galting-request-in-scala"></div>
<p><strong>On the Gatling side, we need to use <em>HttpRequestBuilder</em> to create the HTTP request to test this endpoint</strong>:</p>
<pre><code class="language-scala">val request: HttpRequestBuilder = http(requestName)
  .get(requestPath)
  .check(status.is(expectedResponseStatus))
  .check(bodyString.optional.saveAs("sBodyString"))</code></pre>
<p>The minimum parameters needed for this GET request in Gatling using Scala are:</p>
<ul>
<li>the request name, to describe the request, like <em>request_todo_endpoint</em></li>
<li>the request path, which should be the path of the specific request, like <em>/todo</em></li>
<li>the checks, where we can run some checks to validate the response or save some response fields in variables for other usages</li>
</ul>
<p>In our solution, we&#8217;ve added the response body in the <em>sBodyString</em> variable to be able to log it in error cases. In this case, we log some information to make debugging easier.</p>
<h3 id="bd-3-enrich-the-request-with-debugging-information-using-session" data-id="3-enrich-the-request-with-debugging-information-using-session">2.3. Enrich the Request With Debugging Information Using <em>Session</em></h3>
<div class="bd-anchor" id="3-enrich-the-request-with-debugging-information-using-session"></div>
<p><strong>In order to be able to better debug issues, we can use the <em>Session</em> object to wrap the <em>HttpRequestBuilder</em>. This way we can check the status of a request and if there are failures, we can add some logs and more</strong>:</p>
<pre><code class="language-scala">object ChainRequestsProvider {
    def simpleRequest(requestName: String, requestPath: String, expectedResponseStatus: Int): ChainBuilder = {
        val request: HttpRequestBuilder = http(requestName)
          .get(requestPath)
          .check(status.is(expectedResponseStatus))
          .check(bodyString.optional.saveAs("sBodyString"))
        exec(session =&gt; session.markAsSucceeded)
          .exec(request).doIf(_.isFailed) {
              exec { session =&gt;
                  println("***Failure on [" + requestPath + "] endpoint:")
                  print("Gatling Session Data: ")
                  println(session.attributes.get("sBodyString"))
                  session
              }
          }
    }
}</code></pre>
<p>At the beginning of each request, we set the session as successful. <strong>This is because, in Gatling using Scala, the session maintains its status even after some different requests. So we reset the session at the beginning of each request</strong>. Then we check if it&#8217;s failed, to validate if the current request check failed. Finally, we log the data we need for debugging, if we get a failure on the request.</p>
<p>Notably, we don&#8217;t execute the request yet. We&#8217;ve only created a <em>ChainBuilder</em> object that we&#8217;ll use later. We&#8217;re still missing some configurations in order to execute the request, like the base URL, the test load, etc. <strong>Moreover, this object is only a part of the broader test simulation</strong>.</p>
<h2 id="bd-create-scenarios-in-gatling-using-scala" data-id="create-scenarios-in-gatling-using-scala">3. Create Scenarios in Gatling Using Scala</h2>
<div class="bd-anchor" id="create-scenarios-in-gatling-using-scala"></div>
<p>As mentioned earlier, the <em>HttpRequestBuilder</em> or <em>ChainBuilder</em> object we create to test a specific endpoint is still missing some configuration. <strong>We need to set a base URL and the test load configuration. To do this in Gatling using Scala, we use the <em>scenario()</em> method</strong>:</p>
<pre><code class="language-scala">object ScenariosProvider {
    private val httpProtocol = http.baseUrl("http://localhost:9000").disableCaching.disableFollowRedirect
    def getScenario(scenarioName: String, request: ChainBuilder, tps: Double, rampUpSeconds: Integer, durationSeconds: Integer): PopulationBuilder = {
        scenario(scenarioName)
          .exec(request)
          .inject(
              rampUsersPerSec(0).to(tps).during(rampUpSeconds),
              constantUsersPerSec(tps).during(durationSeconds-rampUpSeconds-rampUpSeconds),
              rampUsersPerSec(tps).to(0).during(rampUpSeconds)
          )
          .protocols(httpProtocol)
    }
}</code></pre>
<p>The <em>scenario()</em> method expects a minimum configuration of:</p>
<ul>
<li>the scenario name, which is a name to recognize this specific scenario, like <em>request_todo_endpoint</em></li>
<li>the request to execute, that is some request builder, like <em>HttpRequestBuilder</em> or <em>ChainBuilder</em></li>
<li>the inject parameters, which are the injected users numbers per time unit</li>
<li>the protocol is the configuration for the HTTP scheme, like <em>https</em>, the base URL, caching options, etc</li>
</ul>
<p>Regarding the injected users, Gatling in Scala provides multiple ways to set the load. <strong>The load, in transactions per second (tps) can be set in a constant manner or by specifying ramp periods to increase or decrease the load steadily. We also have to set the period of the tps and finally combine different injectors</strong>.</p>
<p>In this scenario, we set a ramp-up period to get the users from 0 to some value in a specific period of time, then keep the load steady for some duration, and in the final configured time ramp down to 0.</p>
<p><strong>The returned object is the <em>PopulationBuilder</em>. We&#8217;ll use it in the next step, when we create the simulation, along with other <em>PopulationBuilder</em> objects for other endpoints or configurations</strong>.</p>
<h2 id="bd-create-and-execute-simulations-in-gatling-using-scala" data-id="create-and-execute-simulations-in-gatling-using-scala">4. Create and Execute Simulations in Gatling Using Scala</h2>
<div class="bd-anchor" id="create-and-execute-simulations-in-gatling-using-scala"></div>
<p><strong>Bringing everything together, for load tests in Gatling using Scala, we need to define a <em>Simulation</em> with all of the different scenarios we want to test in parallel</strong>. The simulation can include testing different endpoints, testing with different loads, testing failing scenarios, and more:</p>
<pre><code class="language-scala">class PeakLoadSimulation extends Simulation {
    setUp(
        getScenario("getExistingEndpoint", simpleRequest("request_todo_endpoint", "/todo", 200), 50, 10, 60),
        getScenario("nonExistingEndpoint", simpleRequest("request_wrong_endpoint", "/not-todo", 200), 5, 10, 60)
    )
}</code></pre>
<p>The simulation we create, <em>PeakLoadSimulation</em>, needs to extend the <em>Simulation</em> class. Then, in the <em>setUp()</em> method, we define the scenarios as <em>PopulationBuilder</em> objects. We can add as many scenarios as we want. <strong>All of the different scenarios are to be executed in parallel</strong>.</p>
<p>When executing the simulation against the REST service API we defined earlier, we should get a successful execution:</p>
<a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/wp-content/uploads/sites/3/2025/03/simulation-no-assertions.png"><img loading="lazy" decoding="async" class="alignnone wp-image-226975 size-full" src="https://www.baeldung.com/wp-content/uploads/sites/3/2025/03/simulation-no-assertions.png" alt="simulation outcome" width="1014" height="577" /></a>
<p>Here, we can see the generated report that contains the request count, response times, and the XXth percentile of response times. The request count validates that the requests we made to the existing endpoint are ten times more than the ones we did against the non-existing one.</p>
<h2 id="bd-add-assertions-in-gatling-using-scala" data-id="add-assertions-in-gatling-using-scala">5. Add Assertions in Gatling Using Scala</h2>
<div class="bd-anchor" id="add-assertions-in-gatling-using-scala"></div>
<p>When running the simulations, we can monitor the outcome in different ways. We could be testing if the server will handle the load off or if it will start throwing <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/java-jvm-out-of-memory-during-runtime"><em>OutOfMemory</em> errors</a>. We could also be getting info out of dashboards from the metrics the service exposes.</p>
<p><strong>Gatling using Scala provides ways to validate the execution outcomes from the testing framework side, using assertions against the scenarios</strong>. Those assertions can be per scenario and test different metrics, like the successful response rate, the response time, etc:</p>
<pre><code class="language-scala">class PeakLoadSimulation extends Simulation {
    setUp(
        getScenario("getExistingEndpoint", simpleRequest("request_todo_endpoint", "/todo", 200), 50, 10, 60),
        getScenario("nonExistingEndpoint", simpleRequest("request_wrong_endpoint", "/not-todo", 200), 5, 10, 60)
    ).assertions(
        details("request_todo_endpoint").successfulRequests.percent.gt(99.99),
        details("request_todo_endpoint").responseTime.percentile4.lt(20),
        details("request_todo_endpoint").requestsPerSec.gt(40),
        details("request_wrong_endpoint").successfulRequests.percent.lt(1),
        details("request_wrong_endpoint").responseTime.percentile4.lt(20)
    )
}</code></pre>
<p>We enrich our simulation by adding four assertions for the two scenarios. Each scenario checks at the end of the execution that the successful rate is the expected one and the response time of 99% of the responses (<em>percentile4</em>) is less than 20 milliseconds, which makes sense when testing servers on localhost. Last, we add the <em>requestsPerSec</em>, to verify that the load we want per scenario is the expected one.</p>
<p>The <em>successfulRequests</em> field should accept as successful responses the ones that pass the status check we set in the <em>simpleRequest</em> method. For example, if we change the missing endpoint scenario to expect 404, <em>simpleRequest(&#8220;request_wrong_endpoint&#8221;, &#8220;/not-todo&#8221;, 404)</em>, then the <em>successfulRequests</em> percent should also be changed to validate that is greater than 99.</p>
<p>Notably, the value in the <em>details()</em> method matches the name we give to the <em>HttpRequestBuilder</em> object as <em>requestName</em>.</p>
<p>When we run the updated simulation, with the assertions, we should again get a successful execution:</p>
<a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/wp-content/uploads/sites/3/2025/03/simulation-with-assertions.png"><img loading="lazy" decoding="async" class="wp-image-226976 size-full alignnone" src="https://www.baeldung.com/wp-content/uploads/sites/3/2025/03/simulation-with-assertions.png" alt="gatling simulation with assertions outcome" width="845" height="704" /></a>
<p>This time, we see a similar report, but the outcome of the assertions is also included. First goes the <em>requestName</em>, then goes the description of the assertion in plain text, and last comes the outcome, <em>true</em> or <em>false</em>, followed by some extra info.</p>
<h2 id="bd-conclusion" data-id="conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we went through Gatling using Scala, by discussing all the components needed to create a load test scenario against a REST endpoint. We looked at the basic configuration needed to create simple tests. To make the concepts clear, we demonstrated each concept with a Simulation that tests a couple of endpoints.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/gatling-load-testing">Testing With Gatling Using Scala</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/914402537/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/914402537/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/914402537/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-eventually-block">eventually Block In ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-ignore-conditionally">Ignore Tests Conditionally in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/zio-test-aspects">Test Aspects in ZIO Test</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/cats-effect-ioapp</feedburner:origLink>
		<title>IOApp in Cats Effect</title>
		<link>https://feeds.feedblitz.com/~/912379685/0/baeldung/scala~IOApp-in-Cats-Effect</link>
		
		<dc:creator><![CDATA[Stefanos Georgakis]]></dc:creator>
		<pubDate>Thu, 06 Feb 2025 05:51:08 +0000</pubDate>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Libraries]]></category>
		<category><![CDATA[Cats]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/cats-effect-ioapp</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn how to work with IOApp in Cats Effect.</p>
<p>A tutorial for working with IOApp in Scala Cats Effect, covering concurrency, command-line arguments, custom runtimes, resources, and interruptions.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/912379685/0/baeldung/scala~IOApp-in-Cats-Effect">IOApp in Cats Effect</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912379685/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/eithert-handle-errors">Effective Error Handling With EitherT in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/csv-files-read-write">CSV Files in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/chimney-data-transformation-library">Introduction to Chimney</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/cats-effects-intro">Cats Effect</a> is a popular library in Scala ecosystem and functional programming for managing side effects in functional programming. It provides an easy-to-use API for building asynchronous, concurrent applications. In this tutorial, we&#8217;ll explore the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://typelevel.org/cats-effect/api/3.x/cats/effect/IOApp.html"><em>IOApp</em></a>, a trait that serves as the entry point for simplifying the way we can write Cats Effect applications.</p>
<h2 id="bd-creating-a-simple-application" data-id="creating-a-simple-application">2. Creating a Simple Application</h2>
<div class="bd-anchor" id="creating-a-simple-application"></div>
<p>To start implementing applications with the Cats Effect library, we first need to add the following <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://mvnrepository.com/artifact/org.typelevel/cats-effect">dependency</a> in our <em>build.sbt</em> file:</p>
<pre><code class="language-scala">libraryDependencies += "org.typelevel" %% "cats-effect" % "3.5.7"</code></pre>
<p>Now we are ready to implement our application. We&#8217;ll create an application that only prints a line in our console. For this, we&#8217;ll create an <em>object</em> as our entry point and extend the <em>IOApp.Simple</em> trait. Next, we&#8217;ll define the abstract method <em>run</em> of the trait:</p>
<pre><code class="language-scala">object SimpleIOApp extends IOApp.Simple {
  val run: IO[Unit] = IO.println("Running with simple app")
}</code></pre>
<p>The <em>run</em> method takes no arguments and returns an effect of type <em>Unit</em>. <strong>It is intended for very simple applications and will always exit with a successful exit code</strong>. The Cats Effect runtime provides all the necessary configuration, such as an execution context, and also manages threads and the whole lifecycle of the application. We can use <em>val </em>instead of <em>def</em> for our run method because the <em>IO</em> effect is lazily evaluated during runtime invocation.</p>
<h2 id="bd-creating-an-application-with-arguments" data-id="creating-an-application-with-arguments">3. Creating an Application With Arguments</h2>
<div class="bd-anchor" id="creating-an-application-with-arguments"></div>
<p>Most applications accept arguments, use custom exit codes to notify the users for not expected behavior, and may use custom resources to run. The default <em>IOApp</em> trait helps us implement applications with all of these features.</p>
<p>We&#8217;ll now create an application that will accept command-line arguments. We only need to extend the <em>IOApp</em> trait and then define the <em>run</em> method. The arguments are passed as a pure <em>List</em> instead of an Array. The return type is <em>IO[ExitCode]</em> meaning that <strong>we can define our own exit codes to indicate success or failure</strong>:</p>
<pre><code class="language-scala">object ArgumentIOApp extends IOApp {
  def run(args: List[String]): IO[ExitCode] =
    IO.println(s"Running with args: ${args.mkString(",")}").as(ExitCode.Success)
}</code></pre>
<p>In this example, we accept any number of arguments and print them in the console, returning a success code. We can further enhance our application and handle the case when no arguments have been provided. We&#8217;ll then return a custom error code:</p>
<pre><code class="language-scala">object ArgumentIOApp extends IOApp {
  def run(args: List[String]): IO[ExitCode] =
    if (args.nonEmpty) {
      IO.println(s"Running with args: ${args.mkString(",")}")
        .as(ExitCode.Success)
    } else {
      IO.println("No args provided. Aborting").as(ExitCode(2))
    }
}</code></pre>
<p>Now, we handle the case where we didn&#8217;t provide any arguments and abort the program with <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/linux/status-codes#exit-codes">exit code</a> 2, which indicates that a major error occurred. The library provides a value for an error exit code <em>ExitCode.Error</em>, which maps to exit code 1, but we can use any other valid number we want.</p>
<h2 id="bd-defining-custom-runtime-configuration" data-id="defining-custom-runtime-configuration">4. Defining Custom Runtime Configuration</h2>
<div class="bd-anchor" id="defining-custom-runtime-configuration"></div>
<p>So far, we&#8217;ve created applications that utilize the runtime configuration that the <em>IOApp</em> provides by default. But there are also cases in which we want to modify it and use a custom one. <strong>By default, the <em>IOApp</em> uses the global execution context</strong>, but we may stumble upon a case where another implementation suits our needs better. We can achieve that by defining our custom execution context and using it to evaluate computations. Let&#8217;s create another application that will use a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/java-work-stealing">work-stealing thread pool</a>:</p>
<pre><code class="language-scala">object ContextIOApp extends IOApp {
  private val customExecutionContext: ExecutionContext =
    ExecutionContext.fromExecutor(Executors.newWorkStealingPool(1))
  override def run(args: List[String]): IO[ExitCode] = {
    val computation = IO {
      println(s"Running on thread: ${Thread.currentThread().getName}")
    }
    computation.evalOn(customExecutionContext).as(ExitCode.Success)
  }
}</code></pre>
<p>The only thing we changed is that we&#8217;ve defined our new execution context and that we&#8217;ve used the <em>evalOn</em> method, upon the <em>IO</em> computation, so it is evaluated with our custom execution context. Pretty straightforward.</p>
<h2 id="bd-using-resources" data-id="using-resources">5. Using Resources</h2>
<div class="bd-anchor" id="using-resources"></div>
<p>Since everything is already in place by the trait, we can also use resources in our application. We&#8217;ll demonstrate that by creating again an execution context, but handling it as a resource this time:</p>
<pre><code class="language-scala">object ResourceIOApp extends IOApp {
  val customExecutionContext: Resource[IO, ExecutionContext] =
    Resource.make(
      IO(ExecutionContext.fromExecutorService(Executors.newWorkStealingPool(1)))
    ) { ec =&gt;
      IO.println("Shutting down execution contest").as(ec.shutdown())
    }
  def run(args: List[String]): IO[ExitCode] = customExecutionContext
    .use { ec =&gt;
      IO.println(s"Running on thread: ${Thread.currentThread().getName}")
    }
    .as(ExitCode.Success)
}</code></pre>
<p>We&#8217;re using the <em>Resource</em> monad to wrap our custom execution context and safely shut it down afterward. Then, with the <em>use</em> method, we make our application run and use it.</p>
<h2 id="bd-interrupting-applications" data-id="interrupting-applications">6. Interrupting Applications</h2>
<div class="bd-anchor" id="interrupting-applications"></div>
<p>The Cats Effect library uses <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/cats-effect-fibers-concurrent-programming">fibers</a> for concurrency. Our <em>IOApp</em> can interact with the main fiber and cancel it in case it receives an interrupt signal. This means that <strong>it&#8217;ll also propagate to all the other fibers and invoke any <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/cats-effect-cancellation">finalizers</a> we&#8217;ve defined</strong>, so our application can gracefully shut down. This mechanism, however, has one major side effect. If a finalizer runs forever, the main fiber can&#8217;t shut down and it&#8217;ll also run forever, and we need to issue a <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/linux/sigint-and-other-termination-signals#sigkill">SIGKILL</a> signal for cleanup.</p>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we’ve explored how we can define simple and more complex applications easily with the <em>IOApp</em> trait of the Cats Effect library. We&#8217;ve demonstrated how to use custom error codes, our custom execution context and resources, as well as how the application can be interrupted.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/cats-effect-ioapp">IOApp in Cats Effect</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/912379685/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912379685/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912379685/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/eithert-handle-errors">Effective Error Handling With EitherT in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/csv-files-read-write">CSV Files in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/chimney-data-transformation-library">Introduction to Chimney</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/context-functions-scala-3</feedburner:origLink>
		<title>Context Functions in Scala 3</title>
		<link>https://feeds.feedblitz.com/~/912048281/0/baeldung/scala~Context-Functions-in-Scala</link>
		
		<dc:creator><![CDATA[Matteo Di Pirro]]></dc:creator>
		<pubDate>Fri, 31 Jan 2025 21:51:08 +0000</pubDate>
				<category><![CDATA[Scala Core]]></category>
		<category><![CDATA[Functions]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/context-functions-scala-3</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn how to use Context Functions in Scala 3.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/912048281/0/baeldung/scala~Context-Functions-in-Scala">Context Functions in Scala 3</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912048281/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-11-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scala-3-tasty">TASTy Files in Scala 3</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p><strong>In Scala 3, context functions are functions with only implicit parameters or, more precisely, context parameters.</strong> This means the compiler will input the correct arguments (taking them from the &#8220;context&#8221;, aka the scope) rather than explicitly writing them in the code.</p>
<p>In this tutorial, we&#8217;ll examine context functions and how to use them.</p>
<h2 id="bd-the-syntax" data-id="the-syntax">2. The Syntax</h2>
<div class="bd-anchor" id="the-syntax"></div>
<p><strong>In Scala 3, we write the type of a context function using <em>?=&gt;</em>.</strong> This is different from &#8220;ordinary&#8221; functions, where we use the &#8220;arrow&#8221; sign: <em>=&gt;</em>.</p>
<p>As we saw above, context functions do not have any explicit parameters. Therefore, to use one of the arguments in the implementation, we&#8217;ll have to use <em>summon[T]</em>, which is similar to <em>implicitly[T]</em> in Scala 2. <strong>In brief, <em>summon[T]</em> looks for an implicit value of type <em>T</em> in the scope.</strong> In Scala 3, we can provide such values using <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/contextual-abstractions"><em>given</em></a>.</p>
<p>Let&#8217;s see an example of a context function to increment a number:</p>
<pre><code class="language-scala">val increment: Int ?=&gt; Int = summon[Int] + 1</code></pre>
<p>We define a context function simply by specifying its type and body, just as we&#8217;d do with a &#8220;regular&#8221; function. The <em>Int ?=&gt; Int</em> notation is a shortcut for <em>ContextFunction1[Int, Int]</em>, as much as <em>Int =&gt; Int</em> is syntactic sugar for <em>Function1[Int, Int]</em>.</p>
<p><strong>For context functions, however, the type is mandatory.</strong> If we omitted <em>Int ?=&gt; Int</em>, the compilation would fail:</p>
<pre><code class="language-plaintext">No given instance of type Int was found for parameter x of method summon in object Predef
val increment = summon[Int] + 1</code></pre>
<p><strong>To invoke our function, we have to provide an implicit parameter either explicitly or via the implicit scope</strong>:</p>
<pre><code class="language-scala">// Implicit parameter provided via the scope
given Int = 1
println(s"Result scope: $increment")
// Implicit parameter provided explicitly to the call
println(s"Result explicit: ${increment(using 5)}")</code></pre>
<p>In the first case, we used <em>given</em> to put an <em>Int</em> into the implicit scope. Here, we can invoke <em>increment</em> simply by calling it. In the second case, we explicitly provided the parameter with <em>using</em> at the call site. If we run the example above, we&#8217;ll see two lines in the output:</p>
<pre><code class="language-plaintext">Result scope: 2
Result explicit: 6</code></pre>
<h3 id="bd-1-multiple-context-parameters" data-id="1-multiple-context-parameters">2.1. Multiple Context Parameters</h3>
<div class="bd-anchor" id="1-multiple-context-parameters"></div>
<p><strong>Context functions can have more than a single parameter.</strong> Let&#8217;s see an example:</p>
<pre><code class="language-scala">val repeatString: String ?=&gt; Int ?=&gt; String = summon[String].repeat(summon[Int])
println(s"Result repeatString: ${repeatString(using "Baeldung")(using 3)}")</code></pre>
<p>In the example above, we defined a function with two context parameters, a <em>String</em> and an <em>Int</em>, and invoked it just as before:</p>
<pre><code class="language-plaintext">Result repeatString: BaeldungBaeldungBaeldung</code></pre>
<h2 id="bd-an-example-modeling-kotlin-scope-functions" data-id="an-example-modeling-kotlin-scope-functions">3. An Example: Modeling Kotlin Scope Functions</h2>
<div class="bd-anchor" id="an-example-modeling-kotlin-scope-functions"></div>
<p>Let&#8217;s now see a more complex example of a context function. We&#8217;ll use them to model one of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/kotlin/scope-functions">Kotlin&#8217;s scope functions</a>, <em>also</em>.</p>
<p><strong>In Kotlin, <em>also</em> is a function taking the context object as a parameter, with name <em>it</em>, and returning the context object itself.</strong> In brief, whenever we see <em>also</em> in the code we can think of a function that uses a given object and returns it, without modifying it.</p>
<p>Let&#8217;s take a look at Scala&#8217;s implementation:</p>
<pre><code class="language-scala">opaque type WrappedAlso[T] = T
def it[T](using a: WrappedAlso[T]): T = a
extension [T](x: T)
  def also(f: WrappedAlso[T] ?=&gt; Unit): T =
    f(using x)
    x</code></pre>
<p><strong>First, we modeled an <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/opaque-type-alias">o<em>paque type</em></a>, named <em>WrappedAlso</em>, which essentially wraps a value of type T. </strong>This is always advised with context functions to prevent unwanted givens from being picked from the scope.</p>
<p>Secondly, we implemented a constructor to avoid explicitly <em>summon</em>ing a parameter of type T. To comply with Kotlin&#8217;s naming convention, we call this method <em>it</em>.</p>
<p>Lastly, we defined an <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/extension-methods">extension method</a>, called <em>also</em>, doing all the magic. <strong>It inputs a context function type <em>WrappedAlso[T] ?=&gt; Unit</em>, which means we&#8217;ll have to provide a context function using a value of type <em>T</em>.</strong> <em>also</em> invokes the function <em>f</em> with <em>x</em> as an explicit parameter, discards its result, and returns the original value <em>x</em>.</p>
<p>Since <em>WrappedAlso</em> is an opaque type alias, its values won&#8217;t need boxing. Furthermore, since <em>also</em> is added as an extension method, its argument does not need boxing either.</p>
<p>Let&#8217;s see how we can use our new function:</p>
<pre><code class="language-scala">val numbers = List(1, 2, 3, 4, 5)
numbers
  .also(println(s"The list before adding 6: $it"))
  .appended(6)
  .also(println(s"The list after adding 6: $it"))</code></pre>
<p>In the example above, we defined a list of numbers and made two calls to <em>also,</em> before and after adding an element. In the function body, we can refer to the context parameter with <em>it</em>, as much as we&#8217;d do in Kotlin.</p>
<p><strong>If we hadn&#8217;t defined the <em>it</em> constructor, we would have had to refer to it with an explicit <em>summon[List[Int]]</em>, which is far less readable.</strong></p>
<p>Running the example produces the expected output:</p>
<pre><code class="language-plaintext">The list before adding 6: List(1, 2, 3, 4, 5)
The list after adding 6: List(1, 2, 3, 4, 5, 6)</code></pre>
<p>Lastly, any changes to the list in the body of the <em>also</em> function will not get propagated:</p>
<pre><code class="language-scala">numbers
    .also(it appended 7)
    .also(println(s"The list after adding 7: $it"))</code></pre>
<p>The example above produces <em>The list after adding 7: List(1, 2, 3, 4, 5)</em> as an output.</p>
<h2 id="bd-conclusion" data-id="conclusion">4. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we learned about context functions are in Scala 3. We started with an overview of the syntax, and then we deepened our knowledge with functions with more than one parameter. Finally, we looked at a practical example, showing how simple it is to model idiomatic Kotlin scope functions.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/context-functions-scala-3">Context Functions in Scala 3</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/912048281/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912048281/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-11-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912048281/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scala-3-tasty">TASTy Files in Scala 3</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-11-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/val-and-def-fields-in-traits</feedburner:origLink>
		<title>Usage of val and def Fields in Traits</title>
		<link>https://feeds.feedblitz.com/~/912047660/0/baeldung/scala~Usage-of-val-and-def-Fields-in-Traits</link>
		
		<dc:creator><![CDATA[Callum Gibbons]]></dc:creator>
		<pubDate>Fri, 31 Jan 2025 21:45:48 +0000</pubDate>
				<category><![CDATA[Scala Type System]]></category>
		<category><![CDATA[Traits]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/val-and-def-fields-in-traits</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn the best practices on the usage of val and def fields in Traits in Scala to separate implementation details from the abstractions set within trait definitions.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/912047660/0/baeldung/scala~Usage-of-val-and-def-Fields-in-Traits">Usage of val and def Fields in Traits</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912047660/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-10-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/stackable-trait-pattern">Stackable Trait Pattern in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/root-import-clause">Meaning of _root_ In Scala Import Clause</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p>In this tutorial, we&#8217;ll compare the usage of <em>val</em>s and <em>def</em>s within <em>trait</em> definitions. Using a <em>val</em> rather than <em>def</em>s within <em>trait</em>s can appear like a small difference on the surface, but can become problematic when extending the <em>trait</em>. We&#8217;ll cover the concept of a <em>trait</em> and explore some concrete examples of what can go wrong when extending a <em>trait</em> containing a <em>val</em>.</p>
<h2 id="bd-abstraction-in-traits" data-id="abstraction-in-traits">2. Abstraction in Traits</h2>
<div class="bd-anchor" id="abstraction-in-traits"></div>
<p>A <em>trait</em>, similar to an <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/java-interfaces"><em>interface</em> in Java</a>, should be used to define an abstract blueprint, which other abstract classes or a concrete class definition can extend. As such, we don&#8217;t want a <em>trait</em> to contain any implementation details that the extending class should provide. This includes providing functionality that restricts the extending class.</p>
<p>For example, if we provided a <em>SqlConnection</em> field for a <em>trait</em> that provides access to a database. When we come to create an implementation for an in-memory or NoSql database, we can&#8217;t because we&#8217;re locked into providing a <em>SqlConnection</em>. This implementation detail should only be provided within the extending class.</p>
<p>The same applies to the variable type of a field. By defining a field as a <em>val</em>, we enforce that the the field is instantiated at the point the class is created. <strong>This could be inappropriate for particular implementations of the <em>trait</em></strong>. To ensure we&#8217;re not restricting the implementation of an extending class, we should use the most open variable type of <em>def</em>.</p>
<h2 id="bd-restricting-fields" data-id="restricting-fields">3. Restricting Fields</h2>
<div class="bd-anchor" id="restricting-fields"></div>
<p>Now we understand the concept of a <em>trait</em> and why we should favor <em>def</em>s fields over <em>val</em>s from a conceptual point of view. Let&#8217;s look at some concrete examples to see the problems in practice:</p>
<pre><code class="language-scala">trait CurrentTimePrinter {
  val currentTime: LocalDateTime
  def printCurrentTime(): Unit
}
object TimePrinterImpl extends CurrentTimePrinter {
  override val currentTime: LocalDateTime = LocalDateTime.now()
  override def printCurrentTime(): Unit = println(currentTime)
}</code></pre>
<p>In this example, we define a <em>trait</em> called <em>CurrentTimePrinter</em> with a field called <em>currentTime</em>. Then, a function called <em>printCurrentTime()</em> needs to be implemented in the extending class. Below the <em>trait</em>, we create an <em>object</em> that implements <em>CurrentTimePrinter</em> and overrides the fields defined in the trait. If we run this code and call <em>printCurrentTime</em>, the same <em>LocalDateTime</em> value will be printed each time as <em>currentTime</em> is a val.</p>
<p>Let&#8217;s try and change it to a <em>def</em>, so <em>LocalDateTime.now()</em> is called each time to get an up-to-date value:</p>
<pre><code class="language-scala">object TimePrinterImpl extends CurrentTimePrinter {
  override def currentTime: LocalDateTime = LocalDateTime.now()
  override def printCurrentTime(): Unit = println(currentTime)
}</code></pre>
<p>If we try to compile this code now, we&#8217;re given an error:</p>
<pre><code class="language-scala">overriding value currentTime in trait CurrentTimePrinter of type java.time.LocalDateTime;
method currentTime needs to be a stable, immutable value</code></pre>
<p>This occurs because our <em>trait</em> defines <em>currentTime</em> as an immutable value by setting it as a val. Therefore, we have to provide an immutable value when writing its implementation. This forces the implementing class to use a val for <em>currentTime</em>. Which, in our use case, isn&#8217;t appropriate. We can fix this by setting <em>currentTime</em> to a def in <em>CurrentTimePrinter</em>:</p>
<pre><code class="language-scala">trait CurrentTimePrinterWithDef {
  def currentTime: LocalDateTime
  def printCurrentTime(): Unit
}
object TimePrinterWithDefImpl extends CurrentTimePrinterWithDef {
  override def currentTime: LocalDateTime = LocalDateTime.now()
  override def printCurrentTime(): Unit = println(currentTime)
}</code></pre>
<p>This time, we can call <em>printCurrentTime()</em> and it will print a newly calculated <em>LocalDateTime</em> for each call.</p>
<p>By setting <em>currentTime</em> as a <em>def</em>, we&#8217;ve allowed the implementing class the flexibility to choose the field type. We could override it as a def, val lazy val, or even a var if we wanted to. Using a <em>def</em> in the <em>trait</em> makes the field as open as possible for the overriding class to choose what the implementation should do.</p>
<h2 id="bd-initialization-order" data-id="initialization-order">4. Initialization Order</h2>
<div class="bd-anchor" id="initialization-order"></div>
<p>The next issue we can encounter when using <em>val</em>s in <em>trait</em>s comes when using <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/inheritance#multiple-inheritance">multiple inheritance</a>. Let&#8217;s create some <em>trait</em>s and <em>class</em>es to explore this issue:</p>
<pre><code class="language-scala">trait TraitA {
  val multiplier: Int
  val result: Int = multiplier * 7
}
trait TraitB {
  val multiplier: Int = 10
}
object AB extends TraitA with TraitB
object BA extends TraitB with TraitA</code></pre>
<p>Here, we&#8217;ve created two<em> trait</em>s. <em>TraitA</em> has an abstract field of <em>multiplier</em> and then a concrete field of <em>result</em>, which multiplies the <em>multiplier</em> by 7. Next, we have <em>TraitB,</em> which has a concrete member of <em>multiplier</em>, initialized to 10. Finally, we have two <em>object</em> definitions, <em>AB,</em> which extends <em>TraitA with</em> <em>TraitB</em>. Then, <em>BA</em> which does the opposite &#8211; <em>TraitB with TraitA</em>.</p>
<p>Let&#8217;s call the <em>result</em> on both these <em>object</em>s and see what happens:</p>
<pre><code class="language-scala">AB.result // AB.result = 0
BA.result // BA.result = 70</code></pre>
<p>As we can see, these two results are very different and unexpected for just reversing the order in which we extend the <em>trait</em>s. This happens because <em>trait</em>s are initialized in the order they&#8217;re listed. So, in <em>AB</em>, when the result is calculated in <em>TraitA</em>, the multiplier hasn&#8217;t been set to 10, as <em>TraitB</em> hasn&#8217;t been initialized yet. So, the <em>multiplier</em> defaults to zero, and the <em>result</em> is zero. Whereas, in <em>BA,</em> <em>TraitB</em> is initialized first, so when <em>result</em> is calculated in <em>TraitA</em>, <em>multiplier</em> has been set to 10, therefore we get 70.</p>
<p>As we can see, this effect could produce unexpected results in our codebases. Fortunately, we can mitigate against this by setting <em>result</em> as a def in <em>TraitA</em>:</p>
<pre><code class="language-scala">trait TraitA {
  val multiplier: Int
  def result: Int = multiplier * 7
}
trait TraitB {
  val multiplier: Int = 10
}
object AB extends TraitA with TraitB
object BA extends TraitB with TraitA</code></pre>
<p>Now, let&#8217;s call <em>result</em> on both <em>object</em>s again:</p>
<pre><code class="language-scala">AB.result // AB.result = 70
BA.result // BA.result = 70</code></pre>
<p>This time, both <em>result</em>s returned 70. This is because <em>result</em> is now a <em>def</em>, which is calculated each time we call it. Meaning that the object and all the <em>trait</em>s it extends have been initialized at the point we call the <em>result</em>.</p>
<h2 id="bd-conclusion" data-id="conclusion">5. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we&#8217;ve discussed the good practice of separating implementation details from the abstractions we set within <em>trait</em> definitions. Next, we explored the issues that can occur when we extend a <em>trait</em> containing a <em>val</em> using the example of printing the <em>currentTime</em>. Finally, we saw the unexpected results that can occur in our codebase caused by the initialization order in multiple inheritance using <em>trait</em>s with <em>val</em>s.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/val-and-def-fields-in-traits">Usage of val and def Fields in Traits</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/912047660/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/912047660/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-10-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/912047660/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/stackable-trait-pattern">Stackable Trait Pattern in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/root-import-clause">Meaning of _root_ In Scala Import Clause</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-10-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/map-vs-flatmap</feedburner:origLink>
		<title>Difference Between map() and flatMap() in Scala</title>
		<link>https://feeds.feedblitz.com/~/910696859/0/baeldung/scala~Difference-Between-map-and-flatMap-in-Scala</link>
		
		<dc:creator><![CDATA[Yadu Krishnan]]></dc:creator>
		<pubDate>Thu, 09 Jan 2025 12:17:58 +0000</pubDate>
				<category><![CDATA[Scala Collections]]></category>
		<category><![CDATA[List]]></category>
		<category><![CDATA[Map]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/map-vs-flatmap</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-1024x536.png" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn the differences between map() and flatMap() in Scala</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/910696859/0/baeldung/scala~Difference-Between-map-and-flatMap-in-Scala">Difference Between map() and flatMap() in Scala</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910696859/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2021%2f08%2fScala-Featured-Image-1024x536.png"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/convert-scala-list-to-tuple">Convert a Scala List to a Tuple</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/collection-delete-item">Remove an Element From a Scala Collection</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/list-compute-mean-value">Calculate the Average of a List in Scala</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-1024x536.png" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-1024x536.png 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-300x157.png 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-768x402.png 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-100x52.png 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image.png 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>As a functional programming language, Scala provides powerful abstractions for working with collections, <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/monads">monads</a>, and other structures. Among these abstractions, <em>map()</em> and <em>flatMap()</em> are two of the most frequently used <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/higher-order-functions">higher-order functions</a>. While they might seem similar at first glance, they serve different purposes and behave differently depending on the context.</p>
<p>In this tutorial, let&#8217;s explore the difference between those functions.</p>
<h2 id="bd-map" data-id="map">2. <em>map()</em></h2>
<div class="bd-anchor" id="map"></div>
<p><strong>The <em>map()</em> function transforms each collection element or monadic structures like <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/option-type"><em>Option</em></a>, <em>Future</em>, etc. by applying a given function</strong>. The result is a new structure containing the transformed elements.</p>
<p>Let&#8217;s look at the syntax of the <em>map()</em> function:</p>
<pre><code class="language-scala">def map[B](f: A =&gt; B): F[B]</code></pre>
<p>As we can see, the <em>map()</em> function takes a function that transforms a value of type <em>A</em> into a value of type <em>B</em>.</p>
<p>Let&#8217;s explore a few example usages from Scala&#8217;s standard library types, such as <em>List</em> and <em>Option</em>:</p>
<pre><code class="language-scala">// on List
val numbers = List(1,2,3,4,5)
val doubled = numbers.map(_ * 2) // List(2, 4, 6, 8, 10)
// on Option
val intOpt = Option(2)
val doubledOpt = intOpt.map(_ * 2) // Option(4)</code></pre>
<p>Similarly, many classes from both the standard library and third-party libraries implement the <em>map()</em> function, as it&#8217;s one of the most commonly used operations.</p>
<p>Typically, <em>map()</em> is used when working with the successful side of a monadic structure, such as the <em>Some</em> case in <em>Option</em> or the <em>Right</em> case in <em>Either</em>. This allows transformations without altering the underlying structure. Failure cases such as <em>None </em>and <em>Left</em> are not transformed. However, this is more of a convention than a strict rule on the monadic implementation</p>
<h2 id="bd-flatmap" data-id="flatmap">3. <em>flatMap()</em></h2>
<div class="bd-anchor" id="flatmap"></div>
<p>The <em>flatMap()</em> function can also transform the elements of a collection or a monadic context. However, <strong>it&#8217;s applicable when the transformation function returns a structure of the same type</strong>. It flattens the resulting nested structure into a single structure.</p>
<p>Let&#8217;s look at the syntax:</p>
<pre><code class="language-scala">def flatMap[B](f: A =&gt; F[B]): F[B]</code></pre>
<p>Here, we can see that the transformation function <em>f</em> in <em>flatMap()</em> returns <em>F[B]</em>, whereas in <em>map()</em>, it returns B.</p>
<p>Let&#8217;s look at an example by using <em>List</em>:</p>
<pre><code class="language-scala">val sentences = List("Hello world", "Scala is awesome", "Functional programming is fun")
val words = sentences.flatMap(sentence =&gt; sentence.split(" "))
assert(words == List("Hello", "world", "Scala", "is", "awesome", "Functional", "programming", "is", "fun"))
</code></pre>
<p>In this example, the split method returns an array of words, and <em>flatMap()</em> is used to flatten the resulting lists of words into a single list. If we had used <em>map()</em> instead of <em>flatMap()</em>, the result would have been a nested list, where each element is a list of words for each sentence. <strong>To flatten this structure, we would then need to use <em>flatten()</em>, which can be avoided by directly using <em>flatMap()</em>, as it handles both the transformation and flattening in a single step</strong>.</p>
<p>Like <em>map()</em>, <em>flatMap()</em> also operates on the successful side of a monad.</p>
<p>When multiple nested <em>flatMap()</em> calls are involved, the code can become too difficult to read. In such cases, <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/for-comprehension"><em>for-comprehension</em></a> provides a more readable alternative. <strong>Internally, <em>for-comprehensions</em> are syntactic sugar for chaining <em>flatMap()</em> operations</strong>.</p>
<p>Let&#8217;s look at another example using <em>Option</em> chaining:</p>
<pre><code class="language-scala">val supportedOs = Option("Linux")
val input = Option("Linux")
supportedOs.flatMap { os =&gt;
  input.flatMap { in =&gt;
    if (in == os) then Some("Succes") else None
  }
}</code></pre>
<p>We can rewrite this to a simpler version using <em>for-comprehension</em>:</p>
<pre><code class="language-scala">val supportedOs = Option("Linux")
val input = Option("Linux")
for {
  os &lt;- supportedOs
  in &lt;- input
  if in == os
} yield "Success"
</code></pre>
<p>This improves readability when dealing with multiple <em>flatMap()</em> chains.</p>
<h2 id="bd-summary" data-id="summary">4. Summary</h2>
<div class="bd-anchor" id="summary"></div>
<p>Let&#8217;s summarize what we discussed about map and flatMap</p>
<table class="table-styled" style="width: 100%;height: 144px">
<thead>
<tr style="height: 24px">
<th style="height: 24px">Feature</th>
<th style="height: 24px"><em>map()</em></th>
<th style="height: 24px"><em>flatMap()</em></th>
</tr>
</thead>
<tbody>
<tr style="height: 48px">
<td style="height: 48px">Transformation</td>
<td style="height: 48px">Applies a function that transforms a value to another value.</td>
<td style="height: 48px">Applies a function that transforms a value to a structure (e.g., a collection).</td>
</tr>
<tr style="height: 24px">
<td style="height: 24px">Syntax</td>
<td style="height: 24px"><em>map(f: A =&gt; B): F[B]</em></td>
<td style="height: 24px"><em>flatMap(f: A =&gt; F[B]): F[B]</em></td>
</tr>
<tr style="height: 48px">
<td style="height: 48px">Use Case</td>
<td style="height: 48px">Used when the function transforms a value without creating nested structures.</td>
<td style="height: 48px">Used when the function might create a nested structure or when you want to chain transformations that result in monads or other structures.</td>
</tr>
</tbody>
</table>
<h2 id="bd-conclusion" data-id="conclusion">5. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this tutorial, we explored the differences between <em>map()</em> and <em>flatMap()</em> functions. These two are the most fundamental operations in any functional programming language. A clear understanding of these functions is essential for utilizing the full power of functional programming.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/map-vs-flatmap">Difference Between map() and flatMap() in Scala</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/910696859/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/910696859/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2021%2f08%2fScala-Featured-Image-1024x536.png"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/910696859/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/convert-scala-list-to-tuple">Convert a Scala List to a Tuple</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/collection-delete-item">Remove an Element From a Scala Collection</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/list-compute-mean-value">Calculate the Average of a List in Scala</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2021/08/Scala-Featured-Image-150x150.png</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/play-application-twirl-forms</feedburner:origLink>
		<title>Forms in a Play Application</title>
		<link>https://feeds.feedblitz.com/~/909938138/0/baeldung/scala~Forms-in-a-Play-Application</link>
		
		<dc:creator><![CDATA[Emmanouil Varvarigos]]></dc:creator>
		<pubDate>Wed, 25 Dec 2024 06:15:26 +0000</pubDate>
				<category><![CDATA[Play Framework]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/?p=55739</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Discover how to use Twirl within a Play application to create and submit forms.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/909938138/0/baeldung/scala~Forms-in-a-Play-Application">Forms in a Play Application</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/909938138/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>The <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/play-framework-intro">Play</a> framework comes with <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/play-templating">Twirl</a> as the default template engine. Twirl is Scala-based and easy to learn for developers who have worked with Scala and HTML.</p>
<p>In this tutorial, we&#8217;ll demonstrate how to create and submit forms using Twirl within a Play application.</p>
<h2 id="bd-form-definition-and-simple-example" data-id="form-definition-and-simple-example">2. Form Definition and Simple Example</h2>
<div class="bd-anchor" id="form-definition-and-simple-example"></div>
<p><strong>Forms are Scala objects defined in the application code and passed through template parameters to the Twirl templates to be compiled and rendered.</strong> The <em>apply</em> methods of the <em>Form</em> helper object are a convenient way to create a <em>Form</em> object:</p>
<pre><code class="language-scala">val form: Form[SimpleForm] = Form(
  mapping(
    "i" -&gt; number,
    "active" -&gt; boolean,
    "msg" -&gt; text
  )(SimpleForm.apply)(SimpleForm.unapply)
)</code></pre>
<p>Now that we&#8217;ve created a form with three fields, including a number, a boolean, and a text field, it&#8217;s time to use it within a template:</p>
<pre><code class="language-scala">@(simpleForm: Form[SimpleForm])(implicit messages: Messages)
@form(action = routes.FormController.formPost()) {
    @inputText(simpleForm("i"))
    @inputText(simpleForm("active"))
    @inputText(simpleForm("msg"))
    
}</code></pre>
<p>Subsequently, a controller method will expose the template:</p>
<pre><code class="language-scala">def simpleForm: Action[AnyContent] = Action { implicit request =&gt;
  Ok(views.html.Baeldung.FormTemplate(SimpleForm.form))
}</code></pre>
<p>Finally, the controller&#8217;s <em>formPost</em> function handles the form submission:</p>
<pre><code class="language-scala">def formPost(): Action[AnyContent] = Action { implicit request =&gt;
  val form = SimpleForm.form.bindFromRequest().get
  Ok(form.toString)
}</code></pre>
<p>Now that all the building blocks are in place, let&#8217;s fetch the form to inspect the HTML code:</p>
<pre><code class="language-bash">$ curl localhost:9000/simple-form | awk '!/^[[:space:]]*$/'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   732  100   732    0     0  75046      0 --:--:-- --:--:-- --:--:-- 81333
&lt;form action="/simple-form" method="POST" &gt;
&lt;dl class=" " id="i_field"&gt;
    &lt;dt&gt;&lt;label for="i"&gt;i&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="i" name="i" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="info"&gt;Numeric&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" " id="active_field"&gt;
    &lt;dt&gt;&lt;label for="active"&gt;active&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="active" name="active" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="info"&gt;format.boolean&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" " id="msg_field"&gt;
    &lt;dt&gt;&lt;label for="msg"&gt;msg&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="msg" name="msg" value="" /&gt;
&lt;/dd&gt;
&lt;/dl&gt;
    &lt;input type="submit" value="Submit"&gt;
&lt;/form&gt;
</code></pre>
<p>It&#8217;s important to note that the awk post-processing we&#8217;ve added removes unnecessary empty lines added by the template engine and it&#8217;s used to shorten the curl command&#8217;s output. In other words, the <em>awk</em> part of the command is completely optional and can be omitted.</p>
<h2 id="bd-field-types" data-id="field-types">3. Field Types</h2>
<div class="bd-anchor" id="field-types"></div>
<p><strong>Out of the box,</strong> <strong>Twirl forms support various field types such as <em>number</em>, <em>boolean</em>, <em>date</em>, <em>sqldate</em>, <em>localdate</em>, <em>uuid</em>, and more</strong>. Specifically, the <em>Forms</em> helper object contains the mapping code for these types.</p>
<p>To demonstrate some of the various supported field types, we&#8217;ve created the <em>MultipleFieldsForm</em>:</p>
<pre><code class="language-scala">val form: Form[MultipleFieldsForm] = Form(
  mapping(
    "i" -&gt; number,
    "pwd" -&gt; text,
    "active" -&gt; boolean,
    "msg" -&gt; text,
    "date"-&gt; date,
    "uuid" -&gt; uuid,
    "favMovie" -&gt; text,
    "favDrink" -&gt; text
  )(MultipleFieldsForm.apply)(MultipleFieldsForm.unapply)
)
object Movies {
  val list = List(
    "pulpFiction" -&gt; "Pulp Fiction",
    "inception" -&gt; "Inception",
    "theMatrix" -&gt; "The Matrix",
    "titanic" -&gt; "Titanic",
  )
}
object Drinks {
  val list = List(
    "vodka" -&gt; "Vodka",
    "tequila" -&gt; "Tequila",
    "whisky" -&gt; "Whisky",
    "wine" -&gt; "Wine",
    "beer" -&gt; "Beer"
  )
}</code></pre>
<p>By using template input helpers, the generated form prevents user input errors by adding type validations:</p>
<pre><code class="language-scala">@(multipleFieldsForm: Form[MultipleFieldsForm])(implicit messages: Messages)
@form(action = routes.FormController.multipleFieldsFormPost()) {
    @inputText(multipleFieldsForm("i"))
    @inputPassword(multipleFieldsForm("pwd"))
    @checkbox(multipleFieldsForm("active"))
    @inputText(multipleFieldsForm("msg"))
    @inputDate(multipleFieldsForm("date"))
    @inputText(multipleFieldsForm("uuid"))
    @inputRadioGroup(multipleFieldsForm("favMovie"), MultipleFieldsForm.Movies.list)
    @select(multipleFieldsForm("favDrink"), MultipleFieldsForm.Drinks.list)
    &lt;input type="submit" value="Submit"&gt;
}</code></pre>
<p><strong>Twirl also supports custom fields, as long as a <em>Mapping</em> implementation is present</strong>. For this purpose, we&#8217;ll introduce the <em>UnitMeasurement</em> case class:</p>
<pre><code class="language-scala">case class UnitMeasurement(quantity: Int, unit: String)</code></pre>
<p>In other words, we&#8217;ll add support for fields like &#8220;1 pound&#8221; and &#8220;3 meters&#8221;. Initially, a <em>Mapping</em> of this custom type is required, namely the <em>unitMeasurementMapping</em>:</p>
<pre><code class="language-scala">def unitMeasurementMapping: Mapping[UnitMeasurement] =
  Forms.of[UnitMeasurement]</code></pre>
<p>Another addition we have to include to make our custom type work is the implicit <em>Formatter</em> since the <em>Forms.of</em> method requires it:</p>
<pre><code class="language-scala">implicit def binder: Formatter[UnitMeasurement] =
  new Formatter[UnitMeasurement] {
    override def bind(
      key: String,
      data: Map[String, String]
    ): Either[Seq[FormError], UnitMeasurement] = Formats.parsing(
      d =&gt; UnitMeasurement.fromString(d),
      "The format is (\\d*)(\\s)(\\D*)- example: \"1 pound\"",
      Nil
    )(key, data)
    override def unbind(
      key: String,
      value: UnitMeasurement
    ): Map[String, String] = Map(key -&gt; s"${value.quantity} ${value.unit}")
  }</code></pre>
<p>Essentially, the <em>Formatter[UnitMeasurement]</em> trait defines the &#8220;<em>UnitMeasurement</em> to <em>String</em>&#8221; and &#8220;<em>String</em> to <em>UnitMeasurement</em>&#8221; transformations. Another important building block is the helper method <em>Formats.parsing</em> that provides every Form-related functionality, requiring only a &#8220;<em>String</em> to T&#8221; arrow function.</p>
<p>The <em>UnitMeasurement.fromString</em> method implements the actual transformation:</p>
<pre><code class="language-scala">object UnitMeasurement {
  implicit val unitMeasurementFormWrites: Writes[UnitMeasurement] =
    Json.writes[UnitMeasurement]
  private val pattern = "(\\d*)(\\s)(\\D*)".r
  def fromString(str: String): UnitMeasurement = {
    val matches = pattern.findAllIn(str)
    if (matches.hasNext) {
      val List(number, space, quantity) = matches.subgroups
      UnitMeasurement(number.toInt, quantity)
    } else {
      throw new RuntimeException(s"Incorrect data: $str")
    }
  }
}</code></pre>
<p>Now, we&#8217;re ready to use this new custom <em>Mapping</em> in a form definition:</p>
<pre><code class="language-scala">val form: Form[ComplexFormCustomField] = Form(
  mapping(
    "i" -&gt; number,
    "active" -&gt; boolean,
    "msg" -&gt; text,
    "measurement" -&gt; Measure.unitMeasurementMapping
  )(ComplexFormCustomField.apply)(ComplexFormCustomField.unapply)
)</code></pre>
<h2 id="bd-field-constraints" data-id="field-constraints">4. Field Constraints</h2>
<div class="bd-anchor" id="field-constraints"></div>
<p>While Twirl provides field-type validation out of the box, <strong>additional constraints can be applied to the form fields</strong>. The <em>Forms</em> helper object provides a variety of helper functions that return constrained mappings:</p>
<pre><code class="language-scala">val form: Form[InputFormWithConstraints] = Form(
  mapping(
    "i" -&gt; number(min = 10, max = 20),
    "msg" -&gt; text(minLength = 3, maxLength = 12),
    "msgOpt" -&gt; optional(text),
    "email" -&gt; email,
    "birthday" -&gt; date
  )(InputFormWithConstraints.apply)(InputFormWithConstraints.unapply)
)</code></pre>
<p>Another neat feature is that we&#8217;re able to define custom constraints by leveraging the <em>verifying</em> method of the <em>Mapping</em> trait:</p>
<pre><code class="language-scala">val form: Form[InputFormWithConstraints] = Form(
  mapping(
    "email" -&gt; email.verifying(minLength(15)),
    "birthday" -&gt; date.verifying(
      "Not 18 years old",
      d =&gt; d.toInstant.isBefore(Instant.now().minus(18, ChronoUnit.YEARS))
    )
  )(InputFormWithCustomConstraints.apply)(
    InputFormWithCustomConstraints.unapply
  )
)</code></pre>
<p>In the above example, an email is valid only if it&#8217;s at least 15 characters long. Also, a birthday date is considered valid if the date is older than 18 years.</p>
<h2 id="bd-validation" data-id="validation">5. Validation</h2>
<div class="bd-anchor" id="validation"></div>
<p><strong>Field constraints enable us to provide meaningful feedback to the users regarding unsuccessful form submissions.</strong> To do so, the controller methods that handle form submission requests need to be written differently:</p>
<pre><code class="language-scala">def formWithConstraintsPost(): Action[AnyContent] = Action { implicit request =&gt;
  InputFormWithConstraints.form
    .bindFromRequest()
    .fold(
      { formWithError =&gt;
        BadRequest(views.html.Baeldung.FormTemplateWithConstraints(formWithError))
      },
      { data =&gt; Ok(Json.toJson(data)) }
    )
}</code></pre>
<p>In case of erroneous form submissions, the <em>formWithConstraintsPost</em> method wraps the template initialized with the rejected form in a <em>BadRequest. </em>Let&#8217;s post an empty form to inspect the server response:</p>
<pre><code class="language-bash">$ curl localhost:9000/form-with-constraints -d "" | awk '!/^[[:space:]]*$/'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1655  100  1655    0     0   183k      0 --:--:-- --:--:-- --:--:--  202k
&lt;form action="/form-with-constraints" method="POST" &gt;
&lt;dl class=" error" id="i_field"&gt;
    &lt;dt&gt;&lt;label for="i"&gt;i&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="i" name="i" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="error"&gt;This field is required&lt;/dd&gt;
        &lt;dd class="info"&gt;Minimum value: 10&lt;/dd&gt;
        &lt;dd class="info"&gt;Maximum value: 20&lt;/dd&gt;
        &lt;dd class="info"&gt;Numeric&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" error" id="msg_field"&gt;
    &lt;dt&gt;&lt;label for="msg"&gt;msg&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="msg" name="msg" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="error"&gt;This field is required&lt;/dd&gt;
        &lt;dd class="info"&gt;Minimum length: 3&lt;/dd&gt;
        &lt;dd class="info"&gt;Maximum length: 12&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" " id="msgOpt_field"&gt;
    &lt;dt&gt;&lt;label for="msgOpt"&gt;msgOpt&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="msgOpt" name="msgOpt" value="" /&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" error" id="email_field"&gt;
    &lt;dt&gt;&lt;label for="email"&gt;email&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="text" id="email" name="email" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="error"&gt;This field is required&lt;/dd&gt;
        &lt;dd class="info"&gt;Email&lt;/dd&gt;
&lt;/dl&gt;
&lt;dl class=" error" id="birthday_field"&gt;
    &lt;dt&gt;&lt;label for="birthday"&gt;birthday&lt;/label&gt;&lt;/dt&gt;
    &lt;dd&gt;
    &lt;input type="date" id="birthday" name="birthday" value="" /&gt;
&lt;/dd&gt;
        &lt;dd class="error"&gt;This field is required&lt;/dd&gt;
        &lt;dd class="info"&gt;Date ('yyyy-MM-dd')&lt;/dd&gt;
&lt;/dl&gt;
    &lt;input type="submit" value="Submit"&gt;
&lt;/form&gt;
</code></pre>
<p>As expected, the HTML response is our form with error element additions based on the field constraints we defined earlier.</p>
<h2 id="bd-conclusion" data-id="conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we’ve described how to create, render, submit, and validate HTML forms with Play framework. The Twirl engine is a solid choice for projects using Scala and Play if there&#8217;s no alternative way of handling forms.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/play-application-twirl-forms">Forms in a Play Application</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/909938138/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/909938138/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-09-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/909938138/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-09-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/scalatest-eventually-block</feedburner:origLink>
		<title>eventually Block In ScalaTest</title>
		<link>https://feeds.feedblitz.com/~/908750069/0/baeldung/scala~eventually-Block-In-ScalaTest</link>
		
		<dc:creator><![CDATA[Yadu Krishnan]]></dc:creator>
		<pubDate>Mon, 02 Dec 2024 17:59:19 +0000</pubDate>
				<category><![CDATA[Testing]]></category>
		<category><![CDATA[ScalaTest]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/?p=55718</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn how to use the eventually block in ScalaTest.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/908750069/0/baeldung/scala~eventually-Block-In-ScalaTest">eventually Block In ScalaTest</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908750069/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-13-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-ignore-conditionally">Ignore Tests Conditionally in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-compare-double-values">Comparing Double Values in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-tests">Testing Akka Streams</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/scalatest">ScalaTest</a> is one of the most popular and widely used testing frameworks in Scala. It offers various tools to write expressive and concise tests, and one of its standout features is the <em>eventually</em> block. This utility is especially useful when dealing with asynchronous or <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/cs/eventual-consistency-vs-strong-eventual-consistency-vs-strong-consistency">eventually consistent</a> systems, such as microservices, distributed databases, or message queues.</p>
<p>In this tutorial, let&#8217;s look at how to use the <em>eventually</em> block effectively.</p>
<h2 id="bd-set-up" data-id="set-up">2. Set Up</h2>
<div class="bd-anchor" id="set-up"></div>
<p>First, let&#8217;s add the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://mvnrepository.com/artifact/org.scalatest/scalatest_3/3.2.19"><em>ScalaTest</em></a> library dependency to our <em>build.sbt</em> file:</p>
<pre><code class="language-scala">libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % Test</code></pre>
<p>Now, let’s create a simple test. For this example, we’ll simulate an asynchronous operation where a value is updated after a delay. This pattern resembles scenarios such as database write operations, where updates take some time to complete:</p>
<pre><code class="language-">class AsyncOperation(waitTime: Int) {
  private var database: Map[String, String] = Map.empty
  def writeToDatabase(key: String, value: String): Unit = {
    new Thread(() =&gt; {
      Thread.sleep(waitTime) // Simulate a delay in writing to the database
      database += (key -&gt; value)
    }).start()
  }
  def readFromDatabase(key: String): Option[String] = database.get(key)
}
</code></pre>
<p>The <em>writeToDatabase()</em> method simulates a delayed async write, while <em>readFromDatabase()</em> checks the result. Let&#8217;s write a simple test to verify this code:</p>
<pre><code class="language-scala">it should "get the result from the database after save" in {
  val op = AsyncOperation(100)
  op.writeToDatabase("key", "value")
  op.readFromDatabase("key") shouldBe Some("value")
}</code></pre>
<p><strong>This test fails because the read operation is attempted before the write operation has finished.</strong></p>
<p>Using ScalaTest&#8217;s <em>eventually </em>block, we’ll verify that the data appears in the database after the write operation is completed.</p>
<h2 id="bd-eventually-block" data-id="eventually-block">3. Eventually Block</h2>
<div class="bd-anchor" id="eventually-block"></div>
<p><strong>The <em>eventually</em> block in ScalaTest repeatedly retries the provided code until the assertion passes or the specified timeout is reached.</strong> This is particularly useful for testing asynchronous operations, eventual consistency, or delayed responses, such as database writes, API calls, or message queue processing.</p>
<p>We can incorporate the <em>eventually</em> block by either extending the test class with the <em>Eventually</em> trait or importing it directly. In this example, we’ll mix in the <em>Eventually</em> trait to our test class:</p>
<pre><code class="language-">class EventuallyUnitTest extends AnyFlatSpec with Matchers with Eventually {
  it should "retry the save to database multiple times in eventually with default timeout" in {
    val op = AsyncOperation(100)
    op.writeToDatabase("key", "value")
    eventually {
      op.readFromDatabase("key") shouldBe Some("value")
    }
  }
}</code></pre>
<p>This code is similar to the failed test described in the previous section but with one difference: the read operation is now wrapped within the <em>eventually</em> block. As a result, <strong>the <em>eventually</em> block retries the read operation multiple times until the assertion succeeds or the timeout is reached.</strong> By default, it uses a timeout of 150 milliseconds and a retry interval of 15 milliseconds. Since the write operation takes 100 milliseconds, the default timeout provides sufficient time for the read operation to succeed, allowing the test to pass.</p>
<p>Additionally, <strong>the <em>eventually</em> block uses a backoff algorithm to optimize retries. This helps to avoid overloading the system by gradually increasing the interval between each retry</strong>.</p>
<h2 id="bd-configuring-the-timeout" data-id="configuring-the-timeout">4. Configuring the Timeout</h2>
<div class="bd-anchor" id="configuring-the-timeout"></div>
<p>Let&#8217;s see what happens if the write operation takes more than 150 milliseconds. Let&#8217;s update the test to use more time for write operation:</p>
<pre><code class="language-">val op = AsyncOperation(300)
op.writeToDatabase("key", "value")
eventually {
  op.readFromDatabase("key") shouldBe Some("value")
}</code></pre>
<p>Running the test with this code fails, displaying the message:</p>
<pre><code class="language-">The code passed to eventually never returned normally.
Attempted 5 times over 154.83845499999998 milliseconds. 
Last failure message: None was not equal to Some("value").</code></pre>
<p>This shows that even after 5 retries over approximately 150 milliseconds, the read operation didn&#8217;t return the expected value. It’s important to note that due to task scheduling and thread availability, the actual timeout may slightly exceed the configured 150 milliseconds.</p>
<p>In cases where we know the operation requires more time, <strong>we can adjust the timeout by providing a custom implicit value of type <em>PatienceConfig </em>using<em> the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/contextual-abstractions#the-given-instance">given </a></em>keyword</strong>, which the <em>eventually</em> block will use:</p>
<pre><code class="language-scala">given patienceConfig: PatienceConfig =
  PatienceConfig(
    timeout = scaled(Span(2, Seconds)),
    interval = scaled(Span(5, Millis))
  )</code></pre>
<p>This configuration sets custom values for the <em>timeout</em> and <em>interval</em>. Using <em>scaled</em> with the new defaults is optional but recommended, as it allows the values to adjust dynamically when tests run on systems with varying performance. With this updated configuration, the test now passes as the timeout is increased to 2 seconds.</p>
<p>Additionally, <strong>instead of using the implicit configuration, we can also pass the timeout and interval explicitly in the <em>eventually</em> block</strong>:</p>
<pre><code class="language-scala">eventually(timeout = Timeout(Span(2, Seconds)), interval = Interval(Span(50, Millis))) {
  op.readFromDatabase("new-key") shouldBe Some("value")
}</code></pre>
<p>This makes the timeout clearer than just using an implicit variable.</p>
<h2 id="bd-conclusion" data-id="conclusion">5. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we explored the <em>eventually</em> block in ScalaTest and its usefulness in verifying asynchronous operations, particularly in integration tests. We also discussed how to configure timeout values to meet specific requirements.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/scalatest-eventually-block">eventually Block In ScalaTest</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/908750069/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908750069/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-13-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908750069/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-ignore-conditionally">Ignore Tests Conditionally in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/scalatest-compare-double-values">Comparing Double Values in ScalaTest</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-tests">Testing Akka Streams</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-13-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/akka-streams-error-handling</feedburner:origLink>
		<title>Error Handling in Akka Streams</title>
		<link>https://feeds.feedblitz.com/~/908453492/0/baeldung/scala~Error-Handling-in-Akka-Streams</link>
		
		<dc:creator><![CDATA[Matteo Di Pirro]]></dc:creator>
		<pubDate>Tue, 26 Nov 2024 09:03:10 +0000</pubDate>
				<category><![CDATA[Akka]]></category>
		<category><![CDATA[Akka Streams]]></category>
		<category><![CDATA[Error Handling]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/?p=55704</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn different ways to handle errors in Akka Streams.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/908453492/0/baeldung/scala~Error-Handling-in-Akka-Streams">Error Handling in Akka Streams</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908453492/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-12-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-tests">Testing Akka Streams</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/apache-pekko">Introduction to Apache Pekko</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-read-csv-file">Reading CSV Files Using Akka-Streams</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-introduction" data-id="introduction">1. Introduction</h2>
<div class="bd-anchor" id="introduction"></div>
<p>In a previous article, we saw what <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/akka-streams">Akka Streams</a> are and how to test them. In this article, we&#8217;ll dive into error handling. Typically, when an operator in a stream fails, the entire stream gets torn down. In that case, all the downstream operators get informed about the failure and won&#8217;t get run, whereas upstream operators see a cancellation.</p>
<p><strong>There are three main ways to avoid complete stream failure: Recovering from the failure, restarting the stream, or supervising it.</strong></p>
<p>In this tutorial, we&#8217;ll briefly examine all three ways to handle errors in Akka Streams.</p>
<h2 id="bd-recovering-from-failures" data-id="recovering-from-failures">2. Recovering from Failures</h2>
<div class="bd-anchor" id="recovering-from-failures"></div>
<p><strong>Stream recovery allows us to emit one final element downstream instead of the error to avoid complete stream failure.</strong> We can do this with the <em>recover</em> operator.</p>
<p>Let&#8217;s see an example:</p>
<pre><code class="language-scala">val parseWithRecover: Flow[String, Either[String, (Int, Int)], NotUsed] =
    Flow[String]
      .map { pair =&gt;
        val parts = pair.split(",")
        Right((parts(0).toInt, parts(1).toInt))
      }
      .recover({ case e: ArrayIndexOutOfBoundsException =&gt;
        Left(e.getMessage)
      })</code></pre>
<p>In the code snippet above, we added <em>recover</em> to the <em>parse</em> <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka/current/akka/stream/scaladsl/Flow.html"><em>Flow</em></a> we saw in the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/akka-streams">Introduction to Akka-Streams in Scala</a> article. In particular, we changed the return type of the <em>Flow</em> to be <em>Either[String, (Int, Int)]</em>. This way, we can react to <em>ArrayIndexOutOfBoundsException</em>s, returning an error message.</p>
<p>Let&#8217;s see a simple test for the new <em>Flow</em>:</p>
<pre><code class="language-scala">"The \"parseWithRecover\" flow" should "parse recover from a parsing error" in {
    val (pub, sub) = TestSource[String]()
      .via(parseWithRecover)
      .toMat(TestSink[Either[String, (Int, Int)]]())(Keep.both)
      .run()
    pub.sendNext("1,1")
    pub.sendNext("145146")
    pub.sendComplete()
    sub.requestNext(Right(1, 1))
    sub.requestNext(Left("Index 1 out of bounds for length 1"))
    sub.expectComplete()
  }</code></pre>
<h3 id="bd-1-adding-retries" data-id="1-adding-retries">2.1. Adding Retries</h3>
<div class="bd-anchor" id="1-adding-retries"></div>
<p>The <em>recover</em> operator only lets us emit one element instead of a failed one. <strong><em>recoverWithRetries</em> does the same thing up to a specified number of times.</strong> This is useful when dealing with temporary errors, such as network hiccups.</p>
<h2 id="bd-restarting-the-stream-after-a-failure" data-id="restarting-the-stream-after-a-failure">3. Restarting the Stream After a Failure</h2>
<div class="bd-anchor" id="restarting-the-stream-after-a-failure"></div>
<p>In Akka Streams, we can restart a single stream operator: <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka/current/akka/stream/scaladsl/Source.html"><em>Source</em></a>, <em>Flow</em>, or <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka/current/akka/stream/scaladsl/Sink.html"><em>Sink</em></a>. We can do that using the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka-core/current//akka/stream/scaladsl/RestartSource$.html"><em>RestartSource</em></a>, <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka-core/current//akka/stream/scaladsl/RestartFlow$.html"><em>RestartFlow</em></a>, and <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka-core/current//akka/stream/scaladsl/RestartSink$.html"><em>RestartSink</em></a> constructs, respectively, to implement an exponential backoff restart strategy. This means that when the given operator fails, Akka will restart it, waiting an increasing amount of time between two subsequent restarts.</p>
<p><strong>This pattern lets us add restart support on a very fine grade, enabling it for single-stream operators. It is also very useful for mitigating the effects of transient failures, such as resources not being available</strong>.</p>
<p>Let&#8217;s see an example, using the stream elements implemented in the &#8220;<a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/akka-streams">Introduction to Akka-Streams in Scala</a>&#8221; article and adding backoff restarts to the <em>source</em>:</p>
<pre><code class="language-scala">private val backoffSettings = RestartSettings(
  minBackoff = 3 seconds,
  maxBackoff = 30 seconds,
  randomFactor = 0.2
).withMaxRestarts(3, 5.minutes)
RestartSource
  .withBackoff(backoffSettings) { () =&gt; source }
  .via(parse)
  .via(compare)
  .runWith(sink)
  .andThen {
    case Failure(exception) =&gt; println(exception)
    case Success((correct, total)) =&gt;
      println(s"$correct/$total correct answers")
  }(system.dispatcher)
  .onComplete(_ =&gt; system.terminate())(system.dispatcher)</code></pre>
<p>In the example above, we defined a backoff strategy with the <em><a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka-core/current//akka/stream/RestartSettings.html">RestartSettings</a></em> class. In particular, we set the initial restart delay to 3 seconds (<em>minBackoff</em>), allowing the delay to grow until 30 seconds (<em>maxBackoff</em>), with a <em>randomFactor</em> of <em>0.2</em>. <strong>The random factor simply randomizes the backoff calculation; the higher the value, the more random the backoff delay.</strong></p>
<p>Lastly, we allowed the stream to restart at most three times or for five minutes.</p>
<p>We then add backoff capabilities to <em>source</em> by wrapping it inside <em>RestartSource#withBackoff</em>, which inputs the backoff settings and a lazily-evaluated source. If we run the example above, we get the following output:</p>
<pre><code class="language-plaintext">[baeldung-akka.actor.default-dispatcher-6] INFO akka.stream.scaladsl.RestartWithBackoffSource - Restarting stream due to completion [1]
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.scaladsl.RestartWithBackoffSource - Restarting stream due to completion [2]
[baeldung-akka.actor.default-dispatcher-6] INFO akka.stream.scaladsl.RestartWithBackoffSource - Restarting stream due to completion [3]
16/24 correct answers</code></pre>
<p>The output shows the stream restarted three times, as expected. <strong>This is because <em>RestartSource#withBackoff</em> restarts the stream on success and failure.</strong></p>
<p><strong>If we wanted to restart it only on failure, we&#8217;d have to use</strong> <em><strong>RestartSource#onFailuresWithBackoff</strong>.</em></p>
<p>A <em>RestartSource</em> will not complete or fail until <em>maxRestarts</em> is reached, as it handles completion and failure by restarting the underlying <em>Source</em>. <strong>For <em>RestartFlow</em> and <em>RestartSink</em>, the restart might cause some messages to get lost.</strong></p>
<h2 id="bd-supervising-a-stream" data-id="supervising-a-stream">4. Supervising a Stream</h2>
<div class="bd-anchor" id="supervising-a-stream"></div>
<p><strong>Supervision is a more advanced error resolution strategy, inspired by the error handling of <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/akka-actors-java">Akka actors</a>.</strong></p>
<p>However, it does not make sense in all scenarios. For instance, if an operator interacts with an external service over the network, a back-off strategy is more suited if the connection drops. Therefore, not all operators support stream supervision out of the box and Akka Stream does not supervise streams automatically.</p>
<p>On the contrary, <strong>streams handling user data might benefit from supervision</strong>, as it gives us more control over what to do in case of failure.</p>
<p>We can choose one of three supervision strategies:</p>
<ul>
<li><strong><em>Stop</em></strong>: Where the stream is completed with failure. This is the default</li>
<li><strong><em>Resume</em></strong>: Where the element causing the failure is dropped without terminating the stream</li>
<li><strong><em>Restart</em></strong>: Where the element causing the failure is dropped and the stream continues after restarting the operator, effectively creating a new operator instance. In this case, all the internal state accumulated in the stream gets lost, and <strong>the stream will not replay the elements that flowed in the past</strong></li>
</ul>
<p>Defining a supervision strategy requires accessing the stream&#8217;s underlying runnable graph. Let&#8217;s see an example:</p>
<pre><code class="language-scala">val runnableGraph = TestSource[String]()
  .via(parseWithRecover)
  .toMat(TestSink[Either[String, (Int, Int)]]())(Keep.both)
val decider: Supervision.Decider = {
  case _: ArrayIndexOutOfBoundsException =&gt; Supervision.Resume
  case _                                 =&gt; Supervision.Stop
}
val graphWithResumeSupervision =
      runnableGraph.withAttributes(ActorAttributes.supervisionStrategy(decider))
val (pub, sub) = graphWithResumeSupervision.run()
pub.sendNext("1,1")
pub.sendNext("145146")
pub.sendNext("1,2")
pub.sendComplete()
sub.requestNext(Right(1, 1))
sub.requestNext(Right(1, 2))
sub.expectComplete()</code></pre>
<p>In the example above, we first defined a supervision strategy using the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://doc.akka.io/api/akka-core/current//akka/stream/Supervision$.html"><em>Supervision.Decider</em></a> class. In particular, we chose to resume the stream only in the case of <em>ArrayIndexOutOfBoundsException</em>s, stopping it for all the other errors. Secondly, we decorated the stream graph with the <em>withAttributes</em> method, and then we ran it.</p>
<p>In particular, we used the test kit to send three elements to the stream, with the second crafted to throw an <em>ArrayIndexOutOfBoundsException</em>. Nonetheless, the stream only emitted two elements before completion, proving the second was indeed dropped.</p>
<h2 id="bd-logging-stream-elements" data-id="logging-stream-elements">5. Logging Stream Elements</h2>
<div class="bd-anchor" id="logging-stream-elements"></div>
<p>Logging is not a form of error handling per se, but it is certainly a good practice to signal that something went wrong during the execution of a stream. We can use the <em>log</em> operator in Akka Streams to that end:</p>
<pre><code class="language-scala">val parseWithLogging: Flow[String, (Int, Int), NotUsed] =
    Flow[String]
      .map { pair =&gt;
        val parts = pair.split(",")
        (parts(0).toInt, parts(1).toInt)
      }
      .log(name = "Baeldung stream")
      .addAttributes(
        Attributes.logLevels(
          onElement = Attributes.LogLevels.Info,
        )
      )</code></pre>
<p>To have Akka Stream log something, we add a logging backend to our project. For example, adding <em>slf4j-simple</em> to the <em>build.sbt</em> file:</p>
<pre><code class="language-scala">libraryDependencies ++= Seq(
  "org.slf4j" % "slf4j-api" % "2.0.16",
  "org.slf4j" % "slf4j-simple" % "2.0.16"
)</code></pre>
<p><strong>By default, the <em>log</em> operator logs the element of a stream at the debug level and any exceptions at the error level.</strong> However, logging levels are configurable via <em>Attributes#logLevels(). </em>If we run the example in the &#8220;<a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/akka-streams">Introduction to Akka-Streams in Scala</a>&#8221; article, using <em>parseWithLogging</em> instead of <em>parse,</em> we&#8217;ll get the following output:</p>
<pre><code class="language-plaintext">[baeldung-akka.actor.default-dispatcher-6] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (5,10)
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (15,15)
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (78,79)
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (12,12)
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (0,0)
[baeldung-akka.actor.default-dispatcher-7] INFO akka.stream.Materializer - [Baeldung stream] Element: (456,456)</code></pre>
<p>Where each element is logged, along with the name of the stream.</p>
<p>Stream logging is a broad topic. <strong>For the scope of this tutorial, it is enough to know that Akka Streams lets us decide what to log and to what level.</strong></p>
<h2 id="bd-conclusion" data-id="conclusion">6. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we saw many ways to deal with errors in Akka Streams. First, we analyzed recoveries, allowing us to define a strategy to replace faulty elements. Secondly, we moved to restart the components of a stream, a strategy suitable to cope with temporary errors. Thirdly, we uncovered the power of supervision to define fine-grained error handling. Lastly, we took a quick look at logging individual stream elements or errors as they happen.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/akka-streams-error-handling">Error Handling in Akka Streams</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/908453492/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908453492/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-12-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908453492/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-tests">Testing Akka Streams</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/apache-pekko">Introduction to Apache Pekko</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/akka-streams-read-csv-file">Reading CSV Files Using Akka-Streams</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-150x150.jpg</webfeeds:featuredImage></item>
<item>
<feedburner:origLink>https://www.baeldung.com/scala/remove-first-n-digits</feedburner:origLink>
		<title>Remove the First n Digits of a Number in Scala</title>
		<link>https://feeds.feedblitz.com/~/908408039/0/baeldung/scala~Remove-the-First-n-Digits-of-a-Number-in-Scala</link>
		
		<dc:creator><![CDATA[Pedro Rijo]]></dc:creator>
		<pubDate>Mon, 25 Nov 2024 13:30:35 +0000</pubDate>
				<category><![CDATA[Scala Numbers]]></category>
		<category><![CDATA[String Conversions]]></category>
		<guid isPermaLink="false">https://www.baeldung.com/scala/?p=55694</guid>
					<description><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="max-width:100% !important;height:auto !important;float: left; margin-right: 5px;" loading="lazy" /><p>Learn how to remove the first n digits from a number in Scala using basic string manipulation techniques.</p>
The post <a rel="NOFOLLOW" href="https://feeds.feedblitz.com/~/908408039/0/baeldung/scala~Remove-the-First-n-Digits-of-a-Number-in-Scala">Remove the First n Digits of a Number in Scala</a> first appeared on <a rel="NOFOLLOW" href="https://www.baeldung.com/scala">Baeldung on Scala</a>.<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908408039/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-12-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/csv-files-read-write">CSV Files in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/round-number-to-multiple-of-ten">Round a Number to the Nearest or Next Multiple of 10 in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/round-off-decimal-numbers">Ways to Round Off Decimal Numbers in Scala</a></li></ul>&#160;</div>]]>
</description>
										<content:encoded><![CDATA[<img src="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg" class="webfeedsFeaturedVisual wp-post-image" alt="" style="float: left; margin-right: 5px;" decoding="async" loading="lazy" srcset="https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-1024x536.jpg 1024w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-300x157.jpg 300w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-768x402.jpg 768w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-100x52.jpg 100w, https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12.jpg 1200w" sizes="auto, (max-width: 580px) 100vw, 580px" /><h2 id="bd-overview" data-id="overview">1. Overview</h2>
<div class="bd-anchor" id="overview"></div>
<p>In this tutorial, we’ll demonstrate how to remove the first n digits from a number in Scala using basic string manipulation techniques.</p>
<h2 id="bd-converting-the-number-to-a-string" data-id="converting-the-number-to-a-string">2. Converting the Number to a String</h2>
<div class="bd-anchor" id="converting-the-number-to-a-string"></div>
<p>To begin, we need to ensure our number can be manipulated as a string. This step is essential, as we will be removing characters based on their positions.</p>
<p>Here’s a straightforward approach:</p>
<pre><code class="language-scala">def removeFirstNDigits(num: Int, n: Int): Int = {
  num.toString.drop(n).toInt
}</code></pre>
<p>In this method, we <strong>convert the integer to a string and use the <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/collections"><em>String.drop()</em> </a>method</strong> to remove the first n characters. However, we should consider what happens if n exceeds the length of the number.</p>
<h2 id="bd-handling-edge-cases" data-id="handling-edge-cases">3. Handling Edge Cases</h2>
<div class="bd-anchor" id="handling-edge-cases"></div>
<p>To account for potential issues, we can modify our function to <strong>return 0 if n is greater than or equal to the length of the number:</strong></p>
<pre><code class="language-scala">def removeFirstNDigitsLimit(num: Int, n: Int): Int = {
  val numString = num.toString
  if (n &gt;= numString.length) 
    0 
  else 
    numString.drop(n).toInt
}
</code></pre>
<p>This version checks the length of the string representation of the number and safely handles the scenario where n is too large.n</p>
<h2 id="bd-example-usage" data-id="example-usage">4. Example Usage</h2>
<div class="bd-anchor" id="example-usage"></div>
<p>Let’s look at some examples to see how our function behaves:</p>
<pre><code class="language-scala">removeFirstNDigitsLimit(123456, 2) shouldBe 3456
removeFirstNDigitsLimit(123456, 5) shouldBe 6
removeFirstNDigitsLimit(123456, 6) shouldBe 0</code></pre>
<p>These examples illustrate how our function effectively removes the specified number of digits.</p>
<h2 id="bd-using-pattern-matching" data-id="using-pattern-matching">5. Using Pattern Matching</h2>
<div class="bd-anchor" id="using-pattern-matching"></div>
<p>An alternative approach could involve <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/pattern-matching">pattern matching</a> to enhance readability and expressiveness:</p>
<pre><code class="language-scala">def removeFirstNDigitsPatternMatching(num: Int, n: Int): Int = {
  val numString = num.toString
  numString match {
    case str if n &gt;= str.length =&gt; 0
    case str =&gt; str.drop(n).toInt
  }
}
</code></pre>
<p>This method <strong>utilizes pattern matching to succinctly handle the edge case</strong>, making the code more elegant while retaining its functionality.</p>
<h2 id="bd-negative-numbers" data-id="negative-numbers">6. Negative Numbers</h2>
<div class="bd-anchor" id="negative-numbers"></div>
<p>When dealing with negative numbers, we need to account for the presence of the negative sign. In our previous examples, the negative sign (<code>-</code>) is part of the number but does not get removed when using string manipulation. This means that if we naively apply <code>drop(n)</code> to a negative number, the negative sign will still be preserved in the result, potentially leading to incorrect behavior.</p>
<p>To handle negative numbers correctly, we can <strong>add a check to separate the sign from the magnitude of the number</strong>. Here’s how we can modify our function to deal with negative numbers:</p>
<pre><code class="language-scala">def removeFirstNDigitsNegative(num: Int, n: Int): Int = {
  val numString = num.toString
  if (num &lt; 0) {
    // For negative numbers, remove the first n digits but keep the negative sign
    val absNumString = numString.drop(1) // Drop the negative sign
    if (n &gt;= absNumString.length) 0
    else ("-" + absNumString.drop(n)).toInt
  } else {
    // For positive numbers, apply the same logic as before
    if (n &gt;= numString.length) 0
    else numString.drop(n).toInt
  }
}
</code></pre>
<p>Let&#8217;s see an example with this function:</p>
<pre><code class="language-scala">removeFirstNDigitsNegative(-123456, 2) shouldBe -3456</code></pre>
<h2 id="bd-conclusion" data-id="conclusion">7. Conclusion</h2>
<div class="bd-anchor" id="conclusion"></div>
<p>In this article, we learned how to remove the first n digits from a number in Scala.</p>
<p>We explored different approaches, starting from a basic implementation to more robust solutions that handle edge cases. By using string manipulation and pattern matching, we effectively solved the problem while keeping the code clean and efficient.</p>The post <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala/remove-first-n-digits">Remove the First n Digits of a Number in Scala</a> first appeared on <a href="https://feeds.feedblitz.com/~/t/0/0/baeldung/scala/~https://www.baeldung.com/scala">Baeldung on Scala</a>.<Img align="left" border="0" height="1" width="1" alt="" style="border:0;float:left;margin:0;padding:0;width:1px!important;height:1px!important;" hspace="0" src="https://feeds.feedblitz.com/~/i/908408039/0/baeldung/scala">
<div style="clear:both;padding-top:0.2em;"><a title="Like on Facebook" href="https://feeds.feedblitz.com/_/28/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/fblike20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Pin it!" href="https://feeds.feedblitz.com/_/29/908408039/baeldung/scala,https%3a%2f%2fwww.baeldung.com%2fwp-content%2fuploads%2fsites%2f3%2f2022%2f12%2fScala-Featured-Image-12-1024x536.jpg"><img height="20" src="https://assets.feedblitz.com/i/pinterest20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Post to X.com" href="https://feeds.feedblitz.com/_/24/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/x.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by email" href="https://feeds.feedblitz.com/_/19/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/email20.png" style="border:0;margin:0;padding:0;"></a>&#160;<a title="Subscribe by RSS" href="https://feeds.feedblitz.com/_/20/908408039/baeldung/scala"><img height="20" src="https://assets.feedblitz.com/i/rss20.png" style="border:0;margin:0;padding:0;"></a>&nbsp;<h3 style="clear:left;padding-top:10px">Related Stories</h3><ul><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/csv-files-read-write">CSV Files in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/round-number-to-multiple-of-ten">Round a Number to the Nearest or Next Multiple of 10 in Scala</a></li><li><a rel="NOFOLLOW" href="https://www.baeldung.com/scala/round-off-decimal-numbers">Ways to Round Off Decimal Numbers in Scala</a></li></ul>&#160;</div>]]>
</content:encoded>
					
		
		
		<webfeeds:featuredImage>https://www.baeldung.com/wp-content/uploads/sites/3/2022/12/Scala-Featured-Image-12-150x150.jpg</webfeeds:featuredImage></item>
</channel></rss>

