- Developed at EPFL
- Scala 3
- Both Scala-3 and Scala-2 have stuff which are not in each other
- DOT (Dependent Object Types), a core calculus of depenedent path types, is the core of Scala 3
- dotty: name of scala 3 language while it was being developed ʳ
- Targets JVM
- Can use java libraries
- sbt: build tool
- Tasty file: Typed Abstract Syntax Tree
- https://docs.scala-lang.org/scala3/guides/tasty-overview.html
scalac -decompile foo.tasty
- Can write eDSLs in scala
Tuple2
is a class,Tuple
is a trait
General
- Comments: Like in Java
- Single line:
//
- Multi-line:
/* ... */
- Single line:
Type annotations
Apparently, explicit type annotations are discouraged??
Conventions
- Names use camelCase
- Acronyms considered normal words (eg: html instead of HTML)
https://docs.scala-lang.org/style/naming-conventions.html
Hello world
- 'main' function is marked as entry point with
@main
annotation String*
indicates variable number ofString
arguments
// Filename: hi.scala
def hi(args: String*): Unit =
@main println("Hello world!")
Compilation:
$ scalac --version
Scala compiler version 3.3.1 -- Copyright 2002-2023, LAMP/EPFL
# Generate class files
$ scalac hi.scala
$ ls
'hi$package$.class' 'hi$package.class' 'hi$package.tasty' hi.class hi.scala hi.tasty
# Run
$ scala hi
Hello world!
See:
- https://docs.scala-lang.org/scala3/book/taste-hello-world.html
- https://docs.scala-lang.org/scala3/book/methods-main-methods.html
- https://docs.scala-lang.org/tutorials/scala-for-java-programmers.html#running-hello-world
case class
- Useful for pattern matching
- When two case class values are compared, their structure is compared (not whether they are the same object, unlike I guess normal classes).
https://docs.scala-lang.org/tour/case-classes.html
Path-dependent type
Example from here:
case class Board(width: Int, height: Int) {
case class Coord(x: Int, y: Int) {
require(0 <= x && x <= width &&
0 <= y && y <= height)
}val occupied = scala.collection.mutable.Set[Coord]()
}
def eg(args: String*): Unit =
@main val b = Board(10, 20)
val c1 = b.Coord(3, 5)
occupied += c1 // Add new coordinate to set of occupied
b.// No error
val c2 = b.Coord(11, 20)
// Run-time error! Not compile-time... ??
Running this would give error:
$ scalac pathdeptype.scala; scala eg
java.lang.IllegalArgumentException: requirement failed
at scala.Predef$.require(Predef.scala:324)
at Board$Coord.<init>(pathdeptype.scala:5)
at Board$Coord$.apply(pathdeptype.scala:3)
at pathdeptype$package$.eg(pathdeptype.scala:17)
at eg.main(pathdeptype.scala:11)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at dotty.tools.runner.RichClassLoader$.run$extension$$anonfun$1(ScalaClassLoader.scala:36)
at dotty.tools.runner.ScalaClassLoader$.asContext(ScalaClassLoader.scala:80)
at dotty.tools.runner.RichClassLoader$.dotty$tools$runner$RichClassLoader$$$asContext$extension(ScalaClassLoader.scala:18)
at dotty.tools.runner.RichClassLoader$.run$extension(ScalaClassLoader.scala:36)
at dotty.tools.runner.CommonRunner.run(ObjectRunner.scala:23)
at dotty.tools.runner.CommonRunner.run$(ObjectRunner.scala:13)
at dotty.tools.runner.ObjectRunner$.run(ObjectRunner.scala:48)
at dotty.tools.runner.CommonRunner.runAndCatch(ObjectRunner.scala:30)
at dotty.tools.runner.CommonRunner.runAndCatch$(ObjectRunner.scala:13)
at dotty.tools.runner.ObjectRunner$.runAndCatch(ObjectRunner.scala:48)
at dotty.tools.MainGenericRunner$.run$1(MainGenericRunner.scala:215)
at dotty.tools.MainGenericRunner$.process(MainGenericRunner.scala:270)
at dotty.tools.MainGenericRunner$.main(MainGenericRunner.scala:281)
at dotty.tools.MainGenericRunner.main(MainGenericRunner.scala)
Type of Coord
depends on the Board
instance which instantiated the Coord
.
ie, Coord
type depends on Board
value.
The name is 'path-dependent type' because type depends 'selector path' through objects. ʳ
See:
- https://docs.scala-lang.org/scala3/book/types-dependent-function.html
- https://docs.scala-lang.org/scala3/reference/new-types/dependent-function-types.html
- https://stackoverflow.com/questions/12935731/any-reason-why-scala-does-not-explicitly-support-dependent-types
- https://dev.to/markehammons/a-quick-explanation-of-path-dependent-types-4pki
- https://www.baeldung.com/scala/path-dependent-types
match
.. case
Example from here:
val suffix = (age % 100) match
case 11 | 12 | 13 => "th"
case _ => (age % 10) match
case 1 => "st"
case 2 => "nd"
case 3 => "rd"
case _ => "th"
Predefs: require
, assert
, etc
Useful to represent invariants that is difficult to represent using types.
require
: use to check if caller has adhered to require conditions- If a
require
fails, pre-condition necessary to use a definition was not satisfied - Think of it as a 400 http bad request response
- If a
assert
: can be used to assert something a function should be doing.- If an assertion fails, function definition itself is wrong
- Think of it as a 500 http response
More: ensuring
, assume
, implicitly
See:
- https://www.scala-lang.org/api/current/scala/Predef$.html
- https://stackoverflow.com/questions/26140757/what-to-choose-between-require-and-assert-in-scala
- https://users.scala-lang.org/t/require-assume-and-ensuring/5552
More
<static>
:- For auto-generated code ??
- Not available for user
- Modifier indicating a class method is static
final
- Command line argument parsing:
scala.util.CommandLineParser
??
Packages: chisel
An HDL made as a scala eDSL.
Resources:
- A free book: http://www.imm.dtu.dk/~masca/chisel-book.pdf
General:
- As of Dec 2024, looks like chisel is using scala2, not scala3.
- scala-cli: 'a great "batteries included" way to use Chisel'
- For simple designs. ie, involves only 1 or a few source files.
- Complex designs => a build tool needed. Eg: sbt, mill
- Warning: It will download a jdk (and other libraries?) compatible with it if it can't find it already installed.
- https://www.chisel-lang.org/docs/installation
- https://scala-cli.virtuslab.org/install/
- https://github.com/yadavan88/ScalaCLI-Cheatsheet