r/scala 16h ago

The Bowling Game - From Imperative to Functional Programming - Part 2

Thumbnail fpilluminated.org
Upvotes

r/scala 21h ago

Allow Experimental 0.1.0 - use Scala 3 `@experimental` APIs without making your callers experimental

Upvotes

I’ve released the first version of Allow Experimental, a small Scala 3 compiler plugin:

https://github.com/DmytroMitin/allow-experimental

The motivation is to separate two ideas that Scala’s normal @experimental mechanism deliberately couples:

  • an API is experimental;
  • a consumer intentionally accepts the risk of using that API internally.

For example:

import scala.annotation.experimental
import io.github.dmytromitin.allowexperimental.allowExperimental

@experimental
def provider(): Int = 1

@allowExperimental
def allowed(): Int =
  provider()

def ordinaryCaller(): Int =
  allowed()

allowed may use the experimental API in its implementation, but callers of allowed do not themselves become experimental. A direct unmarked call to provider() still fails with the normal Scala experimental-use diagnostic.

The release currently supports exactly Scala 3.3.8, 3.8.4, and 3.9.0. The compiler plugin is full-crossed because it depends on compiler internals.

ThisBuild / scalaVersion := "3.9.0" // 3.3.8, 3.8.4

libraryDependencies ++= Seq(
  "com.github.dmytromitin" %% "allow-experimental-annotation" % "0.1.0" % Provided,
  compilerPlugin(("com.github.dmytromitin" % "allow-experimental-plugin" % "0.1.0").cross(CrossVersion.full)),
)

One practical use case is macro implementations: a public inline macro frontend can delegate to a private non-inline @allowExperimental implementation that uses an experimental compiler/reflection API, without leaking that requirement to downstream users.

The scope is intentionally conservative rather than a general replacement for scalacOptions += "-experimental". Public inline permission owners, experimental signatures/types, constructors, and several other placements remain unsupported.

0.1.0 is available from Maven Central and the release is at Github.

Feedback on the semantics, implementation approach, and useful real-world cases would be very welcome.

Cross-posted at https://users.scala-lang.org/t/allow-experimental-0-1-0-implementation-scoped-access-to-scala-3-experimental-apis/12385


r/scala 1d ago

Difference between trait, class, case class and object

Upvotes

So I'm pretty new to scala and FP, into it for like a month, and I still don't get the difference between trait, class, case class and object, when I have to use one instead of another which is the strength of each one


r/scala 1d ago

This week in #Scala (Sep 7, 2026)

Thumbnail thisweekinscala.substack.com
Upvotes

r/scala 2d ago

Open-source revenue recognition & analytics for Stripe built with PlayFramework

Thumbnail github.com
Upvotes

I've just open-sourced a revenue recognition & analytics for Stripe called Book of Revenue.

The reason I shared here because it's built with Scala, PlayFramework, and Svelte. The app is bootstrapped with my own PlayFramework template: playfast

It aims to be hosted on a single VPS with multiple CPUs. And that's the main reason for using JVM; JVM-based languages can utilize multiple CPUs more easily and is more robust in terms of GC and thread tuning. These are particularly important when running on a single machine.

Other languages/runtimes are on single threads by default (e.g. JS, Ruby, Python) or too low level for business applications (e.g. Go, Rust). More importantly, I like Scala for its brevity and static typing, which makes it easier to model business use cases in a typed fashion (easier to refactor).

Well, just in case anyone might be interested: I'm offering a free consultation where deploy it for you for free (you pay the hosting cost tho; might be $6/month on OVHcloud) and help clean up your billing integration (so you can have better analytics). I'm an ex-Stripe who worked on analytics and revenue recognition at Stripe, so I know this space well.


r/scala 3d ago

RFC-5: test scheduling

Thumbnail eed3si9n.com
Upvotes

r/scala 4d ago

Scala 3.9 LTS released!

Thumbnail scala-lang.org
Upvotes

Scala 3.9.0 LTS has been released starting the second Scala LTS series as a successor of Scala 3.3 LTS.
This minor becomes a new baseline for the libraries and it's guaranteed to get updates for the next 3 years.

See the release blogpost to see what's new in 3.9, summary of core changes introduced since 3.3, and the migration guide.


r/scala 3d ago

My AI setup for Scala projects: Mistral + ThinkRail

Upvotes

Hi all,

I know it might seem a bit like an advertisement, and in fact it is to some extent, but I would also like this entry to be part of a larger conversation.

Coding with AI agents is not going away anytime soon (if ever), and even those of us who prefer our code to be 100 percent written by a human must acknowledge that AI helps, at least in some tasks. Questions about what to use show up here on r/scala regularly: what LLM, what AI harness, how to orchestrate, how to plug it into CI/CD, and so on.

So today, I would like to share my experience. My setup is a bit untraditional because I am currently not working on a large shared professional project but rather on a few smaller personal projects, where every line of Scala matters. These projects are intended to help me teach Scala to students as sources of code examples, and in the future they should all merge into one large video game project (because of course I want to write a video game one day).

  1. I use the Mistral family of LLMs. Devstral 2 for AI agents and Mistral Medium for research. In general, Mistral falls behind the best frontier models for coding, but in my experience it is on par with them for scientific and technical research, and it can be four to eight times cheaper in tokens. (I had Mistral generate a detailed comparison); but it is still just my experience, not a fact.)
  2. Recently, I have been using ThinkRail as my GUI for working with AI agents. This is the advertisement part: I am currently working with the ThinkRail team as a developer advocate, so I am not exactly objective here, but I honestly like it. It is minimalistic but still helps me understand what the agent is doing, review the changes, and run multiple agents simultaneously. There is also the idea that ThinkRail can automatically use the AI agent to update the documentation (a spec graph) as it makes changes, and the agent then uses this documentation in its coding tasks. I believe that in Scala projects, this means the code has guardrails on every side: the type system, unit tests, and now AI-readable documentation, so even with weaker (but cheaper) LLMs such as Mistral, the code quality is very good.
  3. Last month, I mainly coded my own lightweight implementation of the Actor model: 306 LOC of production code; 867 LOC of unit tests; 413 of Scaladoc comments; and 477 of AI-generated Markdown documentation. I would like to think I wrote more than half of it myself (excluding the Markdown), but that is probably not the case. Still, I know every line of code very well; I know it works and is tested, and the documentation may serve as a starting point for a lecture on the Actor model that I will give at a university in October. Here is the main class if you want to take a look.

So on the one hand, I am curious about your experiences coding Scala projects with AI agents. Let me know what you use, how you use it, and what the results are. On the other hand, I would like to invite you to try ThinkRail. I have written more about it on the blog, that is, not the part about the spec graph (it will be in the next blog entry) but about other main features and how to install and start using it. ThinkRail is currently in its early stages, and we are looking for feedback: What do you like? What do you not like? What do you think we should add? Let me know as well.


r/scala 4d ago

Introduction to Scala 3's Capture Checking and Separation Checking | tanishiking blog

Thumbnail tanishiking.github.io
Upvotes

r/scala 5d ago

Indigo, Tyrian, and Ultraviolet v0.30.0-M6 released

Thumbnail github.com
Upvotes

General update: Since I last posted here, we have in fact done five releases. πŸ˜…

https://github.com/PurpleKingdomGames/indigoengine/releases#release-v0.30.0-M6

Release '0.30.0-M1-PREVIEW' was a "warts and all" release after a serious reorganisation of our projects, and each subsequent release has been about stabilising the new arrangement.

The last two releases also had a large performance work component for our game engine, Indigo. We are busy producing a game and while the performance was ok on the systems we usually develop on, we happened to notice that it was terrible on other machines. On one machine in particular - the worst offender - the cumulative impact of the released engine improvements has raised the frame rate from about 20 frames per second to in excess of 200 FPS*.

The work continues...


r/scala 4d ago

BOB 2027 (Feb 26) Call for Contributions (Deadline Nov 2)

Upvotes

The BOB Call is out, send us your take on how to make the best use of Scala!
bobkonf.de/2027/cfc.html


r/scala 6d ago

Cats-Actors 2.2.0 is released

Upvotes

Cats-Actors is a Cats Effect native actor library: typed messages, functional state, supervision, and the familiar ! operator, all in F[_].

What is new in this release:

- ControlledTestKit, a new trait in the cats-actors-testkit module. It

provisions an ActorSystem[IO] inside Cats Effect's TestControl and ticks the

simulated clock for you, so scheduled work and timeouts resolve without real

waiting. A one hour receive timeout is now an ordinary unit test that finishes

in milliseconds.

- Receive timeouts, the supervisor restart window and the dead letter mailbox

idle check now read Clock[F].monotonic instead of System.currentTimeMillis, so

they all honour simulated time.

- New TestKit assertions, expectMsgTypeCountN and expectMsgTypeSingle, which

count messages of a type and do not depend on when they arrive relative to

the call.

- Breaking: ActorSystem.uptime is now F[Long] rather than Long.

Scala 2.13 and 3, on JVM, Scala.js and Scala Native.

```

resolvers += "jitpack" at "https://jitpack.io"

libraryDependencies += "com.github.cloudmark.cats-actors" %%% "cats-actors" % "2.2.0"

libraryDependencies += "com.github.cloudmark.cats-actors" %%% "cats-actors-testkit" % "2.2.0" % Test

```

Write up: https://cloudmark.github.io/Cats-Actors-Controlling-Time/

Repo: https://github.com/cloudmark/cats-actors

Feedback and issues welcome.


r/scala 6d ago

ldbc v0.8.0 is out πŸŽ‰

Upvotes

ldbc v0.8.0 released β€” SQL injection fix under NO_BACKSLASH_ESCAPES, JDBC 4.3 enquote APIs, and sbt 2 support!

TL;DR: Pure Scala MySQL connector running on JVM, Scala.js, and Scala Native fixes a SQL injection in client-side prepared statements under the NO_BACKSLASH_ESCAPES sql_mode, adds the JDBC 4.3 enquote APIs, and cross-builds its codegen plugin for sbt 1 and sbt 2. Upgrading is recommended if you use the ldbc connector.

ldbc v0.8.0 is out. This is primarily a security release for our Pure Scala MySQL connector that works across JVM, Scala.js, and Scala Native platforms.

The headline of this release is a SQL injection fix for sessions running with NO_BACKSLASH_ESCAPES, alongside JDBC 4.3 enquote APIs and sbt 2 support for ldbc-plugin.

https://github.com/takapi327/ldbc/releases/tag/v0.8.0

Major Changes

πŸ”’ SQL Injection under NO_BACKSLASH_ESCAPES

In 0.7.x and earlier, client-side prepared statements escaped string parameters with backslash escaping only (' β†’ \') and never consulted the server sql_mode.

In a session running with NO_BACKSLASH_ESCAPES, a backslash is an ordinary character. \' therefore does not neutralize the quote, and a string parameter can break out of its literal.

// 0.7.x and earlier, in a session with sql_mode = 'NO_BACKSLASH_ESCAPES'
ps.setString(1, "zzz' OR 1=1 -- ")
// Rendered SQL: WHERE t.name = 'zzz\' OR 1=1 -- '
//            => (name = 'zzz\') OR 1=1  ... always true

Who is affected: the ldbc connector with useServerPrepStmts = false (the default), against a server or session with NO_BACKSLASH_ESCAPES enabled. The jdbc connector is not affected.

The fix has three parts:

  • All escaping centralised in QueryRenderer β€” Parameter no longer exposes a SQL-text representation for strings, so a path that bypasses the sql_mode-aware logic cannot exist by construction
  • Escaping follows the sql_mode β€” quote-doubling (' β†’ '') when NO_BACKSLASH_ESCAPES is active, which is the only way to embed a quote such that it can never be consumed by a preceding backslash
  • The sql_mode is tracked for the life of the session β€” seeded from the handshake status flags and updated from every OK/EOF packet, so a SET SESSION sql_mode = ... issued after connecting is picked up too

No user code changes are required.

πŸ›‘οΈ JDBC 4.3 enquote APIs

Following MySQL Connector/J 9.7.0 (WL #17215), four methods have been added to ldbc.sql.Statement for safely quoting values and identifiers when you assemble SQL as a string.

for
  stmt <- conn.createStatement()
  a    <- stmt.enquoteLiteral("G'Day")              // 'G''Day'
  b    <- stmt.enquoteIdentifier("my table", false) // `my table`
  c    <- stmt.enquoteIdentifier("user", true)      // `user`
  d    <- stmt.enquoteNCharLiteral("Hello")         // N'Hello'
  e    <- stmt.isSimpleIdentifier("user_name")      // true
  f    <- stmt.isSimpleIdentifier("select")         // false (reserved word)
yield ()

isSimpleIdentifier follows the MySQL rules: [0-9a-zA-Z$_] or extended characters (U+0080 and above), not all digits, at most 64 characters, and not a reserved word. When ANSI_QUOTES is enabled, the identifier quote character becomes " instead of \`.

Available on both Statement and PreparedStatement, for the ldbc connector as well as the jdbc connector. The existing ident() helper remains the right tool inside the sql interpolator.

πŸ”§ sbt 2 Support for ldbc-plugin

ldbc-plugin is now cross-built for both sbt 1 and sbt 2 β€” artifacts for sbt 1 (Scala 2.12) and sbt 2 (Scala 3) are published side by side. The declaration is identical either way; sbt resolves the right artifact.

// project/plugins.sbt β€” the same for sbt 1.x and sbt 2.x
addSbtPlugin("io.github.takapi327" % "ldbc-plugin" % "0.8.0")

This was the goal set out for the 0.8.x series. Note that the ldbc build itself still runs on sbt 1, because sbt-typelevel has not been published for sbt 2 yet.

πŸͺ² insert Column-Order Fix

The tuple overload of insert now goes through the entity mapping defined by the table's * projection.

userTable.insert((1L, "Alice", Some(20)))

Previously the tuple was cast onto the column encoder directly, so values could be inserted into the wrong columns whenever the field order of the model differed from the column order of the * projection. The change makes the result correct, but if you have such a table it is worth re-running your tests after upgrading.

πŸ“¦ Dependency Updates

Library Before (0.7.x) After (0.8.0)
MySQL Connector/J 9.6.0 9.7.0
twiddles-core 0.10.0 1.1.0

⚠️ Breaking Changes

Parameter is now sealed and no longer exposes sql

ldbc.connector.data.Parameter is now a sealed trait with one case class per type, and def sql: String has been removed. This is part of the SQL injection fix β€” rendering a string into a SQL literal depends on the sql_mode, so that representation was removed to leave QueryRenderer as the only route.

Custom Parameter implementations are no longer possible; use the factory methods such as Parameter.string(...). Code that read param.sql should use param.toString, which is a sql_mode-independent literal for display and diagnostics only β€” it must not be used to assemble SQL for execution.

params removed from SQLException

SQLException and its subclasses lost the params: SortedMap[Int, Parameter] argument, as did ERRPacket.toException. As a result, the OpenTelemetry attributes error.parameter.$i.type / error.parameter.$i.value and the "and the arguments were" section of exception messages are no longer emitted.

This closes the paths by which bound values could leak through exception messages and telemetry. If you build dashboards or alerts on those attributes, you are affected.

Four abstract methods added to Statement

The four enquote methods are abstract members of ldbc.sql.Statement. No impact if you use the connectors ldbc provides, but implementing Statement or PreparedStatement yourself will now fail to compile.

What has not changed

0.7.x 0.8.0
Java versions 17, 21, 25
Scala versions 3.3.x / 3.8.x

Deprecated APIs

The APIs deprecated in 0.7.0 remain available in 0.8.0 and will be removed in a future release.

API Replacement
sc(identifier) ident(identifier)
Connection.fromSocketGroup(...) Connection.fromNetwork(...)
SSL.fromKeyStoreFile(java.nio.file.Path, ...) SSL.fromKeyStoreFile(fs2.io.file.Path, ...)

Why ldbc?

  • βœ… 100% Pure Scala β€” No JDBC dependency required
  • βœ… True cross-platform β€” Single codebase for JVM, JS, and Native
  • βœ… Fiber-native design β€” Built from the ground up for Cats Effect
  • βœ… ZIO Integration β€” Complete ZIO ecosystem support
  • βœ… First-class testability β€” Dedicated rollback and MUnit testing modules
  • βœ… Production-ready observability β€” OpenTelemetry Semantic Conventions compliant
  • βœ… Enterprise-ready β€” AWS Aurora IAM authentication support
  • βœ… AI/ML ready β€” MySQL VECTOR type support
  • βœ… Security-focused β€” sql_mode-aware parameter escaping and JDBC 4.3 enquote APIs
  • βœ… sbt 1 & sbt 2 β€” Codegen plugin cross-built for both
  • βœ… Migration-friendly β€” Easy upgrade path from 0.7.x

Links


r/scala 7d ago

Released windymelt/inertia-scala: Inertia.js binding for Scala 3 server

Thumbnail github.com
Upvotes

r/scala 7d ago

Code generation from OpenAPI specs

Upvotes

Quick question, how the heck you guys generate Scala code from OpenAPI specs?

I have been trying to generate client code for Meta business API using the Scala generators from openapi-generator but there is always a problem:

All of them, ignore the oneOf spec on openapi (that in theory should generate a sealed trait as the sum type implementation) and instead they generate a single case class with all fields required, nothing is optional.

What is the tool/strategy you guys use to generate API model from OpenAPI? At this point, i'm considering to generate the Scala code using an LLM instead of the classic deterministic approach.

Thanks πŸ™


r/scala 8d ago

Scheduling Quantum-Classical HPC Tasks in Scala

Thumbnail github.com
Upvotes

I wanted to share a project I built earlier this year. It is a distributed task scheduler for hybrid classical-quantum workflows in the quantum cloud. Throughout development I had various conversations with quantum hardware providers like IBM, who have shown interest in adopting bits and pieces of this into their production system, and thanks to generous support from Amazon, I am extending the scheduler to support direct FPGA-level coordination tailored to on-prem hybrid HPC clusters, as well as dynamic AWS resource allocation/release for long running quantum workflows. Developed fully in Scala using the Typelevel stack.

There is a 30 page accompanying paper coming (to be published, in review, a shorter version is up on quant-ph) for anyone interested in the details of the math behind this but an ultra simplified summary for those who aren't familiar with quantum: Essentially scheduling quantum tasks differ from scheduling classical tasks on a few fundamental points:

1) There are very few accessible quantum devices right now. This results in queue times that can often last up to 2-3 days. Due to various restrictions, today's quantum programs don't take more than 3-4 seconds. This means that sometimes you have to wait days to execute something that will take seconds.

2) Quantum programs are probabilistic by their nature. The probability of success not only depends on the device they are executed on but also when it is executed. A user program is mapped onto a quantum device's topology (not really same but think of it as like different memory registers) but each device component have vastly different error metrics for different functions that change throughout the day due to decay (negative) and recalibration (positive). Mapping a user program to the quantum device is NP-hard. Not only this, but there are a variety of different physical architectures for these devices, super conducting, neutral atoms, ion traps, photonic devices etc. While on the logical level, they look the same thanks to abstractions, the execution semantics are vastly different. One example is parallelism. While superconducting devices can execute multiple operations in parallel, ion traps are often sequential due to limited LIZ. Since qubits have limited life times, sequential execution and longer programs are exposed to larger error. Tl;dr is that a scheduler has to jointly optimize the makespan AND the fidelity (probability of success). Last but not least, because the underlying physics is different, all of these devices report different error metrics and expose different capabilities, which have to be unified by the scheduler.

3) Certain physical rules limit our scheduling capabilities. For example, entanglement and the no-cloning theorem prevents us from blindly cutting a program into smaller pieces and executing them individually. Same goes for task duplication. It is possible to cut the quantum programs however putting the results back together requires exponential classical post-processing work. So the scheduler needs to dynamically adjust when and how to deploy techniques like this based on the resource availability at the time. Balance the classical and quantum workloads.

Same goes for executing multiple tasks on a single Quantum Processing Unit. This is possible to do, but 1) because each component have different error characteristics, this increases the competition for high quality components 2) These programs can adversely interfere through effects such as measurement crosstalk and ruin each others' readings.

4) Quantum programs need to be generated by classical programs and results need to be read back into a classical program.

All of this becomes a thousand times more messy when you try to do distributed quantum computing. We do DQC through EPR pairs, a set of entangled qubits. Generating these is no easy process, and they have short lifetimes. This means that your pair needs to navigate the network, go into your QPU and execute within a time frame. This exposes a special type of synchronization barrier across nodes.

All this complexity is beyond what a programmer should be expected to endure, so I built qurator to heuristically make these complex decisions based on resources available. Currently has support for IBM, IonQ, IQM, AQT, QuEra, Rigetti and Pasqal quantum devices.


r/scala 8d ago

This week in #Scala (Aug 31, 2026)

Thumbnail thisweekinscala.substack.com
Upvotes

r/scala 9d ago

basamake: Minimalistic Scala LSP

Thumbnail github.com
Upvotes

Hello!

I have been working on new minimalistic LSP for scala/java.

Works with multiple BSP servers, lazily started, reports diagnostics.

Go to def works based on semanticdb, falls back to source parsing.
JAR/JDK indexes are too loaded lazily.

Still a bit barebones but works good enough for day to day work.

Why?

Metals/Intellij can be very memory heavy, slow-ish, instable, at least in my experience. This is an attempt to improve on that. And we dont need that many features, especially in these agentic days.

Disclaimer: this is my first time implementing an LSP. :)

Contributions and feedback welcome!


r/scala 10d ago

Shadcn Scalajs

Upvotes

I've been working on bringing shadcn-style components to Scala.js, and the first alpha of shadcn-scalajs is now available.

It's still early and there are many components and APIs I want to improve, but I'd love to get some feedback from people actually using Scala.js.

Demo: https://shadcn-scalajs.vercel.app

If you're building frontend apps with Scala.js, give it a try and let me know what you'd like to see next.


r/scala 11d ago

sbt 2.0.8 released

Thumbnail eed3si9n.com
Upvotes

r/scala 15d ago

Share your tips & tricks for LLM/AI efficiency with Scala, please

Upvotes

Unsure if this was already discussed here, but when working with Scala code, I'm wondering what tips & tricks people have for working with Scala or other JVM languages in general

For example, I can name the use of:

  • cellar for quickly querying the APIs of JVM libraries.
  • Metals MCP standalone (since v1.6.6); although, to be honest, I'm having a better time using IntelliJ IDEA's MCP server as it's been more reliable for me. LLM may need explicit instructions to perform IDE-like operations (e.g., renaming symbols).
  • Using sbt in client mode, via sbt --client; this being the default in sbt 2.x, although here an issue is that sbt can leak memory, and LLM may need instructions to kill it if it becomes unresponsive.
  • Activating available linting via sbt-tpolecat and WartRemover.

Can you share other Scala or JVM-specific tricks for minimizing costs or increasing performance?

Thanks,


r/scala 15d ago

This week in #Scala (Aug 24, 2026)

Thumbnail thisweekinscala.substack.com
Upvotes

r/scala 18d ago

sbt 1.13.0 and 2.0.7 are released with a CVE fix

Thumbnail eed3si9n.com
Upvotes

sbt 1.13.0 and 2.0.7 are released with a fix for remote code execution vulnerability via BSP over TCP. Builds with the default serverConnectionType are not affected.


r/scala 19d ago

Someone here is working on MCP servers / clients?

Upvotes

Are you working with MCP from a developer standpoint? Do you have some pain points, experiences?

Asking since some time ago I picked up chimp https://github.com/softwaremill/chimp a PoC of an MCP toolkit for Scala 3. It is gradually turning into a complete MCP SDK, supporting both server & client, both http & stdio, with integrations for Pekko, ZIO and ox in place. Main focus now is on conformance to the latest MCP protocol version.


r/scala 22d ago

This week in #Scala (Aug 17, 2026)

Thumbnail thisweekinscala.substack.com
Upvotes