Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

The Death of Tagless Final

Slide 5

Slide 5 text

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 <- userOpt } yield user.name } } }

Slide 6

Slide 6 text

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] ... }

Slide 7

Slide 7 text

What is Tagless Final?

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

ର৅ݴޠΛઃܭ͢Δ 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] }

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

ΠϯλϓϦλ 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] } ܕ͕อଘ͞ΕΔ ධՁؔ਺

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

• ม਺ଋറΛϗετݴޠʹ·͔ͤΔ 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

Slide 20

Slide 20 text

• ม਺ଋറΛϗετݴޠʹ·͔ͤΔ 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

Slide 21

Slide 21 text

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))

Slide 22

Slide 22 text

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))

Slide 23

Slide 23 text

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))

Slide 24

Slide 24 text

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))

Slide 25

Slide 25 text

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))

Slide 26

Slide 26 text

ݴޠίϯϙʔωϯτΛ߹੒ 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

Slide 27

Slide 27 text

ݴޠίϯϙʔωϯτΛ߹੒ 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]

Slide 28

Slide 28 text

tagless-final ↓ typed-final

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

typed-final

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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]

Slide 42

Slide 42 text

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]

Slide 43

Slide 43 text

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]

Slide 44

Slide 44 text

Normalization by Evaluation • reification • ҙຯΦϒδΣΫτ͔Β߲ͷਖ਼نతදݱΛநग़͢Δ ૢ࡞ • reflection • ߲ͷਖ਼نతදݱ͔ΒҙຯΦϒδΣΫτ΁ͷม׵ • reifyͷٯؔ਺ • ਖ਼نԽ • [Per Martin-Löf. (1975); Danvy and Filinski. (1990); Dybjer and Filinski. (2000)][5,6,7] etc

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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] }

Slide 48

Slide 48 text

දݱܕͷม׵ 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

Slide 49

Slide 49 text

Reification and Reflection // AdditiveIdentity class AddIdent[FS <: AddMulSym](val sym: 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)) } } } ...


Slide 50

Slide 50 text

Reification and Reflection // AdditiveIdentity class AddIdent[FS <: AddMulSym](val sym: 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)) } } } ...


Slide 51

Slide 51 text

Reification and Reflection // AdditiveIdentity class AddIdent[FS <: AddMulSym](val sym: 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

Slide 52

Slide 52 text

GADTͱNbEͰܕอଘͭͭ͠ม׵ • GADTʹΑͬͯSymanticsͷܕʹै͏ class AddIdent[FS <: AddMulSym](val sym: 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) } } } ࠨ୯Ґݩ ӈ୯Ґݩ

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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Λ९कͯ͠࿈࠯͢Δ

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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 ίʔυੜ੒ثΛ༩͑Δ ͜ͱ΋Ͱ͖Δ

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

typed-final

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

·ͱΊ

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

ࢀߟจݙ • [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.