Skip to content

Instantly share code, notes, and snippets.

View nicolasstucki's full-sized avatar
🌴
On vacation

Nicolas Stucki nicolasstucki

🌴
On vacation
  • LAMP / EPFL
  • Switzerland
View GitHub Profile

Example implementation: safe type constraint =:=

In this example we will see how to reimplement =:= using phantom types and in the process fix a vulnerability that it has. It is a simplified version of TypeConstraint which also implements <:<.

=:= in Scala 2.x

Type constraints =:= gives an evidence that two generic types are in fact equal and provides a mechanism to safely cast one type to the other. In the following example we want to assign an x: X to an ys: Array[Y] where we don't know if it is possible (this will be known at call site). Therefore we use an implicit evidence ev: X =:= Y to know that they are equal and ev(x) to cast x form X to Y.

(The Scala Org aims to release Scala 3 by the end of fall 2020. We are about 15 employees (some of whom work part-time), spread in 4 organisations (+ active community members), focusing on finalising 52 essential projects in 6 months. As of today, project leads will publish the road-maps under the category “Scala 3 release projects” to share with you what is to be expected and hopefully get your advice & contributions as well. All the projects’ road-maps come after an extensive feedback gathering, rounds of discussion, and involvement of major stakeholders, we now need the community to help push this effort over the line. Your collaboration is highly appreciated, thank you in advance!)

We are starting to write the initial draft of the macro tutorial. Help improving text that has been written so far would be helpful at this point. Another extreamely valuable addition would be to update the [migration status][migration-status].

This tutorial will cover all that is needed to start writing macros. The first p

Pattern Matching

Huffman coding is a compression algorithm that can be used to compress lists of characters.

In a normal, uncompressed text, each character is represented by the same number of bits (usually eight). In Huffman coding, each character can have a bit representation of a different length, depending on how common a character is: the characters that appear often in a text are represented by a shorter bit sequence than those being used more rarely. Every huffman code defines the specific bit sequences used to represent each character.

A Huffman code can be represented by a binary tree whose leaves represent the characters that should be encoded.

This is an overview/discussion on the current problems with quotes and splices and a potential solution that would also make them fully compatible with TASTy reflect (not seal/unsleal).

Current state

In this section, we will have an overview of how quotations scopes work and interact with the low level tasty API.

We have four basic concepts

  • Expr[T]: Represents an expression of type T. It is a wrapper around the AST of the expression.
  • Type[T]: Represents the type T. It is a wrapper around the AST containing the type.
  • QuoteContext: Materialization of the current scope of expression. It also contains the tasty API.

Phantom types

Phantom types are designed to support compile time type evidences without any overhead costs to runtime. Phantom evidences are usually in the form of implicit arguments, which once resolved, can be erased by the compiler.

Because of these properties, phantom types are completely outside of the normal type lattice, and as such these phantom types do not inherit the semantics of Any.

object foo {
abstract sealed class num
final case class One() extends num
final case class Bit0(a: num) extends num
final case class Bit1(a: num) extends num
abstract sealed class char
final case class zero_char() extends char
final case class Char(a: num) extends char
**** pickled info of object opaquetypes
Names:
0: ASTs
1: <empty>
2: opaquetypes
3: opaquetypes[ModuleClass]
4: <init>
5: <init>[Signed Signature(List(),opaquetypes$)]
6: java
7: lang

Unused Parameters Spec

This spec assumes the existance of implicit funtion types.

The Unused Modifier

LocalModifier   ::= ‘unused’
```
def test(x: Object): Unit =
{
case val x117: Object = x
def case378(): Unit = throw new MatchError(x117)
def case379(): Unit =
if x117.isInstanceOf[Foo29] then
{
case val x118: Foo29 = x117.asInstanceOf[Foo29]
case val x119: Foo29 = Foo29.unapply(x118)
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big
dotty.tools.backend.jvm.DottyBackendInterface$$anon$10::toTypeKind (637 bytes) hot method too big