Meta teaching with Scalameta

Zainab Ali

@_zainabali_

Zeno

Your colleague

 

Interested in functional programming

www.scala-exercises.org

What went wrong?

Exploring different ways

  • Explore other languages
  • Program programming
  • Understand understanding

Iterative Refinement

  • Take a core aspect
  • Try and solve it
  • Fail
  • Try again
  • Add another aspect
  • Repeat
def collapse(xs: List[Int]): Int = {
  xs match {
    case Nil => WRITE_YOUR_ANSWER
    case h :: t => WRITE_YOUR_ANSWER
  }
}
def collapse(xs: List[Int]): Int = WRITE_YOUR_ANSWER
def collapse(xs: List[Int], 
             b: String, 
             f: (Int, String) => String): String = WRITE_YOUR_ANSWER

Iterations

check

next

test

Tutorial

VSCode

Bloop

def collapse(xs: List[Int]): Int = {
  xs match {
    case Nil => 0
    case h :: t => h + collapse(t)
  }
}

Iterations

def collapse(xs: List[Int]): Int = xs.head + collapse(xs.tail)
def collapse(o: Option[String]): String = {
  o match {
    case None => WRITE_YOUR_ANSWER
    case Some(x) => WRITE_YOUR_ANSWER
  }
}
def collapse(xs: List[Int]): Int = {
  xs match {
    case Nil => WRITE_YOUR_ANSWER
    case h :: t => WRITE_YOUR_ANSWER
  }
}
def collapse(xs: List[Int]): Int = {
  xs match {
    case Nil => WRITE_YOUR_ANSWER
    case h :: t => WRITE_YOUR_ANSWER
  }
}

Multiply

Concatenate

Sum

def problem(inputType: String, 
            outputType: String,
            paramName: String,
            patterns: List[String]): String = {
            
  val cases = patterns
    .map(p => s"case $p => WRITE_YOUR_ANSWER")
    .mkString("\n")
  
  s"""
  def collapse($paramName: $inputType): $outputType = {
    $paramName match {
      $cases
    }
  }
  """
}
val optionProblem = 
  problem("Option[Int]", "Int", "o", List("None", "Some(x)"))
case class Type(name: String)

case class Pattern(value: String)

case class ParamName(value: String)

Validation

Algebraic Data Types

def validateType(name: String): Either[Error, Type] = 
  if (name.isEmpty) {
     Left("It's empty!")
  } else if (name.contains(" ")) {
     Left("It contains spaces")
  } ...

Scalameta

def problem(inputType: Type, 
            outputType: Type,
            paramName: Term.Name,
            patterns: List[Pat]): Tree = {
            
  val cases = patterns
    .map(p => p"case $p => WRITE_YOUR_ANSWER")
  
  q"""
  def collapse($paramName: $inputType): $outputType = {
    $paramName match {
      ..case $cases
    }
  }
  """
}
val optionProblem = 
  problem(t"Option[Int]", t"Int", q"o", List(q"None", p"Some(x)"))
def collapse(xs: List[Int]): Int = WRITE_YOUR_ANSWER

pattern matching

concrete types

functions

higher

kinded

types

partial functions

type parameters

implicits

dependent types

variance

Racket

Language subsets

  • Pure functions
  • Higher order functions
  • I/O

check

next

test

Tutorial

VSCode

Bloop

def bannedFeatures(answer: Tree, 
                   featureChecks: List[Tree => Boolean]): List[Tree] =
  answer.collect {
     case node if featureChecks.exists(check => check(node)) => node
  }

Scalameta

def partialFunctionCheck: Tree => Boolean = {
   case partial: Term.PartialFunction => true
   case _ => false
}

Contextual Errors

def newFeatures(code: Tree, 
                checks: List[Tree => Boolean]): List[Tree]  =
  code.collect {
     case node if checks.exists(check => check(node)) => 
       node
  }

Scalameta

Notional Machines

f(x) = x + 1
g(x) = 3 * f(x)
g(2)
= 3 * f(2)
3 * (2 + 1)
3 * 3
9

Substitution

foldRight(List(1, 2, 3), Nil)(Cons(_, _))
Cons(1, Cons(foldRight(List(2, 3), Nil)(Cons(_, _))))
Cons(1, Cons(2, Cons(3, foldRight(Nil, Nil)(Cons(_, _)))))
Cons(1, Cons(2, Cons(3, Nil)))

The Stepper

A Scala Stepper?

  • Meta tree
  • Function substitution
  • Evaluation

The different ways

  • Iterative refinement
  • Pattern recognition
  • Language subsets
  • Context specific errors
  • Syntax guides
  • Notional machines

Have more ideas

Bringing Scala to a Diverse Group of Students,

Noel Welsh / Elissavet Velli / Yifan Xing

Questions?

Made with Slides.com