<< All versions
Skill v1.0.1
currentAutomated scan100/100sickn33/agentic-awesome-skills/scala
+4 new
──Details
PublishedOctober 27, 2026 at 02:58 AM
Content Hashsha256:29b0ace442f72696...
Git SHAe8d346bcb691
Bump Typepatch
──Files
Files (1 file, 7.3 KB)
SKILL.md7.3 KBactive
SKILL.md · 310 lines · 7.3 KB
version: "1.0.1" name: scala description: "Language-specific super-code guidelines for scala." risk: safe source: community date_added: "2026-06-16"
Scala: Idiomatic Efficiency Reference
Apply only within the requested scope and current project conventions. Preserve behavior, ownership, error handling, accessibility and security; examples are independent fragments, not equivalent rewrites in every context. Verify language/library versions and run relevant checks. Required tests and user-facing progress/results take precedence over brevity rules. Do not install dependencies or delete files merely to follow these examples.
When to Use
- Use this skill when the task matches this description: Language-specific super-code guidelines for scala.
Table of Contents
- Collections & Functional Transforms
- Pattern Matching
- Case Classes & ADTs
- Option & Error Handling
- Implicits & Given/Using
- Concurrency
- Anti-patterns specific to Scala
1. Collections & Functional Transforms {#collections}
scala
// ❌ Imperative accumulationval result = new ArrayBuffer[String]()for (item <- items) {if (item.isActive) result += item.name.toUpperCase}// ✅val result = items.filter(_.isActive).map(_.name.toUpperCase)
scala
// ❌ Manual groupingval grouped = mutable.Map[String, List[Item]]()for (item <- items) {grouped(item.category) = grouped.getOrElse(item.category, Nil) :+ item}// ✅val grouped = items.groupBy(_.category)
scala
// ❌ Manual fold when sum/product worksvar total = 0for (o <- orders) total += o.amount// ✅val total = orders.map(_.amount).sum
scala
// ❌ Using head on potentially empty collectionval first = items.head // throws on empty// ✅val first = items.headOption // returns Option[T]
scala
// ❌ Chaining filter + head for findval found = items.filter(_.id == targetId).head// ✅val found = items.find(_.id == targetId) // returns Option[T]
Use `view` for lazy evaluation on large collections to avoid intermediate allocations.
2. Pattern Matching {#patterns}
scala
// ❌ if-else chain for type dispatchif (shape.isInstanceOf[Circle]) {val c = shape.asInstanceOf[Circle]c.radius * c.radius * Math.PI} else if (shape.isInstanceOf[Rect]) { ... }// ✅shape match {case Circle(r) => r * r * Math.PIcase Rect(w, h) => w * h}
scala
// ❌ Nested match with identical fallthroughx match {case 1 => "low"case 2 => "low"case 3 => "mid"case _ => "high"}// ✅x match {case 1 | 2 => "low"case 3 => "mid"case _ => "high"}
scala
// ❌ Match to extract then useval result = opt match {case Some(x) => x.toStringcase None => "N/A"}// ✅val result = opt.map(_.toString).getOrElse("N/A")// or:val result = opt.fold("N/A")(_.toString)
3. Case Classes & ADTs {#case-classes}
scala
// ❌ Regular class for dataclass User(val name: String, val age: Int) {override def equals(obj: Any): Boolean = ...override def hashCode(): Int = ...override def toString: String = ...}// ✅case class User(name: String, age: Int)
scala
// ❌ Sealed trait with unrelated case objectssealed trait Resultcase class Success(value: Int) extends Resultcase class Failure(error: String) extends Resultcase object Unknown extends Result // what does "Unknown" mean?// ✅ — each variant should carry the data it representssealed trait Result[+A]case class Success[A] (value: A) extends Result[A]case class Failure(error: Throwable) extends Result[Nothing]
scala
// ❌ (Scala 3) Verbose enumsealed trait Colorobject Color {case object Red extends Colorcase object Green extends Colorcase object Blue extends Color}// ✅ (Scala 3)enum Color { case Red, Green, Blue }
4. Option & Error Handling {#option}
scala
// ❌ Null checksval name: String = if (user != null) user.name else "Unknown"// ✅val name = Option(user).map(_.name).getOrElse("Unknown")
scala
// ❌ .get on Option (defeats the purpose)val name = userOpt.get // throws if None// ✅val name = userOpt.getOrElse("default")// or: userOpt.map(process).getOrElse(fallback)// or: userOpt match { case Some(u) => ... case None => ... }
scala
// ❌ Try with .getval result = Try(parse(input)).get // throws on failure// ✅val result = Try(parse(input)) match {case Success(v) => vcase Failure(e) => handleError(e)}// or: Try(parse(input)).getOrElse(default)// or: Try(parse(input)).toEither
scala
// ❌ Using exceptions for expected failuresdef findUser(id: String): User = {val user = db.query(id)if (user == null) throw new NotFoundException(id)user}// ✅ — Option for absence, Either for expected errorsdef findUser(id: String): Option[User] = Option(db.query(id)) // wraps a nullable result// or:def findUser(id: String): Either[AppError, User]
5. Implicits & Given/Using {#implicits}
scala
// ❌ (Scala 2) Implicit conversion that hides bugsimplicit def stringToInt(s: String): Int = s.toInt// ✅ — extension methods instead of implicit conversionsextension (s: String)def toIntSafe: Option[Int] = s.toIntOption
scala
// ❌ (Scala 2) Implicit parameter with broad typedef query(sql: String)(implicit conn: Connection): ResultSet// ✅ (Scala 3)def query(sql: String)(using conn: Connection): ResultSet
scala
// ❌ Importing implicits from everywhereimport com.lib.implicits._// ✅ — import only what you needimport com.lib.given// or specific: import com.lib.{given ExecutionContext}
6. Concurrency {#concurrency}
scala
// ❌ Thread.sleep in production codeThread.sleep(5000)// ✅ — use scheduler / timer abstractionimport scala.concurrent.duration._system.scheduler.scheduleOnce(5.seconds)(doWork())
scala
// ❌ Blocking inside FutureFuture {val result = blockingHttpCall() // starves thread poolprocess(result)}// ✅Future {val result = blocking { blockingHttpCall() }process(result)// or use a dedicated blocking ExecutionContext}
scala
// ❌ Awaiting futures in a loopfor (f <- futures) Await.result(f, Duration.Inf)// ✅val all = Future.sequence(futures)all.map(results => process(results))
Prefer `Future.sequence`/`Future.traverse` over manual await loops.
7. Anti-patterns specific to Scala {#antipatterns}
| Anti-pattern | Preferred | |
|---|---|---|
.get on Option/Try | .getOrElse / pattern match | |
null | Option | |
isInstanceOf + asInstanceOf | pattern matching | |
| Implicit conversions (Scala 2) | extension methods (Scala 3) | |
var for accumulation | val + functional transforms | |
return keyword | last expression is the return value | |
| Mutable collections by default | immutable collections | |
Any / AnyRef parameters | generics with type bounds | |
Deeply nested for comprehensions | break into named values | |
| Tuple instead of case class | case class for anything with semantic meaning | |
Await.result in production | compose with map/flatMap |
Limitations
- These are language-specific guidelines and do not cover overall architectural decisions.
- Over-compression might reduce readability; apply judgement.