Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From Tagless-Final to Typed-Final: Program Transformations in the Final Style

dcube
September 16, 2019

From Tagless-Final to Typed-Final: Program Transformations in the Final Style

dcube

September 16, 2019
Tweet

Other Decks in Technology

Transcript

  1. From Tagless-Final
    to Typed-Final
    Program Transformations in the Final Style
    Kenichi Suzuki
    BizReach, Inc.
    [email protected]

    View Slide

  2. ໨࣍
    • ࣗݾ঺հ
    • tagless-finalͱ͸
    • typed-final styleͰϓϩάϥϜม׵

    View Slide

  3. ࣗݾ঺հ
    • ླ໦ ݈Ұ (Kenichi Suzuki)
    [email protected]
    • github.com/knih
    • QUEΛ (http://logic.cs.tsukuba.ac.jp/~ken/quel/)
    • ϓϩάϥϜݴޠ࿦ɺΫΤϦɺFunctional DDD
    • BizReach
    • yamory (https://yamory.io)

    View Slide

  4. The Death of Tagless Final

    View Slide

  5. Pure repository
    trait UserRepository[F[_]] {
    def findOneById(userId: UserId): F[Option[User]]
    }
    class UserService[F[_]](userRepository: UserRepository[F])
    (implicit ME: MonadError[F, Error]) {
    def getName(userId: String) = {
    val userOptF: F[Option[User]] = userRepository.findOneById(userId)
    Monad[F].map(userOptF) { userOpt =>
    for {
    user } yield user.name
    }
    }
    }

    View Slide

  6. Pure repository
    object UserRepositoryOnJdbc extends UserRepository[IO] {
    override def findOneById(userId: UserId): IO[Option[User]] = ???
    }
    object UserController extends ApplicationController {
    implicit val userRepository: UserRepository[IO] =
    UserRepositoryOnJdbc
    val service = new UserService[IO]
    ...
    }

    View Slide

  7. What is Tagless Final?

    View Slide

  8. tagless-finalͱ͸
    • ܕ҆શͳຒࠐΈDSLΛߏங͢Δख๏
    • ܕ෇͚͕ϝλݴޠ (ϗετݴޠ) ͷͦΕʹؼண͢Δ
    • ܕݕࠪΞϧΰϦζϜΛ࣮૷͠ͳͯ͘Α͍
    • HOAS (ߴ֊ந৅ߏจ) ͕࢖͑Δ
    • ϝλݴޠʹΑͬͯείʔϓ҆શੑ͕୲อ͞ΕΔ
    • ݴޠίϯϙʔωϯτͷ߹੒Λαϙʔτ
    • ύʔαΛ࡞Βͳͯ͘Α͍
    • ϗετݴޠͷΤίγεςϜ͕࢖͑Δ
    [J. Carette, O. Kiselyov and C.-c. Shan. (2009)] [1]

    View Slide

  9. ର৅ݴޠͱϝλݴޠ
    • ର৅ݴޠ (object language)
    • දݱ͍ͨ͠ݴޠɺDSL
    • ϝλݴޠ (meta language)
    • Scala, OCaml, Haskell౳ͷຒࠐΈઌϗετݴޠ

    View Slide

  10. Symantics
    Symantics
    ΠϯλϑΣʔε
    Symantics
    ΠϯλϓϦλ
    ߏจ(Syntax)
    ͱ ܕنଇ
    Symantics
    ΠϯλϓϦλ
    Symantics
    ΠϯλϓϦλ
    ҙຯ࿦(Semantics)

    View Slide

  11. ର৅ݴޠΛઃܭ͢Δ
    n is an integer
    n : Z
    AAAClXichVHLShxBFD22STSThxNdKLhpHAxZDXdMwCAIohLc+RyVODJUtzVjYXd1010zqE3/QD4gWWSlEIL4C9mFiD+QhZ8QsjSQTRa53dMQEklym646de49t05VOaGnYkN01Wf137p9Z2Dwbune/QcPh8qPhjfjoBO5su4GXhBtOyKWntKybpTx5HYYSeE7ntxyDhay/FZXRrEK9IY5CuWuL9patZQrDFPNMjX2WpFwE203jDw0ia1iW2hbaSPbMkpTTszYDV+YfcdJXqZpqVmuUJXysG+CWgEqKGIlKL9HA3sI4KIDHxIahrEHgZi/HdRACJnbRcJcxEjleYkUJdZ2uEpyhWD2gMc2r3YKVvM66xnnapd38fiPWGljkj7TGV3TJZ3TF/rx115J3iPzcsSz09PKsDn0amz9+39VPs8G+79U//Rs0MLz3Kti72HOZKdwe/ru8Zvr9Zm1yeQxndJX9n9CV/SRT6C739x3q3LtLbIHqP153TfB5lS19rQ6tfqsMjdfPMUgxjGBJ3zf05jDElZQ531f4wM+4cIatWatRetFr9TqKzQj+C2s5Z/yAZyG
    e1 : Z e2 : Z
    e1 + e2 : Z
    AAACqHichVHLSiNBFD326IwTdczoRnDTGJRBIVTHgZGsRDcu4yPGR6Sp7lRiY7/srgScJj/gD7hw5YCI+Blu3LkamHyCuHRgNi683WlQR9RbVNWtU+fcOlVl+LYVSsY6PcqH3r6Pn/o/ZwYGh74MZ7+OrIdeMzBF2fRsL9gweChsyxVlaUlbbPiB4I5hi4qxtxjvV1oiCC3PXZMHvthxeMO16pbJJUF6drFaqwfcjISuqUW16nC5axjRVlut7u83eU0VeqH4iLZj3kyMPaG29WyO5VkS6stES5Mc0ih52TNUUYMHE004EHAhKbfBEVLbhgYGn7AdRIQFlFnJvkAbGdI2iSWIwQndo7FBq+0UdWkd1wwTtUmn2NQDUqqYZL/ZObtjV+yC3bD7V2tFSY3YywHNRlcrfH34cGz137sqh2aJ3UfVm54l6phLvFrk3U+Q+BZmV9/6eXS3WlyZjKbYL3ZL/k9Yh13SDdzWX/N0WawcI0MfoP3/3C+T9UJem80Xlr/n5hfSr+jHOCbwjd77B+axhBLKdO45rvEHHWVaKSkVZbNLVXpSzSiehWI8AA4Yo7E=
    e ::= n
    | e + e
    AAACinichVFNSxtBGH5ctU1XrVEvBS9DQ6SghEksqAkF0R48JmpUcCXsrqMO2S92N4EY/AP2B/TQk4KI9ORVj176Bzz4E8SjghcPvrtZECvqu+zM8z7zPu88M2N4lgxCzq+6lO6e3g8fU5/Uvv6Bz4PpoeGVwG34pqiaruX6a4YeCEs6ohrK0BJrni9027DEqlGfj9ZXm8IPpOsshy1PbNj6tiO3pKmHRNXSWcGKxR9sTCs5TNNUxphmy80o1yYEG48GVVVr6QzP8TjYS5BPQAZJlN30MTRswoWJBmwIOAgJW9AR0LeOPDg84jbQJs4nJON1gT2opG1QlaAKndg6jduUrSesQ3nUM4jVJu1i0e+TkiHLL/kJv+X/+F9+zR9e7dWOe0ReWjQbHa3waoP7X5bu31XZNIfYeVK96TnEFqZjr5K8ezETncLs6Ju7v2+XiovZ9hg/5Dfk/4Bf8Qs6gdO8M48qYvEPogfI/3/dL8FKIZefzBUq3zOzc8lTpDCKr/hG9z2FWSygjCrt+wunOMO50q8UlBml1ClVuhLNCJ6F8vMRh1OStw==
    ߏจ (syntax) ܕ෇͚نଇ (typing rules)
    දݱ͍ͨ͠ର৅ݴޠ
    Symantics
    trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }

    View Slide

  12. trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }
    ର৅ݴޠΛઃܭ͢Δ
    n is an integer
    n : Z
    AAAClXichVHLShxBFD22STSThxNdKLhpHAxZDXdMwCAIohLc+RyVODJUtzVjYXd1010zqE3/QD4gWWSlEIL4C9mFiD+QhZ8QsjSQTRa53dMQEklym646de49t05VOaGnYkN01Wf137p9Z2Dwbune/QcPh8qPhjfjoBO5su4GXhBtOyKWntKybpTx5HYYSeE7ntxyDhay/FZXRrEK9IY5CuWuL9patZQrDFPNMjX2WpFwE203jDw0ia1iW2hbaSPbMkpTTszYDV+YfcdJXqZpqVmuUJXysG+CWgEqKGIlKL9HA3sI4KIDHxIahrEHgZi/HdRACJnbRcJcxEjleYkUJdZ2uEpyhWD2gMc2r3YKVvM66xnnapd38fiPWGljkj7TGV3TJZ3TF/rx115J3iPzcsSz09PKsDn0amz9+39VPs8G+79U//Rs0MLz3Kti72HOZKdwe/ru8Zvr9Zm1yeQxndJX9n9CV/SRT6C739x3q3LtLbIHqP153TfB5lS19rQ6tfqsMjdfPMUgxjGBJ3zf05jDElZQ531f4wM+4cIatWatRetFr9TqKzQj+C2s5Z/yAZyG
    e1 : Z e2 : Z
    e1 + e2 : Z
    AAACqHichVHLSiNBFD326IwTdczoRnDTGJRBIVTHgZGsRDcu4yPGR6Sp7lRiY7/srgScJj/gD7hw5YCI+Blu3LkamHyCuHRgNi683WlQR9RbVNWtU+fcOlVl+LYVSsY6PcqH3r6Pn/o/ZwYGh74MZ7+OrIdeMzBF2fRsL9gweChsyxVlaUlbbPiB4I5hi4qxtxjvV1oiCC3PXZMHvthxeMO16pbJJUF6drFaqwfcjISuqUW16nC5axjRVlut7u83eU0VeqH4iLZj3kyMPaG29WyO5VkS6stES5Mc0ih52TNUUYMHE004EHAhKbfBEVLbhgYGn7AdRIQFlFnJvkAbGdI2iSWIwQndo7FBq+0UdWkd1wwTtUmn2NQDUqqYZL/ZObtjV+yC3bD7V2tFSY3YywHNRlcrfH34cGz137sqh2aJ3UfVm54l6phLvFrk3U+Q+BZmV9/6eXS3WlyZjKbYL3ZL/k9Yh13SDdzWX/N0WawcI0MfoP3/3C+T9UJem80Xlr/n5hfSr+jHOCbwjd77B+axhBLKdO45rvEHHWVaKSkVZbNLVXpSzSiehWI8AA4Yo7E=
    e ::= n
    | e + e
    AAACinichVFNSxtBGH5ctU1XrVEvBS9DQ6SghEksqAkF0R48JmpUcCXsrqMO2S92N4EY/AP2B/TQk4KI9ORVj176Bzz4E8SjghcPvrtZECvqu+zM8z7zPu88M2N4lgxCzq+6lO6e3g8fU5/Uvv6Bz4PpoeGVwG34pqiaruX6a4YeCEs6ohrK0BJrni9027DEqlGfj9ZXm8IPpOsshy1PbNj6tiO3pKmHRNXSWcGKxR9sTCs5TNNUxphmy80o1yYEG48GVVVr6QzP8TjYS5BPQAZJlN30MTRswoWJBmwIOAgJW9AR0LeOPDg84jbQJs4nJON1gT2opG1QlaAKndg6jduUrSesQ3nUM4jVJu1i0e+TkiHLL/kJv+X/+F9+zR9e7dWOe0ReWjQbHa3waoP7X5bu31XZNIfYeVK96TnEFqZjr5K8ezETncLs6Ju7v2+XiovZ9hg/5Dfk/4Bf8Qs6gdO8M48qYvEPogfI/3/dL8FKIZefzBUq3zOzc8lTpDCKr/hG9z2FWSygjCrt+wunOMO50q8UlBml1ClVuhLNCJ6F8vMRh1OStw==
    ߏจ (syntax) ܕ෇͚نଇ (typing rules)
    දݱ͍ͨ͠ର৅ݴޠ
    Symantics

    View Slide

  13. trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }
    ର৅ݴޠΛઃܭ͢Δ
    n is an integer
    n : Z
    AAAClXichVHLShxBFD22STSThxNdKLhpHAxZDXdMwCAIohLc+RyVODJUtzVjYXd1010zqE3/QD4gWWSlEIL4C9mFiD+QhZ8QsjSQTRa53dMQEklym646de49t05VOaGnYkN01Wf137p9Z2Dwbune/QcPh8qPhjfjoBO5su4GXhBtOyKWntKybpTx5HYYSeE7ntxyDhay/FZXRrEK9IY5CuWuL9patZQrDFPNMjX2WpFwE203jDw0ia1iW2hbaSPbMkpTTszYDV+YfcdJXqZpqVmuUJXysG+CWgEqKGIlKL9HA3sI4KIDHxIahrEHgZi/HdRACJnbRcJcxEjleYkUJdZ2uEpyhWD2gMc2r3YKVvM66xnnapd38fiPWGljkj7TGV3TJZ3TF/rx115J3iPzcsSz09PKsDn0amz9+39VPs8G+79U//Rs0MLz3Kti72HOZKdwe/ru8Zvr9Zm1yeQxndJX9n9CV/SRT6C739x3q3LtLbIHqP153TfB5lS19rQ6tfqsMjdfPMUgxjGBJ3zf05jDElZQ531f4wM+4cIatWatRetFr9TqKzQj+C2s5Z/yAZyG
    e1 : Z e2 : Z
    e1 + e2 : Z
    AAACqHichVHLSiNBFD326IwTdczoRnDTGJRBIVTHgZGsRDcu4yPGR6Sp7lRiY7/srgScJj/gD7hw5YCI+Blu3LkamHyCuHRgNi683WlQR9RbVNWtU+fcOlVl+LYVSsY6PcqH3r6Pn/o/ZwYGh74MZ7+OrIdeMzBF2fRsL9gweChsyxVlaUlbbPiB4I5hi4qxtxjvV1oiCC3PXZMHvthxeMO16pbJJUF6drFaqwfcjISuqUW16nC5axjRVlut7u83eU0VeqH4iLZj3kyMPaG29WyO5VkS6stES5Mc0ih52TNUUYMHE004EHAhKbfBEVLbhgYGn7AdRIQFlFnJvkAbGdI2iSWIwQndo7FBq+0UdWkd1wwTtUmn2NQDUqqYZL/ZObtjV+yC3bD7V2tFSY3YywHNRlcrfH34cGz137sqh2aJ3UfVm54l6phLvFrk3U+Q+BZmV9/6eXS3WlyZjKbYL3ZL/k9Yh13SDdzWX/N0WawcI0MfoP3/3C+T9UJem80Xlr/n5hfSr+jHOCbwjd77B+axhBLKdO45rvEHHWVaKSkVZbNLVXpSzSiehWI8AA4Yo7E=
    e ::= n
    | e + e
    AAACinichVFNSxtBGH5ctU1XrVEvBS9DQ6SghEksqAkF0R48JmpUcCXsrqMO2S92N4EY/AP2B/TQk4KI9ORVj176Bzz4E8SjghcPvrtZECvqu+zM8z7zPu88M2N4lgxCzq+6lO6e3g8fU5/Uvv6Bz4PpoeGVwG34pqiaruX6a4YeCEs6ohrK0BJrni9027DEqlGfj9ZXm8IPpOsshy1PbNj6tiO3pKmHRNXSWcGKxR9sTCs5TNNUxphmy80o1yYEG48GVVVr6QzP8TjYS5BPQAZJlN30MTRswoWJBmwIOAgJW9AR0LeOPDg84jbQJs4nJON1gT2opG1QlaAKndg6jduUrSesQ3nUM4jVJu1i0e+TkiHLL/kJv+X/+F9+zR9e7dWOe0ReWjQbHa3waoP7X5bu31XZNIfYeVK96TnEFqZjr5K8ezETncLs6Ju7v2+XiovZ9hg/5Dfk/4Bf8Qs6gdO8M48qYvEPogfI/3/dL8FKIZefzBUq3zOzc8lTpDCKr/hG9z2FWSygjCrt+wunOMO50q8UlBml1ClVuhLNCJ6F8vMRh1OStw==
    ߏจ (syntax) ܕ෇͚نଇ (typing rules)
    දݱ͍ͨ͠ର৅ݴޠ
    Symantics
    Repr

    View Slide

  14. Symantics
    • syntaxͱtyping rulesΛؔ਺ͷγάχνϟͰද͢
    • දݱܕ (representation type) Ͱܕ෇͚نଇΛ
    ද͢
    • ߴ֊ΧΠϯυΛ࢖͏
    • polymorphic lifting ͸࢖Θͳ͍
    • semantics Λؔ਺ͷ࣮૷Ͱද͢

    View Slide

  15. ϢʔβϓϩάϥϜ
    trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }
    class Program[S import sym._
    val ex1 = add(int(1), int(0))
    }
    ΠϯλϓϦλʢ࣮૷ʣʹ
    ґଘ͠ͳ͍Ϣʔβϓϩά
    ϥϜ͕هड़Ͱ͖Δ

    View Slide

  16. ΠϯλϓϦλ
    final case class R[A](unR: A) // type Id[A] = A
    object interp extends AddSym {
    type Repr[T] = R[T]
    def int(n: Int): R[Int] = R(n)
    def add(t1: R[Int], t2: R[Int]): R[Int] =
    R(t1.unR + t2.unR)
    }
    def eval[A](e: R[A]): A = e.unR
    trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }
    ܕ͕อଘ͞ΕΔ
    ධՁؔ਺

    View Slide

  17. ಈ͔͢
    object test {
    val evaluator = Run.interp
    val p1 = new Program(evaluator)
    def main(args: Array[String]) = {
    println("---------------------------------")
    println(evaluator.eval(p1.ex1)) // => 1
    }

    View Slide

  18. HOASͰλந৅Λѻ͏
    • HOAS (Higher-Order Abstract Syntax; ߴ֊ந৅ߏจ)
    • ม਺ଋറΛϗετݴޠͷλͰදݱ͢ΔςΫχοΫ
    • ม਺Λਖ਼֬ʹѻ͏ͷ͸ׂͱ໘౗
    • ม਺໊͕ඃΒͳ͍Α͏ʹ͢Δ
    • de Bruijn ΠϯσοΫεΛ࢖͏৔߹Ͱ΋ɺ୅ೖૢ࡞࣌ͷΠ
    ϯσοΫεͷγϑτܭࢉ͸ඞཁ
    • capture-avoiding substitution
    [Miller and Nadathur (1987); Pfenning and Elliott. (1988)][2,3]

    View Slide

  19. • ม਺ଋറΛϗετݴޠʹ·͔ͤΔ
    HOASͰλந৅Λѻ͏
    trait LamSym {

    type Repr[T]
    def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B]
    def app[A, B](e1: Repr[A => B], e2: Repr[A]): Repr[B]
    }
    [x : ⌧1]
    .
    .
    .
    e : ⌧2
    x.e : ⌧1
    ! ⌧2
    AAAC23ichVE7b9RAEB6bV3ACOaBBorE4B1Gd1gcS6KoIGso8uCTS7em09k2OVfa8lr22Eqyr6CLaKAUVSAghfgYNf4AiEn8AUQaJhoLxQyASBcbyzrffzDczuxvESqaGsSPLPnf+wsVLc5ed+YUrVxdb165vpDpLQuyHWulkKxApKhlh30ijcCtOUEwDhZvBzuMyvpljkkodPTV7MQ6nYhLJbRkKQ9SolfMAJzIqjAgyJZJZEc4cb7Db40ZkI3/ouZw7PB9rk5bIwzrQrXiPaypddi64opZj4e66HRd7bq0mp2vYnXkOx2j8u82o1WYdVpl7GvgNaENjK7r1DjiMQUMIGUwBIQJDWIGAlL4B+MAgJm4IBXEJIVnFEWbgkDajLKQMQewOrRPaDRo2on1ZM63UIXVR9CekdGGJfWbv2TH7xD6wr+znmbWKqkY5yx75oNZiPFrcv7n+47+qKXkDz/6o/jmzgW14WM0qafa4YspThLU+f354vN5bWyrusDfsG83/mh2xj3SCKP8evl3FtVfg0AP4J6/7NNjodvx7ne7q/fbyo+Yp5uAW3Ia7dN8PYBmewAr0qe8Xy7bmrQV7aL+w9+2XdaptNZob8JfZB78AP0qzGg==
    e1 : ⌧1
    ! ⌧2 e2 : ⌧1
    e1 e2 : ⌧2
    AAACqXichVFNSxtBGH5cW7WxamwvhV6WBosghNm0oKSXUHvwaLTRUFeW2ckkLm52193ZQAz5A/4BD55aKNL2Z3jx2IuH+A9Kjwq99NB3P6C0or7LzjzzvM/zzjszduA6kWJsNKaNP3g4MTn1qDD9eGZ2rjj/ZCvy41DIhvBdP2zaPJKu48mGcpQrm0Eoedd25ba9v5rkt3syjBzfe6/6gdzt8o7ntB3BFVFW8Z3ZaodcDKRl6FXdVDwmYCo/gxXdPDiIeUuXVqWaJYeJ1HyTELlmWLCKJVZmaeg3gZGDEvJY94unMNGCD4EYXUh4UIRdcET07cAAQ0DcLgbEhYScNC8xRIG8MakkKTix+zR2aLWTsx6tk5pR6ha0i0t/SE4dC+yCfWFX7Jx9Yz/Y71trDdIaSS99mu3MKwNr7ujZ5q97XV2aFfb+uu7sWaGNlbRXh3oPUiY5hcj8vcPjq83qxsLgJfvEflL/H9mIndEJvN61+FyXGydIHsD4/7pvgq1K2XhVrtRfl2pv86eYwnO8wCLd9zJqWMM6GrTvV3zHCJfaklbXmtqHTKqN5Z6n+Cc08QcZZKI2

    View Slide

  20. • ม਺ଋറΛϗετݴޠʹ·͔ͤΔ
    HOASͰλந৅Λѻ͏
    trait LamSym {

    type Repr[T]
    def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B]
    def app[A, B](e1: Repr[A => B], e2: Repr[A]): Repr[B]
    }
    [x : ⌧1]
    .
    .
    .
    e : ⌧2
    x.e : ⌧1
    ! ⌧2
    AAAC23ichVE7b9RAEB6bV3ACOaBBorE4B1Gd1gcS6KoIGso8uCTS7em09k2OVfa8lr22Eqyr6CLaKAUVSAghfgYNf4AiEn8AUQaJhoLxQyASBcbyzrffzDczuxvESqaGsSPLPnf+wsVLc5ed+YUrVxdb165vpDpLQuyHWulkKxApKhlh30ijcCtOUEwDhZvBzuMyvpljkkodPTV7MQ6nYhLJbRkKQ9SolfMAJzIqjAgyJZJZEc4cb7Db40ZkI3/ouZw7PB9rk5bIwzrQrXiPaypddi64opZj4e66HRd7bq0mp2vYnXkOx2j8u82o1WYdVpl7GvgNaENjK7r1DjiMQUMIGUwBIQJDWIGAlL4B+MAgJm4IBXEJIVnFEWbgkDajLKQMQewOrRPaDRo2on1ZM63UIXVR9CekdGGJfWbv2TH7xD6wr+znmbWKqkY5yx75oNZiPFrcv7n+47+qKXkDz/6o/jmzgW14WM0qafa4YspThLU+f354vN5bWyrusDfsG83/mh2xj3SCKP8evl3FtVfg0AP4J6/7NNjodvx7ne7q/fbyo+Yp5uAW3Ia7dN8PYBmewAr0qe8Xy7bmrQV7aL+w9+2XdaptNZob8JfZB78AP0qzGg==
    e1 : ⌧1
    ! ⌧2 e2 : ⌧1
    e1 e2 : ⌧2
    AAACqXichVFNSxtBGH5cW7WxamwvhV6WBosghNm0oKSXUHvwaLTRUFeW2ckkLm52193ZQAz5A/4BD55aKNL2Z3jx2IuH+A9Kjwq99NB3P6C0or7LzjzzvM/zzjszduA6kWJsNKaNP3g4MTn1qDD9eGZ2rjj/ZCvy41DIhvBdP2zaPJKu48mGcpQrm0Eoedd25ba9v5rkt3syjBzfe6/6gdzt8o7ntB3BFVFW8Z3ZaodcDKRl6FXdVDwmYCo/gxXdPDiIeUuXVqWaJYeJ1HyTELlmWLCKJVZmaeg3gZGDEvJY94unMNGCD4EYXUh4UIRdcET07cAAQ0DcLgbEhYScNC8xRIG8MakkKTix+zR2aLWTsx6tk5pR6ha0i0t/SE4dC+yCfWFX7Jx9Yz/Y71trDdIaSS99mu3MKwNr7ujZ5q97XV2aFfb+uu7sWaGNlbRXh3oPUiY5hcj8vcPjq83qxsLgJfvEflL/H9mIndEJvN61+FyXGydIHsD4/7pvgq1K2XhVrtRfl2pv86eYwnO8wCLd9zJqWMM6GrTvV3zHCJfaklbXmtqHTKqN5Z6n+Cc08QcZZKI2

    View Slide

  21. HOASͰλந৅Λѻ͏
    • ΠϯλϓϦλ͸ܕ߹ΘͤήʔϜ
    def lam[A, B](f: R[A] => R[B]): R[A => B] =
    R((x: A) => f(R(x)).unR)
    def app[A, B](e1: R[A => B], e2: R[A]): R[B] =
    R(e1.unR(e2.unR))

    View Slide

  22. HOASͰλந৅Λѻ͏
    • ΠϯλϓϦλ͸ܕ߹ΘͤήʔϜ
    def lam[A, B](f: R[A] => R[B]): R[A => B] =
    R((x: A) => f(R(x)).unR)
    def app[A, B](e1: R[A => B], e2: R[A]): R[B] =
    R(e1.unR(e2.unR))

    View Slide

  23. HOASͰλந৅Λѻ͏
    • ΠϯλϓϦλ͸ܕ߹ΘͤήʔϜ
    def lam[A, B](f: R[A] => R[B]): R[A => B] =
    R((x: A) => f(R(x)).unR)
    def app[A, B](e1: R[A => B], e2: R[A]): R[B] =
    R(e1.unR(e2.unR))

    View Slide

  24. HOASͰλந৅Λѻ͏
    • ΠϯλϓϦλ͸ܕ߹ΘͤήʔϜ
    def lam[A, B](f: R[A] => R[B]): R[A => B] =
    R((x: A) => f(R(x)).unR)
    def app[A, B](e1: R[A => B], e2: R[A]): R[B] =
    R(e1.unR(e2.unR))

    View Slide

  25. HOASͰλந৅Λѻ͏
    • ΠϯλϓϦλ͸ܕ߹ΘͤήʔϜ
    def lam[A, B](f: R[A] => R[B]): R[A => B] =
    R((x: A) => f(R(x)).unR)
    def app[A, B](e1: R[A => B], e2: R[A]): R[B] =
    R(e1.unR(e2.unR))

    View Slide

  26. ݴޠίϯϙʔωϯτΛ߹੒
    trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(e1: Repr[Int], e2: Repr[Int]): Repr[Int]
    }
    trait SymLam {
    type Repr[T]
    def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B]
    def app[A, B](e1: Repr[A => B], e2: Repr[A]): Repr[B]
    }
    trait Sym extends AddSym with SymLam

    View Slide

  27. ݴޠίϯϙʔωϯτΛ߹੒
    trait AddSym[Repr[_]] {
    def int(n: Int): Repr[Int]
    def add(e1: Repr[Int], e2: Repr[Int]): Repr[Int]
    }
    trait SymLam[Repr[_]] {
    def lam[A, B](f: Repr[A] => Repr[B]): Repr[A => B]
    def app[A, B](e1: Repr[A => B], e2: Repr[A]): Repr[B]
    }
    trait Sym[Repr[_]] extends AddSym[Repr] with SymLam[Repr]

    View Slide

  28. tagless-final

    typed-final

    View Slide

  29. ਁಁ͍ͯ͠ͳ͍ͷͰ΋͏Ұ౓

    View Slide

  30. typed-final

    View Slide

  31. ʢάάϥϏϦςΟΛߟ͍͑ͯͳ͔ͬͨʣ

    View Slide

  32. ϓϩάϥϜม׵
    • ୯Ґݩ
    • n + 0 = n ... ӈ୯Ґݩ
    • 0 + m = m ... ࠨ୯Ґݩ
    • tagless-final͸ؔ਺ʹΑͬͯݴޠΛߏ੒͢Δ
    • ؔ਺Ͱߏ੒͞ΕͨϓϩάϥϜΛͲͷΑ͏ʹม׵͢Δ͔
    val program: R[Int] = add(int(1), int(0))

    View Slide

  33. ϓϩάϥϜม׵
    • tagless-final typed-final ͸1ͭͷΠϯλϑΣʔ
    ε(symantics)ʹରͯ͠ෳ਺ͷ࣮૷(ΠϯλϓϦ
    λ)Λ࣋ͭ͜ͱ͕Ͱ͖Δ

    View Slide

  34. ϓϩάϥϜม׵
    Symantics
    ΠϯλϑΣʔε
    Symantics
    ΠϯλϓϦλ
    Symantics
    ΠϯλϓϦλ
    Symantics
    ΠϯλϓϦλ

    View Slide

  35. ϓϩάϥϜม׵
    Symantics
    ΠϯλϑΣʔε
    Symantics
    ΠϯλϓϦλ
    Symantics
    ΠϯλϓϦλ

    View Slide

  36. ϓϩάϥϜม׵
    Symantics
    ΠϯλϑΣʔε
    ධՁΠϯλϓϦλ
    ม׵ΠϯλϓϦλ

    View Slide

  37. ϓϩάϥϜม׵
    • ධՁثΠϯλϓϦλ͸ͦͷ··࢖͍͍ͨ
    • ม׵ϩδοΫͱධՁϩδοΫΛ෼཭͍ͨ͠
    • ͞Βʹม׵ޙʹධՁ͍ͨ͠
    • ܕ͸อଘ͍ͨ͠

    View Slide

  38. ϓϩάϥϜม׵
    Symantics
    ΠϯλϑΣʔε
    ධՁΠϯλϓϦλ
    ม׵ΠϯλϓϦλ

    View Slide

  39. ϓϩάϥϜม׵
    ධՁΠϯλϓϦλ

    View Slide

  40. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    mul(add(int(2),
    int(0)),int(1))
    ߲ ධՁ݁Ռ
    [Suzuki, Kiselyov and Yukiyoshi. (2016)][4]

    View Slide

  41. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    mul(int(2),in
    t(1))
    Mul(Int(2), Int(1))
    AddIdent(R)
    AddIdent

    ϑΝϯΫλ
    mul(add(int(2),
    int(0)),int(1))
    ߲ ධՁ݁Ռ
    [Suzuki, Kiselyov and Yukiyoshi. (2016)][4]

    View Slide

  42. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    mul(int(2),in
    t(1))
    Mul(Int(2), Int(1))
    AddIdent(R)
    reflect
    reify
    AddIdent

    ϑΝϯΫλ
    mul(add(int(2),
    int(0)),int(1))
    Ճ๏୯Ґݩنଇ
    ("%5
    ߲ ධՁ݁Ռ
    [Suzuki, Kiselyov and Yukiyoshi. (2016)][4]

    View Slide

  43. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    Int(2)
    AddIdent(R)
    reflect
    reify
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    ("%5
    ߲ ධՁ݁Ռ
    [Suzuki, Kiselyov and Yukiyoshi. (2016)][4]

    View Slide

  44. Normalization by Evaluation
    • reification
    • ҙຯΦϒδΣΫτ͔Β߲ͷਖ਼نతදݱΛநग़͢Δ
    ૢ࡞
    • reflection
    • ߲ͷਖ਼نతදݱ͔ΒҙຯΦϒδΣΫτ΁ͷม׵
    • reifyͷٯؔ਺
    • ਖ਼نԽ

    [Per Martin-Löf. (1975); Danvy and Filinski. (1990); Dybjer and Filinski. (2000)][5,6,7] etc

    View Slide

  45. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify

    View Slide

  46. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify
    ؍ଌ
    PCTFSWBUJPO

    View Slide

  47. GADT (Generalized Algebraic Data Types)
    • දݱܕΛGADTͰߏ੒ͨ͠ܕʹ͢Δ
    sealed trait Term[T]
    final case class Unknown[A](x: sym.Repr[A]) extends Term[A]
    final case class IntLit(e: Int) extends Term[Int]
    final case class Add(e1: Term[Int], e2: Term[Int]) extends Term[Int]
    type Repr[T] = Term[T]
    trait AddSym {
    type Repr[T]
    def int(n: Int): Repr[Int]
    def add(t1: Repr[Int], t2: Repr[Int]): Repr[Int]
    }

    View Slide

  48. දݱܕͷม׵
    trait RR {
    import cats.~>
    type From[_]
    type To[_] // Term
    def fwd: From ~> To // reflection
    def bwd: To ~> From // reification
    def map[A, B](f: From[A] => From[B]): To[A] => To[B] =
    (t: To[A]) => fwd(f(bwd(t)))
    def map2[A, B, C](f: (From[A], From[B]) => From[C]): (To[A],
    To[B]) => To[C] =
    (t1: To[A], t2: To[B]) => fwd(f(bwd(t1), bwd(t2)))
    }
    R.Repr
    AddIdent(R).Repr
    MulIdent(AddIdent(R))
    .Repr
    From To
    From To

    View Slide

  49. Reification and Reflection
    // AdditiveIdentity
    class AddIdent[FS sealed trait Term[T]
    final case class Unknown[A](x: sym.Repr[A]) extends Term[A]
    final case class IntLit(e: Int) extends Term[Int]
    final case class Add(e1: Term[Int], e2: Term[Int]) extends Term[Int]
    object AddRR extends RR {
    override type From[T] = sym.Repr[T]
    override type To[T] = Term[T]
    def fwd: From ~> To = new (From ~> To) {
    def apply[A](x: sym.Repr[A]): Term[A] = Unknown(x)
    }
    def bwd: To ~> From = new (To ~> From) {
    def apply[A](term: Term[A]): sym.Repr[A] = term match {
    case Unknown(x) => x
    case IntLit(n) => sym.int(n)
    case Add(e1, e2) => sym.add(bwd(e1), bwd(e2))
    }
    }
    }
    ...


    View Slide

  50. Reification and Reflection
    // AdditiveIdentity
    class AddIdent[FS sealed trait Term[T]
    final case class Unknown[A](x: sym.Repr[A]) extends Term[A]
    final case class IntLit(e: Int) extends Term[Int]
    final case class Add(e1: Term[Int], e2: Term[Int]) extends Term[Int]
    object AddRR extends RR {
    override type From[T] = sym.Repr[T]
    override type To[T] = Term[T]
    def fwd: From ~> To = new (From ~> To) {
    def apply[A](x: sym.Repr[A]): Term[A] = Unknown(x)
    }
    def bwd: To ~> From = new (To ~> From) {
    def apply[A](term: Term[A]): sym.Repr[A] = term match {
    case Unknown(x) => x
    case IntLit(n) => sym.int(n)
    case Add(e1, e2) => sym.add(bwd(e1), bwd(e2))
    }
    }
    }
    ...


    View Slide

  51. Reification and Reflection
    // AdditiveIdentity
    class AddIdent[FS sealed trait Term[T]
    final case class Unknown[A](x: sym.Repr[A]) extends Term[A]
    final case class IntLit(e: Int) extends Term[Int]
    final case class Add(e1: Term[Int], e2: Term[Int]) extends Term[Int]
    object AddRR extends RR {
    override type From[T] = sym.Repr[T]
    override type To[T] = Term[T]
    def fwd: From ~> To = new (From ~> To) {
    def apply[A](x: sym.Repr[A]): Term[A] = Unknown(x)
    }
    def bwd: To ~> From = new (To ~> From) {
    def apply[A](term: Term[A]): sym.Repr[A] = term match {
    case Unknown(x) => x
    case IntLit(n) => sym.int(n)
    case Add(e1, e2) => sym.add(bwd(e1), bwd(e2))
    }
    }
    }
    ...

    R.Repr
    AddIdent(R).Repr
    MulIdent(AddIdent(R))
    .Repr
    From To
    From To

    View Slide

  52. GADTͱNbEͰܕอଘͭͭ͠ม׵
    • GADTʹΑͬͯSymanticsͷܕʹै͏
    class AddIdent[FS ...
    val addIdentInterp = new GenericTrans(AddRR)(sym) {
    def add(t1: Term[Int], t2: Term[Int]): Term[Int] = (t1, t2) match {
    case (IntLit(0), _) => t2
    case (_, IntLit(0)) => t1
    case (_, _) => Add(t1, t2)
    }
    }
    }
    ࠨ୯Ґݩ
    ӈ୯Ґݩ

    View Slide

  53. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify
    ؍ଌ
    PCTFSWBUJPO

    View Slide

  54. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify
    ؍ଌ
    PCTFSWBUJPO

    ͦΕͧΕͷϞδϡʔϧ͸
    4ZNBOUJDTΛ९कͯ͠࿈࠯͢Δ

    View Slide

  55. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify
    ؍ଌ
    PCTFSWBUJPO

    View Slide

  56. typed-finalϓϩάϥϜม׵
    R(2)
    R
    ղऍ
    int(2)
    ߲ ධՁ݁Ռ
    Int(2)
    AddIdent(R)
    reflect
    AddIdent

    ϑΝϯΫλ
    add(int(2),
    int(0)
    Ճ๏୯Ґݩنଇ
    mul(add(int(2),
    int(0)),int(1))
    Add(Int(2),Int(0))
    MulIdent(AddIdent(R))
    ...
    ...
    ...
    MulIdent

    ϑΝϯΫλ
    ৐๏୯Ґݩنଇ
    reify
    reify
    ؍ଌ
    PCTFSWBUJPO

    ίʔυੜ੒ثΛ༩͑Δ
    ͜ͱ΋Ͱ͖Δ

    View Slide

  57. Finally, Tagless
    ҙ༁: ࠷ޙʹλά͕ͳ͚Ε͹͍͍ΑͶ

    View Slide

  58. typed-final

    View Slide

  59. [Suzuki, Kiselyov and Yukiyoshi. (2016)][4]

    View Slide

  60. ·ͱΊ

    View Slide

  61. ·ͱΊ
    • typed-final͸DSLΛߏங͢ΔΞϓϩʔν
    • දݱܕreprͰର৅֎ͷߏ੒ࢠ͕ೖΓࠐ·ͳ͍
    Α͏ʹ͢Δ
    • GADTͱNbEతΞϓϩʔνΛซ༻͢Δ͜ͱͰɺ
    ܕΛอଘ͠ͳ͕Βfinal styleͰϓϩάϥϜม׵
    • tagless-final͸typed-finalʹͳͬͨ

    View Slide

  62. ࢀߟจݙ
    • [1] Jacques Carette, Oleg Kiselyov, and Chung-chieh Shan. 2009. Finally tagless, partially evaluated: Tagless
    staged interpreters for simpler typed languages. J. Funct. Program. 19, 5 (September 2009), 509-543.
    • [2] Miller, Dale & Nadathur, Gopalan (1987) A logic programming approach to manipulating formulas and
    programs. In IEEE Symposium on Logic Programming, Seif Haridi (ed). Washington, DC: IEEE Comp. Society
    Press, pp. 379–388.
    • [3] Pfenning, Frank & Elliott, Conal (1988) Higher-order abstract syntax. In PLDI 88: Proceedings of the ACM
    Conference on Programming Language Design and Implementation. ACM SIGPLAN Notices, vol. 23(7).
    New York: ACM, pp. 199–208.
    • [4] Kenichi Suzuki, Oleg Kiselyov, and Yukiyoshi Kameyama. 2016. Finally, safely-extensible and efficient
    language-integrated query. PEPM '16. ACM, New York, NY, USA, 37-48.
    • [5] Per Martin-Löf. About models for intuitionistic type theories and the notion of definitional equality. In
    Proceedings of the Third Scandinavian Logic Symposium (1972), volume 82 of Studies in Logic and the
    Foundation of Mathematics, pages 81–109. North-Holland, 1975.
    • [6] Olivier Danvy and Andrzej Filinski. Abstracting control. In Mitchell Wand, editor, Proceedings of the 1990
    ACM Conference on Lisp and Functional Programming, pages 151–160, Nice, France, June 1990. ACM Press
    • [7] Peter Dybjer and Andrzej Filinski. Normalization and partial evaluation. In Gilles Barthe, Peter Dybjer,
    Luís Pinto, and João Saraiva, editors, Applied Semantics – Advanced Lectures, number 2395 in Lecture
    Notes in Computer Science, pages 137–192, Caminha, Portugal, September 2000. Springer-Verlag.

    View Slide