A law is a group of two or more expressions which are required to be the same. The expressions will usually involve one or more typed holes ("inputs") which vary.
Some examples:
x.map(id) === x| #!/usr/bin/env bash | |
| # | |
| # Dependencies: | |
| # coursier ( on OSX: brew install --HEAD paulp/extras/coursier ) | |
| # zinc ( on OSX: brew install zinc ) | |
| # | |
| set -euo pipefail | |
| # You can compile code in different projects by overriding these, e.g. |
| #|@ | |
| This is a simple capabilities implementation | |
| that provides most of the properties described in | |
| [_Capability Myths Demolished_](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.3660). | |
| The only one missing (I think) is _A: No Designation Without Authority_. | |
| I need to read more about the capabilities that exist in other systems, | |
| but it seems like they wrap two things into the authority: | |
| the designator and the operation (read, write, etc.). | |
| However, our operations can match arbitrary patterns |
Recently, I found myself in need to precisely understand Scala's core typechecking rules. I was particulary interested in understanding rules responsible for typechecking signatures of members defined in classes (and all types derived from them). Scala Language Specification (SLS) contains definition of the rules but lacks any examples. The definition of the rules uses mutual recursion and nested switch-like constructs that make it hard to follow. I've written down examples together with explanation how specific set of rules (grouped thematically) is applied. These notes helped me gain confidence that I fully understand Scala's core typechecking algorithm.
Let's quote the Scala spec for As Seen From (ASF) rules numbered for an easier reference:
| type Timestamp = Long | |
| type Nanos = Long | |
| sealed trait Clock[A] | |
| final case class CurrentMillis extends Clock[Timestamp] | |
| final case class CurrentNanos extends Clock[Nanos] | |
| final case class EntryId(val asString: String) extends AnyVal | |
| sealed trait Audit[A] |
| Write a program that does what it’s supposed to do | |
| Write idiomatic code | |
| Debug a program that you wrote | |
| Debug a program someone else wrote | |
| Debug the interaction between a system you wrote and one you didn’t | |
| File a good bug report | |
| Modify a program you didn’t write | |
| Test a program you wrote | |
| Test a program you didn’t write | |
| Learn a new programming language |
| module Main where | |
| import Data.Maybe (fromMaybe) | |
| import Control.Applicative | |
| import Control.Arrow (first) | |
| import Control.Monad (ap) | |
| import Debug.Trace | |
Java 8 introduced lambdas to the Java language. While the design choices differ in many regards from Scala's functions, the underlying mechanics used to represent Java lambdas is flexible enough to be used as a target for the Scala compiler.
Java does not have canonical heirarchy of generic function types (ala scala.FunctionN), but instead allows a lambda to be used as a shorthand for an anonymous implementation of an Functional Interface
Here's an example of creating a predicate that closes over one value:
| // Define the general Arg type and companion object: | |
| import language.higherKinds, language.implicitConversions, language.existentials | |
| object Arg { implicit def toArg[Tc[_], T: Tc](t: T): Arg[T, Tc] = Arg(t, implicitly[Tc[T]]) } | |
| case class Arg[T, Tc[_]](value: T, typeclass: Tc[T]) | |
| // Say, for example we have a typeclass for getting the length of something, with a few instances | |
| trait Lengthable[T] { def length(t: T): Int } | |
| implicit val intLength = new Lengthable[Int] { def length(i: Int) = 1 } | |
| implicit val stringLength = new Lengthable[String] { def length(s: String) = s.length } |
| // PROBLEM STATEMENT | |
| // Let's build Proxy[T], an object that can capture calls to methods of an underlying object. | |
| // We want the proxy to be type-safe, i.e. we need to verify that the names of the calls | |
| // and the arguments that are passed to those calls are well-typed wrt the type of the proxee. | |
| object Test extends App { | |
| trait Foo { /* ... */ } | |
| val proxy: Proxy[Foo] = ??? | |
| proxy.bar() |