var isOpen: Boolean,...) { def open(): Unit def close(): Unit def temporaryClose(): Unit } temporaryClose は使ってよ さそう 呼び出すタイミングは状況による なぁ close()を呼び出すだけでよくな い? Uses temporaryClose() Uses both with if logic temporaryClose() Dev A Dev B Dev C そして、構造がルールを定義しなく なると、意味は失われ始める
var isOpen: Boolean,...) { def open(): Unit def close(): Unit def temporaryClose(): Unit } temporaryClose() を使う 両方を使い分ける temporaryClose()は無視 Dev A Dev B Dev C 使われ方がバラバラ 意味を守れない構造 if (isPreliminary) period.temporaryClose() if (isAudited) period.close() else period.temporaryClose() period.close()
丸善出版 (2014) Brooks, Fred P. (1986). “No Silver Bullet — Essence and Accident in Software Engineering”. Proceedings of the IFIP Tenth World Computing Conference: 1069–1076.
to find out what is at its core making it tick. Another way to think of it is about stripping away irrelevant details, or rather, stripping away details that are irrelevant to what we’re thinking about now. 抽象とは、ある状況を深く掘り下げ、物事の核心にある「それを動かしている 本質」を見つけ出すことです。別の言い方をすれば、今考えていることにとっ て重要でない詳細を取り除いていく、あるいは不要な詳細をそぎ落としてい くことです。 “ Cheng E. The Joy of Abstraction: An Exploration of Math, Category Theory, and Life. Cambridge University Press; 2022.
UI W eb Devices D B External Interfaces Martin, R. C. (2017). Clean Architecture: A Craftsman's Guide to Software Structure and Design. Prentice Hall. 依存方向
val exampleEval = new Example(EvalInterpreter) val result1 = exampleEval.program println(result1) // 3 // Writer example val exampleWriter = new Example(WriterInterpreter) val result2: Writer[Int] = exampleWriter.program println(s"Result: ${result2.value}") // 3 println("Logs:") result2.log.foreach(println) // Creating int: 1 // Creating int: 2 // Adding 1 and 2 } def program: sym.Repr[Int] = { val a = int(1) val b = int(2) add(a, b) } ユーザープログラムは同じ インタプリタ インタプリタ
B](source: Fusion[S], f: S => B) extends Fusion[B] case FlatMap[S, B](source: Fusion[S], f: S => Fusion[B]) extends Fusion[B] case Filter[S](source: Fusion[S], p: S => Boolean) extends Fusion[S] case Union(left: Fusion[A], right: Fusion[A]) extends Fusion[A] case Table[A](name: String) extends Fusion[List[A]] case Empty
= 0 private def nextAlias(): String = aliasCounter += 1 s"t$aliasCounter" def toSQL[A](ir: Fusion[A]): String = ir match case Fusion.Table(name) => s"SELECT * FROM $name" case Fusion.Map(src, f) => val alias = nextAlias() val srcQuery = toSQL(src) s"SELECT ${mapFunctionToSQL(f)} FROM ($srcQuery) AS $alias" (以下、省略)