==== Lectures ====
Lecture 5.1 - More Functions on Lists (13:04)
:::はListの結合。
++はListの要素をListへ追加。receiverがListだと:::と同じ結果になる。
Lecture 5.2 - Pairs and Tuples (10:45)
pairとは2要素のtuppleの事。
tuppleは_1, _2...でアクセスできるが、pattern matchingを使うのが一般的。
tuppleに対してもpattern matching出来る。
?? 複雑度が高くなってしまう??
Lecture 5.3 - Implicit Parameters (11:08)
型推論は関数の第一パラメータリストを使うので、型が分かっているものを置く。
?? View boundは使っていなかったが、使う方が一般的?
Lecture 5.4 - Higher-Order List Functions (14:53)
map, filter等の説明。
?? place holderを使っていなったのは分かりやすさのため?
Lecture 5.5 - Reduction of Lists (15:35)
reduceとfold。
foldは初期値(accumulator)を別途渡す。
reduceはリストの先頭が初期値になる。
place hold _ の説明もあった。
Lecture 5.6 - Reasoning About Concat (13:00)
structural induction(構造帰納法)
プログラムの正当性を証明するための1手法。
プログラムがある制約を満たすことを示す。
referential transparency(参照透過) であることが重要になる。
(xs ++ ys) ++ zs == xs ++ (ys ++ zs) の証明
xs.reverse.reverse = xs の証明
Lecture 5.7 - A Larger Equational Proof on Lists (9:53)
前のLectureの続き。動画の最後がちょっとだけ切れていた。
map (xs ++ ys) == (map xs) ++ (map ys) の証明
==== Assignments ====
今週はAssignmentsはないらしい。。。
==== Etc. ====
今週はLectureは約90分。Assignmentsがないので何とかなるか。。。
4/27の1週目の開始以降何のAnnounceも無いし、Forumにもinstructorが出てきていない感じがする。
Assignmentsも自動採点のみだし、4回目で枯れてきているので放置気味??
==== Log ====
2014/05/27 00:15 準備
2014/05/27 00:45 Lecture
2014/05/28 00:45 Lecture
2014年5月29日木曜日
2014年5月27日火曜日
Functional Programming Principles in Scala (Week 4: Types and Pattern Matching)
==== Lectures ====
Lecture 4.1 - Functions as Objects
関数リテラルもbuilt-in機能ではなくて、trait Function1等を実装したanonymous classのapply methodのabbreviation。
引数の数に合わせてFunction22まで存在する。
?? tupleも22個までだった様な気がするが、22に何か特別な意味がある??
def f は function value ではない。
eta expression
Lecture 4.2 - Objects Everywhere
pure object oriented language
全てがobject
booleanや整数も通常のclassで定義出来るところが新鮮だった。
宣言的なプログラミング。
そのtypeに関する制約を満たすものが求めたいtypeになる。
漸化式的、再帰的に定義すれば無限集合も扱える。
Lecture 4.3 - Subtyping and Generics
T >: L <: Uで TはLのsuperでUのsub typeに制限出来る。
Lecture 4.4 - Variance (Optional)
Liskov Substitution Principle - 代わりに使えるかどうかがポイント。
NilはList[Nothing]のobject。全てのList[]に代入出来るが、引数では型を指定しないと使えない。
Lecture 4.5 - Decomposition
通常のOOの機能では、parserを作るのはかなり煩雑。
isInstanceの様なdowncast的な操作を使わないと簡単にならない。
Lecture 4.6 - Pattern Matching
pattern matchingはfunctional program languageでは一般的。
constructor pattern が recursive に使えると言うのはとても強力。
実装としてはunapply() methodが呼ばれる。
Lecture 4.7 - Lists
Listはrecursive、Arrayはflat。
(a :: (b :: (c :: Nil)))のstructure
complexity(計算量)はsubstitution(置き換え)の回数で決まる。
==== Assignments ====
[Huffman Coding]
今回は一回目で満点の20/20獲得できた。
sbtのstyleCheckで"Cyclomatic complexity exceeds 10"がでて99/100になった。
複雑なpattern matchをやめて簡素化したら回避できた。
==== Etc. ====
今週はLectureの分量が多い。約2時間分ある。
何故か4.2と4.3の順番が逆に登録されていたが?
==== Log ====
2014/5/20 Assignments 01:00
2014/5/21 Assignments 03:30
2014/5/21 Assignments 02:00
2014/5/26 Lecture 01:00
2014/5/26 Lecture 01:00
Lecture 4.1 - Functions as Objects
関数リテラルもbuilt-in機能ではなくて、trait Function1等を実装したanonymous classのapply methodのabbreviation。
引数の数に合わせてFunction22まで存在する。
?? tupleも22個までだった様な気がするが、22に何か特別な意味がある??
def f は function value ではない。
eta expression
Lecture 4.2 - Objects Everywhere
pure object oriented language
全てがobject
booleanや整数も通常のclassで定義出来るところが新鮮だった。
宣言的なプログラミング。
そのtypeに関する制約を満たすものが求めたいtypeになる。
漸化式的、再帰的に定義すれば無限集合も扱える。
Lecture 4.3 - Subtyping and Generics
T >: L <: Uで TはLのsuperでUのsub typeに制限出来る。
Lecture 4.4 - Variance (Optional)
Liskov Substitution Principle - 代わりに使えるかどうかがポイント。
NilはList[Nothing]のobject。全てのList[]に代入出来るが、引数では型を指定しないと使えない。
Lecture 4.5 - Decomposition
通常のOOの機能では、parserを作るのはかなり煩雑。
isInstanceの様なdowncast的な操作を使わないと簡単にならない。
Lecture 4.6 - Pattern Matching
pattern matchingはfunctional program languageでは一般的。
constructor pattern が recursive に使えると言うのはとても強力。
実装としてはunapply() methodが呼ばれる。
Lecture 4.7 - Lists
Listはrecursive、Arrayはflat。
(a :: (b :: (c :: Nil)))のstructure
complexity(計算量)はsubstitution(置き換え)の回数で決まる。
==== Assignments ====
[Huffman Coding]
今回は一回目で満点の20/20獲得できた。
sbtのstyleCheckで"Cyclomatic complexity exceeds 10"がでて99/100になった。
複雑なpattern matchをやめて簡素化したら回避できた。
==== Etc. ====
今週はLectureの分量が多い。約2時間分ある。
何故か4.2と4.3の順番が逆に登録されていたが?
==== Log ====
2014/5/20 Assignments 01:00
2014/5/21 Assignments 03:30
2014/5/21 Assignments 02:00
2014/5/26 Lecture 01:00
2014/5/26 Lecture 01:00
2014年5月26日月曜日
Programming in Scala, First Edition: Chapter 20
20. Abstract Members
classやtraitのmemberは完全な定義がなければabstractになる。
abstractはsubclassで実装される事を意図している。
method, field(val, var), type がabstract memberになりえる。
javaはmethodのみだがscalaではより一般的に概念に拡張されている。
pre-initialized fields, lazy vals, path-dependent types, enumerationsも扱う。
20.1 A quick tour of abstract members
method, val, var typeがabstract memberになる。
trait Abstract {
type T
def transform(x: T): T
val initial: T
var current: T
}
subclassで実装する。
class Concrete extends Abstract {
type T = String
def transform(x: String) = x + x
val initial = "hi"
var current = initial
}
?? x: Stringは x: Tのままでも良いのでは? 文法上は可能。
20.2 Type members
type T のみで定義がない場合はabstract type
type memberの使用目的
より短い、分かりやすい名前にするため。
abstractにしてsubclassで定義させるため。この後のSectionで説明。
20.3 Abstract vals
何らかの固定値を使いたいが、具体的な値はsubclass毎に決めたい場合に使う。
名前と型のみ定義する。
val v: T
abstract defはvalでoverride可能。
trait TR { def f: String }
trait TR_ok extends TR { val f = "a" } // OK
abstract valはdefでoverride不可能。
trait TR { val f: String }
trait TR_ng extends TR { def f = "a" } // NG!!
valなら値は不変だが、defだと状況に応じて戻り値が変化する可能性があるから。
これも置き換え(substitution)可能かどうかと言う事。
valはdefの特殊な形(sub xxx的な発想)と考えることが出来る。
** 使う能力(covariant)、受け入れる能力(contravariant)
** 特殊化(covariant)、一般化(contravariant)
20.4 Abstract vars
何らかの可変値を使いたいが、初期値はsubclass毎に決めたい場合に使う。
名前と型のみ定義する。
var v: T
内部的にはgetterとsetterのmethodが定義されるのはabstractでも同じ。
def v: T
def v_=(x: T)
getterとsetterは実装のないabstract methodになる。
abstractの場合は内部的に値を保持するためのprivate varは定義されない。
内部的に値を保持するためのprivate varはsubclassで定義される。
20.5 Initializing abstract vals
traitではparameterを渡せるconstructorを持っていないのでabstractでパラメータ化する。
trait RationalTrait {
val numerArg: Int
val denomArg: Int
}
new RationalTrait {
val numerArg = expr1
val denomArg = expr2
}
traitに実装を定義してnewすると、anonymous classが生成されてnewされる。
** javaのinner classと同様。
new Rational(expr1, expr2)とほぼ同等だが、処理順序が違う。
classをnewした場合はRationalの初期化の前のexprは評価される。
traitをnewした場合はexprの評価はanonymous classの初期化の一部として行われる。
anonymous classの初期化はtraitの初期化の後に行われる。
traitの初期化でnumerArg、denomArgの値が使えない。
厳密には初期化前type Intのdefault valueの0になってしまう!!
Pre-initialized fields
new {
val numerArg = expr1
val denomArg = expr2
} with RationalTrait
object twoThirds extends {
val numerArg = 2
val denomArg = 3
} with RationalTrait
class RationalClass(n: Int, d: Int) extends {
val numerArg = n
val denomArg = d
} with RationalTrait { ... }
subclassのfieldの初期化をsuperclassの初期化前に行える。
named classやobjectについても使える。
初期化前のsuperclassについては参照出来ない。
thisはsubclassを定義している外側のclassのobjectが参照される。
?? 使用上の制約がtraitのsignatureからは読み取れないので分かり難い??
Lazy vals
lazy val x = expr
右辺の評価(初期化)を最初に使われた時のみに出来る。
defと違うのは最初の一回しか評価されない所。
object自体もlazy valの様に使用される最初に評価される。
defとby-name parameterは使用されるたびに評価される。
副作用と関係ない場合に使える。
副作用があると順番が把握しにくいので使いにくい。
命令型だと使いにくいと言う事。
関数型に向いている。処理の順序に依存しないから。
Lazy functional languages
遅延評価(lazy evaluation)で有名なのはHaskell。
20.6 Abstract types
abstract class A { type T; ... }
aliasの実体のないtype宣言がabstract typeとなる。
型の実体はsubclassで定義する。
abstract type Tはsuperclass内の他の部分でも使える。
20.7 Path-dependent types
class C { type T = Int }
val c new C
c.TはPath-dependent type。
Tはobject cの型メンバ。objectが異なればTも異なる。
class Outer { class Inner }
Outer#Innerで参照出来る。
class InnerをnewするにはOuterのインスタンス(object)が必要。
InnerからOuterのインスタンスを参照出来る。
Outer#Innerはnew出来ない。
Outerのインスタンス(object)を生成してPath-dependent type指定でnewする。
val o = new Outer; new o.Inner
class Innerも型なのでPath-dependent type指定になる。
20.8 Enumerations
scalaのenumrationsはstandard libraryのclass。
javaやC#等の他の言語ではbuilt-inの特別なsyntaxが必要。
Enumerationをextendsすれば定義出来る。
object Color extends Enumeration {
val Red, Green, Blue = Value
}
inner classにColor.Valueが定義される。
Red, Green, BlueのtypeはColor.Value
Color.Valueはpath-dependent type
object毎に違うtypeになる。
各値に名前をを結び付けることも出来る。
object Direction extends Enumeration {
val North = Value("North")
val East = Value("East")
val South = Value("South")
val West = Value("West")
}
foreach, map, flatMap, filterと一緒に使える。
scala> for (d <- Direction) print(d +" ")
North East South West
id methodで0始まりの番号が取れる。
scala> Direction.East.id
res5: Int = 1
idから値を取り出すことも可能。
scala> Direction(1)
res6: Direction.Value = East
更に詳しい内容は Scaladoc comments of class scala.Enumeration 参照。
20.9 Case study: Currencies
abstract typeはnewできない。他のtypeのsuper typeにもなれない。
factory methodを使って生成すればよい。
factory methodをabstractにして、subclassで実装する。
abstract typeを使えばconcrete typeが決まっていなくてもconcrete methodを定義出来る。
inner class Inner内で他のOuter内のInnerを指定するときは、Outer#Inner
別々のtypeを定義して不可能な演算をcompile時点で抑制することでbugを減らせる。
The crash of the Mars Climate Orbiter spacecraft on September 23, 1999
20.10 Conclusion
class設計時点で不明なmemberは全てabstract memberにすれば良い。
type systemが推論してくれる。
scalaではmethodだけではなくて、type, value, variable全てabstractに出来る。
classやtraitのmemberは完全な定義がなければabstractになる。
abstractはsubclassで実装される事を意図している。
method, field(val, var), type がabstract memberになりえる。
javaはmethodのみだがscalaではより一般的に概念に拡張されている。
pre-initialized fields, lazy vals, path-dependent types, enumerationsも扱う。
20.1 A quick tour of abstract members
method, val, var typeがabstract memberになる。
trait Abstract {
type T
def transform(x: T): T
val initial: T
var current: T
}
subclassで実装する。
class Concrete extends Abstract {
type T = String
def transform(x: String) = x + x
val initial = "hi"
var current = initial
}
?? x: Stringは x: Tのままでも良いのでは? 文法上は可能。
20.2 Type members
type T のみで定義がない場合はabstract type
type memberの使用目的
より短い、分かりやすい名前にするため。
abstractにしてsubclassで定義させるため。この後のSectionで説明。
20.3 Abstract vals
何らかの固定値を使いたいが、具体的な値はsubclass毎に決めたい場合に使う。
名前と型のみ定義する。
val v: T
abstract defはvalでoverride可能。
trait TR { def f: String }
trait TR_ok extends TR { val f = "a" } // OK
abstract valはdefでoverride不可能。
trait TR { val f: String }
trait TR_ng extends TR { def f = "a" } // NG!!
valなら値は不変だが、defだと状況に応じて戻り値が変化する可能性があるから。
これも置き換え(substitution)可能かどうかと言う事。
valはdefの特殊な形(sub xxx的な発想)と考えることが出来る。
** 使う能力(covariant)、受け入れる能力(contravariant)
** 特殊化(covariant)、一般化(contravariant)
20.4 Abstract vars
何らかの可変値を使いたいが、初期値はsubclass毎に決めたい場合に使う。
名前と型のみ定義する。
var v: T
内部的にはgetterとsetterのmethodが定義されるのはabstractでも同じ。
def v: T
def v_=(x: T)
getterとsetterは実装のないabstract methodになる。
abstractの場合は内部的に値を保持するためのprivate varは定義されない。
内部的に値を保持するためのprivate varはsubclassで定義される。
20.5 Initializing abstract vals
traitではparameterを渡せるconstructorを持っていないのでabstractでパラメータ化する。
trait RationalTrait {
val numerArg: Int
val denomArg: Int
}
new RationalTrait {
val numerArg = expr1
val denomArg = expr2
}
traitに実装を定義してnewすると、anonymous classが生成されてnewされる。
** javaのinner classと同様。
new Rational(expr1, expr2)とほぼ同等だが、処理順序が違う。
classをnewした場合はRationalの初期化の前のexprは評価される。
traitをnewした場合はexprの評価はanonymous classの初期化の一部として行われる。
anonymous classの初期化はtraitの初期化の後に行われる。
traitの初期化でnumerArg、denomArgの値が使えない。
厳密には初期化前type Intのdefault valueの0になってしまう!!
Pre-initialized fields
new {
val numerArg = expr1
val denomArg = expr2
} with RationalTrait
object twoThirds extends {
val numerArg = 2
val denomArg = 3
} with RationalTrait
class RationalClass(n: Int, d: Int) extends {
val numerArg = n
val denomArg = d
} with RationalTrait { ... }
subclassのfieldの初期化をsuperclassの初期化前に行える。
named classやobjectについても使える。
初期化前のsuperclassについては参照出来ない。
thisはsubclassを定義している外側のclassのobjectが参照される。
?? 使用上の制約がtraitのsignatureからは読み取れないので分かり難い??
Lazy vals
lazy val x = expr
右辺の評価(初期化)を最初に使われた時のみに出来る。
defと違うのは最初の一回しか評価されない所。
object自体もlazy valの様に使用される最初に評価される。
defとby-name parameterは使用されるたびに評価される。
副作用と関係ない場合に使える。
副作用があると順番が把握しにくいので使いにくい。
命令型だと使いにくいと言う事。
関数型に向いている。処理の順序に依存しないから。
Lazy functional languages
遅延評価(lazy evaluation)で有名なのはHaskell。
20.6 Abstract types
abstract class A { type T; ... }
aliasの実体のないtype宣言がabstract typeとなる。
型の実体はsubclassで定義する。
abstract type Tはsuperclass内の他の部分でも使える。
20.7 Path-dependent types
class C { type T = Int }
val c new C
c.TはPath-dependent type。
Tはobject cの型メンバ。objectが異なればTも異なる。
class Outer { class Inner }
Outer#Innerで参照出来る。
class InnerをnewするにはOuterのインスタンス(object)が必要。
InnerからOuterのインスタンスを参照出来る。
Outer#Innerはnew出来ない。
Outerのインスタンス(object)を生成してPath-dependent type指定でnewする。
val o = new Outer; new o.Inner
class Innerも型なのでPath-dependent type指定になる。
20.8 Enumerations
scalaのenumrationsはstandard libraryのclass。
javaやC#等の他の言語ではbuilt-inの特別なsyntaxが必要。
Enumerationをextendsすれば定義出来る。
object Color extends Enumeration {
val Red, Green, Blue = Value
}
inner classにColor.Valueが定義される。
Red, Green, BlueのtypeはColor.Value
Color.Valueはpath-dependent type
object毎に違うtypeになる。
各値に名前をを結び付けることも出来る。
object Direction extends Enumeration {
val North = Value("North")
val East = Value("East")
val South = Value("South")
val West = Value("West")
}
foreach, map, flatMap, filterと一緒に使える。
scala> for (d <- Direction) print(d +" ")
North East South West
id methodで0始まりの番号が取れる。
scala> Direction.East.id
res5: Int = 1
idから値を取り出すことも可能。
scala> Direction(1)
res6: Direction.Value = East
更に詳しい内容は Scaladoc comments of class scala.Enumeration 参照。
20.9 Case study: Currencies
abstract typeはnewできない。他のtypeのsuper typeにもなれない。
factory methodを使って生成すればよい。
factory methodをabstractにして、subclassで実装する。
abstract typeを使えばconcrete typeが決まっていなくてもconcrete methodを定義出来る。
inner class Inner内で他のOuter内のInnerを指定するときは、Outer#Inner
別々のtypeを定義して不可能な演算をcompile時点で抑制することでbugを減らせる。
The crash of the Mars Climate Orbiter spacecraft on September 23, 1999
20.10 Conclusion
class設計時点で不明なmemberは全てabstract memberにすれば良い。
type systemが推論してくれる。
scalaではmethodだけではなくて、type, value, variable全てabstractに出来る。
Programming in Scala, First Edition: Chapter 3
3. Next Steps in Scala
この章と前章でscalaで有用なスクリプトを書けるレベルの知識が身に付く。
実際に使わないと分からない。
Step 7. Parameterize arrays with types
インスタンス化する時はnewを使う。
型パラメータは[]で値パラメータは()でコンストラクタに渡す。
val greetStrings: Array[String] = new Array[String](3)
greetStringsは普遍だがgreetStrings(0)はArrayがmutableなので変更出来る。
一引数でレシーバが明示されている場合は.や()を省略できる。
(0).to(2) は 0 to 2 と書ける。
"Console println 10"とかける。
"println 10"はレシーバが明記されていないのでNG。
すべてがメソッドでオペレータではないので、オペレータの再定義は存在しない。
メソッドが再定義される。
1 + 1 は (1).+(1)のこと
どんなオブジェクトでも()を付けたたらapply()メソッドに変換される。
Array型のインスタンスであってもそれは同じ。
greetStrings(0)はgreetStrings(0).apply(0)に変換される。
scalaではArrayも普通のクラスで特別ではない。なので()でアクセスする。
代入もコンパイル時にupdate()メソッドに変換される。
scalaでは全てがメソッドを持ったオブジェクト。例外を覚える必要がない。
更にコンパイル時にJavaのbuiltinに変換されるので性能も悪くならない。
配列は下記で初期化できる。
val numNames = Array("zero", "one", "two")
実際は、
val numNames = Array.apply("zero", "one", "two")
これはArrayのcompanion objectとして定義されている。
companion objectはJavaのstaitc methodと似ている。
** 概念は統一的だが簡素な記法をsyntactic sugarとして用意している。
Step 8. Use lists
Array[A]は要素が型Aのmutableな配列
List[A]は要素が型Aのimmutableな配列
Listを変更しているように見えても、実際は新しいListが生み出されている。
関数型的にするにはimmutableにする必要がある。
参照透過になってシンプルで再利用性が高まる。
型システムによるエラーチェックが効果的に働くようになる。
:::が結合で::がcons
:で終わるメソッドは右記述子。他は通常の左記述子
?? Listには長くなると実行時間が掛かるからappendがない?? :::は良いの??
mutableリストでappendしてからtoListでimmutable化するとあるが。。。
空リストはNil
?? Nothingは型無しの意味??
Step 9. Use tuples
tupleはimmutable
別々の型を格納できる
val t: (Int, String) = (1, "hoge")
アクセスは._N
t._1
1始まり。
static tuplesは歴史的に1始まり。HaskellとかMLも。
t._Nの戻り値の型がNに依存して変わるのでNをパラメタとする単一のメソッドはNG。
?? これもオブジェクト? _1はメソッド?? なんか違う気もする??
?? tupleは最大22要素まで??
Step 10. Use sets and maps
scalaでは命令型と関数型両方をサポートするためにcollectionにmutable, immutable両方を用意している。
SetとMapはクラス階層の中で可変性を区別している。
Setはdefaultではimmutalbe
var jetSet = Set("a", "b")
jetSet += "c"
これは新しいSetを生み出してそれをjetSetに代入している。
jetSetに保存されている値を書き換えているのでvarの必要がある。
jetSet = JetSet + "c"と同じ意味。
?? コンパイラが変換している??
mutableのSetを使いたいときはimport等でmutableの型を指定する。
import scala.collections.mutalbe.set
val jetSet = Set("a", "b")
jetSet += "c"
これはSetの中身を書き換えている。新しく生み出していない。
jetSetが指しているものは同じなのでvalで大丈夫。
+=はメソッドでJetSet.+=("c")と同じ。
** Setは重複を許さないcollection
** Mapは連想配列、辞書
Setと同様にclass階層でmutablityを区別している。
defaultではimmutable
mutableを使うときはimport等でクラス階層を指定
import scala.collection.mutable.Map
val m = Map[Int, String]()
m += (1 -> "hoge")
1 -> "hoge"は(1).->("hoge")でtuple (1, "hoge")を返す。
これをm.+=の引数として渡すと追加される。
key, valueが別々の型でもOK
val m = Map(1 -> "a", "hoge" -> 2)
?? 型にはAnyやNothingもある??
Step 11. Learn to recognize the functional style
scalaでは関数型の書き方を推奨している。
関数型かどうか判断の一つはvarがない事。
varをなるべく使わないようにすれば関数型の書き方に近づける。
varを減らすことで、簡素で分かりやすくバグが少なく出来る。
関数型かどうか判断の一つは副作用がない事。
副作用は最小限にすべき。
副作用がある部分を分離すべき。
副作用がなくなればテストしやすくなる。
Assertを使った単体テストで十分になる。
varも副作用も悪ではない。それを使うことが適切な場合もある。
バランス感覚としては、
基本的にはval, immutable, no side effectで書く。
相応の理由がある時のみvar, immutable, side effectを使う。
** var, immutable, side effectを分散させずに少ない箇所に閉じ込めるのも大切。
Step 12. Read lines from a file
** Source.fromFile(filename).getLinesは2.8から改行はstripする様に変更されている。
ファイルの内容の読み方。
** scalaプログラムの読み方も学べる。
scala.io package, Source class, Iterator[String], standard error stream
Iteratorは一度実行すると消費されてしまうが、Listに変換すれば何回も使える。
Listにファイルから読み込むコストは1回だけ。
** stream型のプログラムより一括して読む込む分メモリを使いそう??
畳み込みreduceLeftを使ってループを変換してvarを消している。
** mapも使えると思うが、そこまでは行っていない。
** valでも同じ名前に別の値を再定義できる。定義内のスコープでは変更出来ない。
for (line <- Source.fromFile(args(0)).getLines) {
val numSpace = maxWidth- widthOfLength(line)
println(" " * numSpace + line.length + " | " + line)
}
?? ダイナミックスコープ? レキシカルスコープ?
?? valに関数リテラルを定義するのと、defの差はある??
Conclusion
これで小さいタスクを実行するためのスクリプトを書けるようになったはず。
** そんなに簡単では無い気がするが、リファレンス読みながら書ける?
** ちょっとしたscriptの実行にJVMの立ち上げなどもあるので実行時間が掛かる。
** 関数型スタイルでは結果から逆向きに必要な部品を作成する。
** TDD(test driven development)と相性が良さそう。
** 実際にやってみると関数型スタイルはコードの部分移動(refactor)が楽。
?? scalaの型推論はhaskellの推論より浅い?? compile時により束縛??
この章と前章でscalaで有用なスクリプトを書けるレベルの知識が身に付く。
実際に使わないと分からない。
Step 7. Parameterize arrays with types
インスタンス化する時はnewを使う。
型パラメータは[]で値パラメータは()でコンストラクタに渡す。
val greetStrings: Array[String] = new Array[String](3)
greetStringsは普遍だがgreetStrings(0)はArrayがmutableなので変更出来る。
一引数でレシーバが明示されている場合は.や()を省略できる。
(0).to(2) は 0 to 2 と書ける。
"Console println 10"とかける。
"println 10"はレシーバが明記されていないのでNG。
すべてがメソッドでオペレータではないので、オペレータの再定義は存在しない。
メソッドが再定義される。
1 + 1 は (1).+(1)のこと
どんなオブジェクトでも()を付けたたらapply()メソッドに変換される。
Array型のインスタンスであってもそれは同じ。
greetStrings(0)はgreetStrings(0).apply(0)に変換される。
scalaではArrayも普通のクラスで特別ではない。なので()でアクセスする。
代入もコンパイル時にupdate()メソッドに変換される。
scalaでは全てがメソッドを持ったオブジェクト。例外を覚える必要がない。
更にコンパイル時にJavaのbuiltinに変換されるので性能も悪くならない。
配列は下記で初期化できる。
val numNames = Array("zero", "one", "two")
実際は、
val numNames = Array.apply("zero", "one", "two")
これはArrayのcompanion objectとして定義されている。
companion objectはJavaのstaitc methodと似ている。
** 概念は統一的だが簡素な記法をsyntactic sugarとして用意している。
Step 8. Use lists
Array[A]は要素が型Aのmutableな配列
List[A]は要素が型Aのimmutableな配列
Listを変更しているように見えても、実際は新しいListが生み出されている。
関数型的にするにはimmutableにする必要がある。
参照透過になってシンプルで再利用性が高まる。
型システムによるエラーチェックが効果的に働くようになる。
:::が結合で::がcons
:で終わるメソッドは右記述子。他は通常の左記述子
?? Listには長くなると実行時間が掛かるからappendがない?? :::は良いの??
mutableリストでappendしてからtoListでimmutable化するとあるが。。。
空リストはNil
?? Nothingは型無しの意味??
Step 9. Use tuples
tupleはimmutable
別々の型を格納できる
val t: (Int, String) = (1, "hoge")
アクセスは._N
t._1
1始まり。
static tuplesは歴史的に1始まり。HaskellとかMLも。
t._Nの戻り値の型がNに依存して変わるのでNをパラメタとする単一のメソッドはNG。
?? これもオブジェクト? _1はメソッド?? なんか違う気もする??
?? tupleは最大22要素まで??
Step 10. Use sets and maps
scalaでは命令型と関数型両方をサポートするためにcollectionにmutable, immutable両方を用意している。
SetとMapはクラス階層の中で可変性を区別している。
Setはdefaultではimmutalbe
var jetSet = Set("a", "b")
jetSet += "c"
これは新しいSetを生み出してそれをjetSetに代入している。
jetSetに保存されている値を書き換えているのでvarの必要がある。
jetSet = JetSet + "c"と同じ意味。
?? コンパイラが変換している??
mutableのSetを使いたいときはimport等でmutableの型を指定する。
import scala.collections.mutalbe.set
val jetSet = Set("a", "b")
jetSet += "c"
これはSetの中身を書き換えている。新しく生み出していない。
jetSetが指しているものは同じなのでvalで大丈夫。
+=はメソッドでJetSet.+=("c")と同じ。
** Setは重複を許さないcollection
** Mapは連想配列、辞書
Setと同様にclass階層でmutablityを区別している。
defaultではimmutable
mutableを使うときはimport等でクラス階層を指定
import scala.collection.mutable.Map
val m = Map[Int, String]()
m += (1 -> "hoge")
1 -> "hoge"は(1).->("hoge")でtuple (1, "hoge")を返す。
これをm.+=の引数として渡すと追加される。
key, valueが別々の型でもOK
val m = Map(1 -> "a", "hoge" -> 2)
?? 型にはAnyやNothingもある??
Step 11. Learn to recognize the functional style
scalaでは関数型の書き方を推奨している。
関数型かどうか判断の一つはvarがない事。
varをなるべく使わないようにすれば関数型の書き方に近づける。
varを減らすことで、簡素で分かりやすくバグが少なく出来る。
関数型かどうか判断の一つは副作用がない事。
副作用は最小限にすべき。
副作用がある部分を分離すべき。
副作用がなくなればテストしやすくなる。
Assertを使った単体テストで十分になる。
varも副作用も悪ではない。それを使うことが適切な場合もある。
バランス感覚としては、
基本的にはval, immutable, no side effectで書く。
相応の理由がある時のみvar, immutable, side effectを使う。
** var, immutable, side effectを分散させずに少ない箇所に閉じ込めるのも大切。
Step 12. Read lines from a file
** Source.fromFile(filename).getLinesは2.8から改行はstripする様に変更されている。
ファイルの内容の読み方。
** scalaプログラムの読み方も学べる。
scala.io package, Source class, Iterator[String], standard error stream
Iteratorは一度実行すると消費されてしまうが、Listに変換すれば何回も使える。
Listにファイルから読み込むコストは1回だけ。
** stream型のプログラムより一括して読む込む分メモリを使いそう??
畳み込みreduceLeftを使ってループを変換してvarを消している。
** mapも使えると思うが、そこまでは行っていない。
** valでも同じ名前に別の値を再定義できる。定義内のスコープでは変更出来ない。
for (line <- Source.fromFile(args(0)).getLines) {
val numSpace = maxWidth- widthOfLength(line)
println(" " * numSpace + line.length + " | " + line)
}
?? ダイナミックスコープ? レキシカルスコープ?
?? valに関数リテラルを定義するのと、defの差はある??
Conclusion
これで小さいタスクを実行するためのスクリプトを書けるようになったはず。
** そんなに簡単では無い気がするが、リファレンス読みながら書ける?
** ちょっとしたscriptの実行にJVMの立ち上げなどもあるので実行時間が掛かる。
** 関数型スタイルでは結果から逆向きに必要な部品を作成する。
** TDD(test driven development)と相性が良さそう。
** 実際にやってみると関数型スタイルはコードの部分移動(refactor)が楽。
?? scalaの型推論はhaskellの推論より浅い?? compile時により束縛??
2014年5月25日日曜日
2014/5/16-25
==== 2014/5/16 ====
[雑感]
本質的な基本事項に絞り込んでそこだけ十分に理解する。
理解したと言うのは使える、作れると言うこと。
色々な豊富な機能があるが、理解している基本的な部分のみで試しに作ってみると面白いかもしれない。
[#3good]
#codecademy Max Streak Count of 55 バッジ獲得。半年ぶりにMax Streakの新記録更新!!
子供が起きている時間に帰って、一緒に早寝できた。
会社帰りに見えた月が綺麗だった。
==== 2014/5/17 ====
[#3good]
早起きして勉強出来た。
#studyplus 初コメント投稿!!
家の周りの草取りをした。
いちごとサンと公園に行った。気持ちの良い天気だった。
子供たちが寝る準備を進んでやってくれた。
==== 2014/5/18 ====
[#3good]
北海道から送ってもらったアスパラが大きくて驚いた。とても美味しかった。
#coursera posa-002 Week 1 Lecture & Quiz & Assignment submit完了!! 始める前は結構不安だったけど思ったより簡単だった!! この後もevaluationが残っている。。。
昼に食べたキウイが美味しかった。
早寝できた。子供たちの寝る準備が早く終わった。昔の写真をみんなで見た。
==== 2014/5/19 ====
[#3good]
昨日早く寝たので朝早起きしてcodecademyと茶碗洗いを出来た。朝活!?
お弁当が美味しかった。
サンの幼稚園の遠足のお土産のくまさんカステラチョコ味が美味しかった。
[雑感]
#3good(twitter), blog, codecademy, lang-8, cousera, studyplus
NHKラジオ英語、まぐまぐ英語メルマガ
習慣化すれば続けられる。何かやった気にはなるが効果は? やった気になるのが重要?
[tips]
exlipseのhelpを読む
eclipseのperspective, quick access
plug-in開発
eclipseのplug-inを作成出来た!!
機能が多過ぎる。全部覚えることは出来ない。
覚える手間を節約する為に作る。車輪の再発明で省力化。
[雑感]
javaのannotation
コンパイラによるチェックをより強力にしたり、作成者の意図をコードに記載するための機能が追加されている。
[chrome]
ハードウエアアクセラレーションをOFFにすれば、linkをhoverした時にaddressが表示される。
[Programming in Scala, First Edition]
2014/5/19 90 chapter20 6/10
typoが結構ある。後でまとめて見直す?
読んでいる途中で生じた疑問点??についても後でまとめて見直す必要ある?
==== 2014/5/20 ====
[#3good]
#Cousera progfun-004開始。今回はLectureの分量が多い。先にAssignmentsから始めてみる。
New Daysの宇治茶メロンパンとマンゴークリームパンが美味しかった。
台湾のお土産のいも饅頭みたいな物をもらった。味は。。。(^^;
weblio アカウント登録!!
[tips]
ハイパー辞書 会津大学の印欧語根を用いた英単語学習辞書
[ちょっと考えたこと]
英語を「勉強する事」そのものも楽しい。
英語を使って「何かをする事」も楽しい。
英語を「使う事そのもの」はそんなに楽しくない?
中国語も勉強できないか?
==== 2014/5/21 ====
[#3good]
#codecademy Max Streak Count of 60 達成!!
雨、風が強かったけど、帰りは晴れていた。
会社で間食しなかった。
子供が起きている時間に帰れた。サンといちごのピアノがまた上達していた。
[Programming in Scala, First Edition]
2014/5/21 30 chapter20 7/10
pattern matchingとisInstanceは似ている?
down castにならないのか? 型をチェックして安全だらOK?
==== 2014/5/22 ====
[#3good]
#Coursera #progfun-004 Week 4 Assignments完了!! Lectureは大量に残っているが。。。
#Coursera #posa-002 Week 2開始。Lecture90分程度あり。順番に見ていくことにする。
朝いちごが自分で起きれた。
==== 2014/5/23 ====
[tips]
ピグマリオン効果: 教師期待効果。教師が期待することで学習者の成績が向上する。
#gamification について #MOOC を探してみた。
#Coursera にもあったのでwatchlistに追加。
#iversity, #OpenLearning, #Canvas.net にもあり。
==== 2014/5/24 ====
[#3good]
#Coursera からrecommended courseのメールあり。どれも面白そうで困る。。。
いちごの運動会を無事に見に行けた。
いちごが運動会の駆けっこで2位を取れた!!
[雑感]
末っ子は甘やかされると言われているが、小さくて可愛いから甘やかすと言うよりも、子育てに慣れてこれくらいはどうにかなるだろうと思って放置する事が多くなっているだけの様な気がしする。
[雑感]
いちごの運動会のプログラム22個を記憶術の場所法を使って覚えられた。
今は昔住んでいた家をキーにしている。いろんな場所を増やしていければ結構覚えられるかも知れない。
[tips]
動画編集用にムービーメーカーインストールした。
動画のコマから静止画を抜き取るのはデジカメ本体で行った方が綺麗に取れた。
==== 2014/5/25 ====
[#3good]
早寝早起き出来たので体調が良い。朝から掃除や茶碗洗いを手伝えた。
いちごも進んで宿題を、サンもピアノを朝から出来た。
あんずがいちごの運動会のダンスの曲で踊ってくれた。
子供3人と近所の公園に行った。
[寝ているときに見た夢]
少し前まで会社でお世話になっていた先輩が夢に出てきた。
出張先に向かう途中で地下鉄に乗り遅れたりしていた。
[雑感]
本質的な基本事項に絞り込んでそこだけ十分に理解する。
理解したと言うのは使える、作れると言うこと。
色々な豊富な機能があるが、理解している基本的な部分のみで試しに作ってみると面白いかもしれない。
[#3good]
#codecademy Max Streak Count of 55 バッジ獲得。半年ぶりにMax Streakの新記録更新!!
子供が起きている時間に帰って、一緒に早寝できた。
会社帰りに見えた月が綺麗だった。
==== 2014/5/17 ====
[#3good]
早起きして勉強出来た。
#studyplus 初コメント投稿!!
家の周りの草取りをした。
いちごとサンと公園に行った。気持ちの良い天気だった。
子供たちが寝る準備を進んでやってくれた。
==== 2014/5/18 ====
[#3good]
北海道から送ってもらったアスパラが大きくて驚いた。とても美味しかった。
#coursera posa-002 Week 1 Lecture & Quiz & Assignment submit完了!! 始める前は結構不安だったけど思ったより簡単だった!! この後もevaluationが残っている。。。
昼に食べたキウイが美味しかった。
早寝できた。子供たちの寝る準備が早く終わった。昔の写真をみんなで見た。
==== 2014/5/19 ====
[#3good]
昨日早く寝たので朝早起きしてcodecademyと茶碗洗いを出来た。朝活!?
お弁当が美味しかった。
サンの幼稚園の遠足のお土産のくまさんカステラチョコ味が美味しかった。
[雑感]
#3good(twitter), blog, codecademy, lang-8, cousera, studyplus
NHKラジオ英語、まぐまぐ英語メルマガ
習慣化すれば続けられる。何かやった気にはなるが効果は? やった気になるのが重要?
[tips]
exlipseのhelpを読む
eclipseのperspective, quick access
plug-in開発
eclipseのplug-inを作成出来た!!
機能が多過ぎる。全部覚えることは出来ない。
覚える手間を節約する為に作る。車輪の再発明で省力化。
[雑感]
javaのannotation
コンパイラによるチェックをより強力にしたり、作成者の意図をコードに記載するための機能が追加されている。
[chrome]
ハードウエアアクセラレーションをOFFにすれば、linkをhoverした時にaddressが表示される。
[Programming in Scala, First Edition]
2014/5/19 90 chapter20 6/10
typoが結構ある。後でまとめて見直す?
読んでいる途中で生じた疑問点??についても後でまとめて見直す必要ある?
==== 2014/5/20 ====
[#3good]
#Cousera progfun-004開始。今回はLectureの分量が多い。先にAssignmentsから始めてみる。
New Daysの宇治茶メロンパンとマンゴークリームパンが美味しかった。
台湾のお土産のいも饅頭みたいな物をもらった。味は。。。(^^;
weblio アカウント登録!!
[tips]
ハイパー辞書 会津大学の印欧語根を用いた英単語学習辞書
[ちょっと考えたこと]
英語を「勉強する事」そのものも楽しい。
英語を使って「何かをする事」も楽しい。
英語を「使う事そのもの」はそんなに楽しくない?
中国語も勉強できないか?
==== 2014/5/21 ====
[#3good]
#codecademy Max Streak Count of 60 達成!!
雨、風が強かったけど、帰りは晴れていた。
会社で間食しなかった。
子供が起きている時間に帰れた。サンといちごのピアノがまた上達していた。
[Programming in Scala, First Edition]
2014/5/21 30 chapter20 7/10
pattern matchingとisInstanceは似ている?
down castにならないのか? 型をチェックして安全だらOK?
==== 2014/5/22 ====
[#3good]
#Coursera #progfun-004 Week 4 Assignments完了!! Lectureは大量に残っているが。。。
#Coursera #posa-002 Week 2開始。Lecture90分程度あり。順番に見ていくことにする。
朝いちごが自分で起きれた。
==== 2014/5/23 ====
[tips]
ピグマリオン効果: 教師期待効果。教師が期待することで学習者の成績が向上する。
#gamification について #MOOC を探してみた。
#Coursera にもあったのでwatchlistに追加。
#iversity, #OpenLearning, #Canvas.net にもあり。
==== 2014/5/24 ====
[#3good]
#Coursera からrecommended courseのメールあり。どれも面白そうで困る。。。
いちごの運動会を無事に見に行けた。
いちごが運動会の駆けっこで2位を取れた!!
[雑感]
末っ子は甘やかされると言われているが、小さくて可愛いから甘やかすと言うよりも、子育てに慣れてこれくらいはどうにかなるだろうと思って放置する事が多くなっているだけの様な気がしする。
[雑感]
いちごの運動会のプログラム22個を記憶術の場所法を使って覚えられた。
今は昔住んでいた家をキーにしている。いろんな場所を増やしていければ結構覚えられるかも知れない。
[tips]
動画編集用にムービーメーカーインストールした。
動画のコマから静止画を抜き取るのはデジカメ本体で行った方が綺麗に取れた。
==== 2014/5/25 ====
[#3good]
早寝早起き出来たので体調が良い。朝から掃除や茶碗洗いを手伝えた。
いちごも進んで宿題を、サンもピアノを朝から出来た。
あんずがいちごの運動会のダンスの曲で踊ってくれた。
子供3人と近所の公園に行った。
[寝ているときに見た夢]
少し前まで会社でお世話になっていた先輩が夢に出てきた。
出張先に向かう途中で地下鉄に乗り遅れたりしていた。
EGit/Git For Eclipse Usersのメモ
EGit/Git For Eclipse Users読んだので気になった部分のメモ。
[Worked example]
上記ページのWorked exampleが分かりやすい。参照すべし。
[ローカルでの作業が容易]
サーバのリポジトリと通信できない環境でもローカルに履歴情報などがあるのでdiff等が取れる。
[patchがoutdatedになり難い]
マージする場合に履歴情報を使えるから。
[Each user has a full copy of the repository]
ローカルに履歴情報も含めたリポジトリ全体を保持する。
[There is no master repository]
ツールの仕組みとしては何処かのリポジトリをマスターとするようにはなっていない。
個々のリポジトリ同士で相互にリポジトリの差分を取ったり同期したりする事が出来る。メッシュ構造。
実際の運用では何処かのリポジトリがマスターとなって、そのリポジトリからpullしたりpushしたりする場合が多い。木構造。スター構造。
[DVCS repositories are much smaller, typically because they contain only a small number of highly-related projects]
ローカルに全部の情報を保持するので、基本的にはリポジトリは大きくなる。
ただ、CVCSと比較するとより関連の強い部分のみローカルに複製する事が多いので、実質小さくなる。
CVCSは新しいリポジトリを作るのにコストが掛かるので古いプロジェクトのリポジトリに新しいプロジェクトを追加するケースが多い。
DVCSは小プロジェクト毎にリポジトリを分けて作ることが多い。
マスターとして動作するための特別なプロトコルを話せるサーバを用意する必要がないので、新しい細かいリポジトリを起こしやすい。
[Changesets are identified by a hash of their contents]
リポジトリは空の状態から始まって、そこからのchangeset(patch, 差分)の連続として扱われている。
それぞれのchangesetは「直前のchangesetのhash値と変更内容」のsha1のhash値をIDとしている。
同じ変更を複数回行っても直前のchangesetへのポインタ(hash値)を含んでいるので区別出来る。
?? 違う変更内容のhash値が偶然同じ値になってしまった場合は??
[Git hashes can be shortened to any unique prefix]
hash値はIDとして使うには長いので、prefix 6桁を省略形として使う場合が多い。
小さいプロジェクトならもっと短い桁数、大きいプロジェクトならもっと長い桁数にしてもよい。
?? さらにhash値の衝突が発生しやすくならないか。
[The default 'trunk' is called 'master' in Git]
[The tip of the current branch is referred to as 'HEAD']
tipはそのbranchの先頭のversionの事。
branchはあるversion以前の変更すべてを含むchangesetで参照される。
[Creating, and switching between, branches is fast]
既に作成済のchangesetを参照するだけでbranchを作ったり切り替えたり出来る。
[Think of branches as throwaway changesets]
DVCSではbranchを沢山作成する運用になる。
何か試して捨ててしまうような変更はbranchを作成して試してみる。
[It's painful to merge in a CVCS; therefore branches tend not to happen]
[Merging in a DVCS like Git is trivial]
changesetにどこ更新をどこのversion(point,changeset)に対して行ったかが記録されているので、ツールが内容ではなくて履歴同士を合成する形でmerge出来る。
CVCSでは内容のみなので、履歴の情報がある分だけマージしやすくなる。
mergeとはあるlocal branchに別のlocal branchのchangesetをweavingして一つにする事。
mergeはworking directoryに対して行われるのではなくて直接repositoryに反映されるので注意!!
[Pulling and pushing in a DVCS like Git is trivial]
localのbranchとremoteのbranchの共通の祖先(ancestor)からtipまでのchangesetを送ったり(push)取得したり(pull)する。
どこが共通の祖先かはツールが知っているので気にしなくていい。
[Origin is the name of the default remote, but you can have many remotes per repository]
push/pullする先はremote nameとしてlocalのrepository毎に複数設定できる。
通常は最初にcloneしたremote nameがoriginとしてその対象になる。
他のremote nameを定義してそこを指定してpush/pullする事も出来る。
remoteはURLで指定する。
pullはremoteのbranchをlocalのbranchにmergeするという事。
['git init' creates a fresh repository in the current directory]
['git add' is used to add files and track changes to files]
['git commit' is used to commit tracked files]
gitにはindexという概念がある。
今commit対象になっているファイルの組。
addで追加できる。commitするとindexのファイルがcommitされる。
commitするたびにindexはclearされるので、再commitするためには再度addが必要。
['git branch' is used to create and list branches]
['git checkout' is used to switch branches]
['git checkout -b' is used to create and then switch branches]
checkoutは別のbranchのファイルを取り出すという事。
今後の作業対象のbranchも切り替わる。
今のbranchの作業内容はcommitしていないのとdiscardされるの注意!!
branchの作成はbranch pointのchangesetを指定してbranch nameをつける。
branch nameでtipを参照する。
[Rebasing replants your tree; but do it on local branches only]
git rebase [basebranch] [topicbranch]
topic branchにbase branchをmergeした場合と同じsnapshotになる。
異なるのはそこに至る履歴。
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、baseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
baseにtopicをfast-forward出来るようになる。
通常はmasterにpushする前に履歴を整理するために行う。
topic branchの履歴が変わってしまうため、changesetを他人に公開した後は行うべきではない。
git rebase --onto newbase [basebranch] [topicbranch]
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、newbaseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
[補足]
[working directory]
repositoryからcheckoutされた作業対象。
[fast-forward]
git用語。tipの先に単にchangesetを追加するだけでmerge出来る場合のmergeの事。
[bare, non-bare]
履歴情報のみのbare repositoryと実際のworking directoryを持つnon-bare repositoryという概念がある。
詳しくはこちら。
git config --bool core.bare true もしくは false でbare属性を指定。
non-bare上でbareからpull、bareへpushすると言うのが普通の使い方。
?? gitにはfile lock機能がないので整合性を保つために必要らしい??
bareだとcheckout出来ない。non-bareへはpush出来ない。
[stage (index)]
staging: index に working copy の変更を登録する事。
git add: working copyをindexにstageする
git add -u: 変更を一括stageする
git add -p: 対話的に変更部分のstage/unstageを決められる。
git reset: Hirotryの内容をindexに取り出す。(unstage)
git checkout: indexの内容をworking copyに取り出す。
git commit: indexをHistoryに登録する。
git diff: working copyとindex差分
git diff --cached: indexとcommitの差分
http://marklodato.github.io/visual-git-guide/index-ja.html
図解されていて分かりやすい。
単純に任意のcommitからbranchを作成する場合。
git branch
何処からも参照されないcommitは破棄されてしまうのは注意が必要。
branchやtagを小まめに打つ必要がある??
?? tagやbranchが増えすぎで分かり難くならないか? 名前を考えるのも大変。
?? tagやbranchはいらなくなったら削除すべき?
[stash]
http://qiita.com/fukajun/items/41288806e4733cb9c342
working copy上に未commitのファイルがある状態でbranchを切り替えたい場合はgit stashを使う。
git stashすると未commitの修正がstash領域に一時退避される。
退避後にbranchをcheckoutしてstashをgit stash applyすれば退避していた修正がbranchのworking copyに乗る。
stashには修正が残ったままなので、git stash dropで小まめに消去する必要がある。
gitの基本としては、bransh作成、切り替えてからworking copyの変更を開始する。
[Reference, Book]
http://git-scm.com/doc
Gitをボトムアップから理解する
[その他]
GitのようなDVCSとCVS/SVNのようなCVCSはカラーテレビと白黒テレビの様な違いと例えられていた。
その便利さを知ってしまったらもう元には戻れないと言う意味で。
Egitでmerge toolを使うためにはローカルの変更ファイルをcommitしてからmergeする必要がある??
色々な人がWeb説明を書いているが、コマンドの詳細は意外と書いていない。
[Worked example]
上記ページのWorked exampleが分かりやすい。参照すべし。
[ローカルでの作業が容易]
サーバのリポジトリと通信できない環境でもローカルに履歴情報などがあるのでdiff等が取れる。
[patchがoutdatedになり難い]
マージする場合に履歴情報を使えるから。
[Each user has a full copy of the repository]
ローカルに履歴情報も含めたリポジトリ全体を保持する。
[There is no master repository]
ツールの仕組みとしては何処かのリポジトリをマスターとするようにはなっていない。
個々のリポジトリ同士で相互にリポジトリの差分を取ったり同期したりする事が出来る。メッシュ構造。
実際の運用では何処かのリポジトリがマスターとなって、そのリポジトリからpullしたりpushしたりする場合が多い。木構造。スター構造。
[DVCS repositories are much smaller, typically because they contain only a small number of highly-related projects]
ローカルに全部の情報を保持するので、基本的にはリポジトリは大きくなる。
ただ、CVCSと比較するとより関連の強い部分のみローカルに複製する事が多いので、実質小さくなる。
CVCSは新しいリポジトリを作るのにコストが掛かるので古いプロジェクトのリポジトリに新しいプロジェクトを追加するケースが多い。
DVCSは小プロジェクト毎にリポジトリを分けて作ることが多い。
マスターとして動作するための特別なプロトコルを話せるサーバを用意する必要がないので、新しい細かいリポジトリを起こしやすい。
[Changesets are identified by a hash of their contents]
リポジトリは空の状態から始まって、そこからのchangeset(patch, 差分)の連続として扱われている。
それぞれのchangesetは「直前のchangesetのhash値と変更内容」のsha1のhash値をIDとしている。
同じ変更を複数回行っても直前のchangesetへのポインタ(hash値)を含んでいるので区別出来る。
?? 違う変更内容のhash値が偶然同じ値になってしまった場合は??
[Git hashes can be shortened to any unique prefix]
hash値はIDとして使うには長いので、prefix 6桁を省略形として使う場合が多い。
小さいプロジェクトならもっと短い桁数、大きいプロジェクトならもっと長い桁数にしてもよい。
?? さらにhash値の衝突が発生しやすくならないか。
[The default 'trunk' is called 'master' in Git]
[The tip of the current branch is referred to as 'HEAD']
tipはそのbranchの先頭のversionの事。
branchはあるversion以前の変更すべてを含むchangesetで参照される。
[Creating, and switching between, branches is fast]
既に作成済のchangesetを参照するだけでbranchを作ったり切り替えたり出来る。
[Think of branches as throwaway changesets]
DVCSではbranchを沢山作成する運用になる。
何か試して捨ててしまうような変更はbranchを作成して試してみる。
[It's painful to merge in a CVCS; therefore branches tend not to happen]
[Merging in a DVCS like Git is trivial]
changesetにどこ更新をどこのversion(point,changeset)に対して行ったかが記録されているので、ツールが内容ではなくて履歴同士を合成する形でmerge出来る。
CVCSでは内容のみなので、履歴の情報がある分だけマージしやすくなる。
mergeとはあるlocal branchに別のlocal branchのchangesetをweavingして一つにする事。
mergeはworking directoryに対して行われるのではなくて直接repositoryに反映されるので注意!!
[Pulling and pushing in a DVCS like Git is trivial]
localのbranchとremoteのbranchの共通の祖先(ancestor)からtipまでのchangesetを送ったり(push)取得したり(pull)する。
どこが共通の祖先かはツールが知っているので気にしなくていい。
[Origin is the name of the default remote, but you can have many remotes per repository]
push/pullする先はremote nameとしてlocalのrepository毎に複数設定できる。
通常は最初にcloneしたremote nameがoriginとしてその対象になる。
他のremote nameを定義してそこを指定してpush/pullする事も出来る。
remoteはURLで指定する。
pullはremoteのbranchをlocalのbranchにmergeするという事。
['git init' creates a fresh repository in the current directory]
['git add' is used to add files and track changes to files]
['git commit' is used to commit tracked files]
gitにはindexという概念がある。
今commit対象になっているファイルの組。
addで追加できる。commitするとindexのファイルがcommitされる。
commitするたびにindexはclearされるので、再commitするためには再度addが必要。
['git branch' is used to create and list branches]
['git checkout' is used to switch branches]
['git checkout -b' is used to create and then switch branches]
checkoutは別のbranchのファイルを取り出すという事。
今後の作業対象のbranchも切り替わる。
今のbranchの作業内容はcommitしていないのとdiscardされるの注意!!
branchの作成はbranch pointのchangesetを指定してbranch nameをつける。
branch nameでtipを参照する。
[Rebasing replants your tree; but do it on local branches only]
git rebase [basebranch] [topicbranch]
topic branchにbase branchをmergeした場合と同じsnapshotになる。
異なるのはそこに至る履歴。
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、baseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
baseにtopicをfast-forward出来るようになる。
通常はmasterにpushする前に履歴を整理するために行う。
topic branchの履歴が変わってしまうため、changesetを他人に公開した後は行うべきではない。
git rebase --onto newbase [basebranch] [topicbranch]
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、newbaseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
[補足]
[working directory]
repositoryからcheckoutされた作業対象。
[fast-forward]
git用語。tipの先に単にchangesetを追加するだけでmerge出来る場合のmergeの事。
[bare, non-bare]
履歴情報のみのbare repositoryと実際のworking directoryを持つnon-bare repositoryという概念がある。
詳しくはこちら。
git config --bool core.bare true もしくは false でbare属性を指定。
non-bare上でbareからpull、bareへpushすると言うのが普通の使い方。
?? gitにはfile lock機能がないので整合性を保つために必要らしい??
bareだとcheckout出来ない。non-bareへはpush出来ない。
[stage (index)]
staging: index に working copy の変更を登録する事。
git add: working copyをindexにstageする
git add -u: 変更を一括stageする
git add -p: 対話的に変更部分のstage/unstageを決められる。
git reset: Hirotryの内容をindexに取り出す。(unstage)
git checkout: indexの内容をworking copyに取り出す。
git commit: indexをHistoryに登録する。
git diff: working copyとindex差分
git diff --cached: indexとcommitの差分
http://marklodato.github.io/visual-git-guide/index-ja.html
図解されていて分かりやすい。
単純に任意のcommitからbranchを作成する場合。
git branch
何処からも参照されないcommitは破棄されてしまうのは注意が必要。
branchやtagを小まめに打つ必要がある??
?? tagやbranchが増えすぎで分かり難くならないか? 名前を考えるのも大変。
?? tagやbranchはいらなくなったら削除すべき?
[stash]
http://qiita.com/fukajun/items/41288806e4733cb9c342
working copy上に未commitのファイルがある状態でbranchを切り替えたい場合はgit stashを使う。
git stashすると未commitの修正がstash領域に一時退避される。
退避後にbranchをcheckoutしてstashをgit stash applyすれば退避していた修正がbranchのworking copyに乗る。
stashには修正が残ったままなので、git stash dropで小まめに消去する必要がある。
gitの基本としては、bransh作成、切り替えてからworking copyの変更を開始する。
[Reference, Book]
http://git-scm.com/doc
Gitをボトムアップから理解する
[その他]
GitのようなDVCSとCVS/SVNのようなCVCSはカラーテレビと白黒テレビの様な違いと例えられていた。
その便利さを知ってしまったらもう元には戻れないと言う意味で。
Egitでmerge toolを使うためにはローカルの変更ファイルをcommitしてからmergeする必要がある??
色々な人がWeb説明を書いているが、コマンドの詳細は意外と書いていない。
2014年5月17日土曜日
Programming in Scala, First Edition Chapter 19
19. Type Parameterization
type parameterizationについて説明する。
scalaではtypeは何かに特定しなくてはならない。
javaではraw typeを許しているのと異なる。
information hiding
type parameterizationを使って行う。
purely functional queues
information hidingの実例として取り上げる。
19.1 Functional queues
Listの様にimmutableなpurely functional queuesを考える。
head, tail, appendのoperationが必要。
mutableと同様にO(1)でのoperationを行いたい。
head, tailはListと同様にしてもappendはO(n)になってしまう。
要素を前半leadingと後半trailingの二つのListに分ける。
leading ::: trailing.reverse がqueueの全体像。
leadingがemptyの時のみhead, tail時にtrailing.reverseでmirrorする。
reverseはQ(n)だがtailすればhead, tailのO(1)の実施をn回分charge出来る。
head, tail, appendが同回数ならasymptotically(漸近的)にO(1)となる。
class Queue[T](private val leading: List[T], private val trailing: List[T]) {
private def mirror =
if (leading.isEmpty) new Queue(trailing.reverse, Nil)
else this
def head = mirror.leading.head
def tail = { val q = mirror; new Queue(q.leading.tail, q.trailing) }
def append(x: T) = new Queue(leading, x :: trailing)
}
19.2 Information hiding
先のclass Queueのコンストラクタは前半と後半のリバースと言う不自然な使用。
効率のよって使いやすが犠牲にされている。
内部の実装がAPIにみえてしまっている。
どう隠蔽するか?
Private constructors and factory methods
privateを付けることでprimary constructorも非公開に出来る。
class Queue[T] private (...)
typeとしては公開されたまま。コンストラクタのみが非公開。
コンストラクタはクラス内とcompanion objectから呼べる。
auxiliary constructorは使える。
def this(elems: T*) = this(elems.toList, Nil)
T*は引数の任意回の繰り返し。Section 8.8
Array[T]として渡される。
factory methodをcompanion objectに定義する。
object Queue {
// constructs a queue with initial elements `xs'
def apply[T](xs: T*) = new Queue[T](xs.toList, Nil)
}
classとobjectを同じファイルで置くことでcompanion objectになる。
Queue(1, 2, 3)の様に自然な形で初期化出来る。
global objectのapply methodはobject名で呼べるのでglobal関数に見える。
実際はscalaではmethodは必ずclassかobjectに含まれている。
An alternative: private classes
trait Queue[T] { def head: T; ... }
object Queue {
def apply[T](xs: T*): Queue[T] = { ... }
private class QueueImpl[T](...) { ... }
}
traitでpublic interfaceのみを公開する。
class全体をobject Queueのprivateのclassとして隠ぺいする。
19.3 Variance annotations
trait Queue[T]自体はtypeではない。type parameterを取るので。
typeではないので、値を定義できない。
def doesNotCompile(q: Queue) {} はコンパイルエラーになる。
type parameterを特定すれば(parameterized)型になる。
Queue[String], Queue[Int]は型。
def doesCompile(q: Queue[Int]) {} はコンパイル出来る。
type parameterを取るtrait, classなどをtype constructorと呼ぶ。
type constructorはfamily of typesをgenerateする。
type parameterを取るtrait, classなどをgenericとも呼ぶ。
個々の型を一般化generalizeしたものだから
type parameterのsubtypingと生成された型の関係をvariantと言う。
covariant (flexible)
型に+を付けて表現する。
trait Queue[+T] { ... }
SがTのsubtypeならQueue[S]もQueue[T]のsubtypeになる。
Queue[T]をQueue[S]の型の変数に代入出来るということを。
Tを戻り値の型として使う時。
Queue[T]に実施出来る演算は、Queue[S]にも出来ると言う事。
immutableなら問題ない場合が多い。(全てではない)
mutableの場合は矛盾した操作が出来てしまう可能性あり注意必要。
contravariant
型に-を付けて表現する。
trait Queue[-T] { ... }
SがTのsubtypeならQueue[T]はQueue[S]のsubtypeになる。
covariantの反対。上の例は不自然。。。Section 19.6
Tを引数の型として使うとき。
Tが一般化するとそれを引数とする関数は特殊化する。
nonvariant (rigid)
型に-に何もつけない場合。
trait Queue[T] { ... }
SがTのsubtypeでもQueue[S]とQueue[T]は無関係。
mutableの場合はこの方が安全??
Variance and arrays
scalaのarrayはnonvariant(rigid)
だだし、javaとの互換性のためにArray[Object]型には何でもup cast出来る。
javaのarrayはcovariant(flexible)
type parameterが無かった時からの互換性のため。
19.4 Checking variance annotations
covariant, contravariantに出来るかは、type parameterの使われ方による。
mutableのfieldでNGなのも、setterのdef x_=(x: T)があるから。
imutableでもメソッドの引数にtype parameterの使われたらcovariantに出来ない。
compilerでtype parameterの使われ方がチェックされる。
全てのtype parameterの使用場所を3つに分類する。
covariant(+)のtype parameterが使えるのpositiveな場所のみ。
contravariant(-)のtype parameterが使えるのはnegative場所のみ。
nonvariantはneutralな場所を含め全ての場所で使える。
top levelでのクラス宣言はpositive
原則、ネストされた場所は外側の場所と同じ分類になる。
ネストと言うのは型パラメタ[]のネストと言う意味。
Array[List[T]]のようなネスト。
例外も幾つかある。
メソッドの値引数の型は外側の分類と逆(flipped)になる。
positive <-> negative, neutralはそのまま。
メソッドのtype parameterは外側の分類と逆(flipped)になる。
途中で使われるクラスのtype parameterはそのtype parameterの宣言による。
type parameterが+で宣言されていると変わらない。
type parameterが-宣言されていると逆(flipped)になる。
type parameterがnonvariantなら分類もneutralになる。
一回neutralになるとその内側の場所は全部neutralになる。
追うのが大変なので整合性のチェックはcomilerに任せた方が良い。
abstract class Cat[-T, +U] {
def meow[W^-](volume: T^-, listener: Cat[U^+, T^-]^-)
: Cat[Cat[U^+, T^-]^-, U^+]^+
}
Wはメソッドのtype parameterなので逆(flipped)になって-
volume, listenerはメソッドのvalue parameterなので逆(flipped)になって-
listenerのCat[U, T]
Uはclass Cat[-T, +U]の第一型パラメタが-なので-から逆(flipped)になって+
Tはclass Cat[-T, +U]の第二型パラメタが+なので-のまま。
戻り値の型のCat[Cat[U, T], U]
戻り値の型全体としてはtop levelなので+
型引数Cat[U, T]
全体としては、class Cat[-T, +U]の第一型パラメタが-なので+から逆で-
Uはclass Cat[-T, +U]の第一型パラメタが-なので-から逆(flipped)になって+
Tはclass Cat[-T, +U]の第二型パラメタが+なので-のまま。
型引数U
class Cat[-T, +U]の第二型パラメタが+なので+のまま。
** 上の例を全部追えた!!
?? 直感的にはよくわからない。。。
19.5 Lower bounds
Lower bounds
type parameterの下限を指定できる。
[U >: T]
UをTのsuper classのみに制限出来る。
class Queue[T](private val leading: List[T], private val trailing: List[T]) {
...
def append(x: T) = new Queue(leading, x :: trailing)
}
Queue[T]のTはpositive、append(x: T)のTはnegative => Tをcovariantに出来ない。
class Queue[+T](private val leading: List[T], private val trailing: List[T]) {
...
def append[U >: T](x: U) = new Queue[U](leading, x :: trailing)
}
Uがnegativeになるだけなので、Tはcovariantに出来る。
直感的には、xとTの共通のsuper class Uを型推論で導き出すと言う事。
contravariantは最大公約数的な発想。
自分の要素と演算対象の要素の型が異なる場合は共通の演算しかできない。
type-driven design
型インタフェースによって実装の方法をガイドする。
型設計の概念を入れることで設計が整理しやすくなる。
declaration-site variance
scala、variantを明示的に宣言する。
コンパイラでチェックできる。
use-site variance
javaのwildecard、variantは使う側が暗黙的に決める。
コンパイラでチェック出来ない。
variant複雑で間違いやすいので、結局難し過ぎて使えないと言う事になりがち。
19.6 Contravariance
contravarianceの使用が自然である場合の例
trait OutputChannel[-T] {
def write(x: T)
}
OutputChannel[AnyRef]はOutputChannel[String]のsubtype
AnyRefをwrite出来る場合はStirngをwriteしても安全。
OutputChannel[AnyRef]の使用場所でOutputChannel[String]に置き換えても安全。
OutputChannel[AnyRef]型の値をOutputChannel[String]型の変数に代入出来る。
OutputChannel[AnyRef]がsubtypeでOutputChannel[String]がsuper type
代入する側か、される側か
val super: T = sub の使いかたならTとこの表現を含む部分はcovariant
val super = sub: T の使いかたならTとこの表現を含む部分はcontravariant
両方の表現を含む部分はTとnonvariantにしか出来ない。
戻り値か、引数か
f(x: U): T
Tとfはcovariantで、Uとfはcontravariant
引数は関数の要求、条件、制約
戻り値は関数の提供する機能
型システム設計の一般原則 - Liskov Substitution Principle
TがUのsubtypeならUの代わりにTが使える。
TはUと同等以上のオペレーションをサポートしている。
TのオペレーションはUよりも要求(条件、制約)が少ない。
Tのオペレーションの結果はUの結果の同等以上(subtype的)
** 置き換えられるか(substitution, reasoning)が重要。
** 型システムで置き換え可能であることを保証する。
trait Function1[-S, +T] {
def apply(x: S): T
}
subtype的な関数 - どの関数の代わりとしても使える関数
戻り値がどんな事でも実施できる
Tが全てのtraitをmix-inしたような全てのsubtypeであるような型
Tがsubtype的であるほどFunction1はsubtype的になる。
covariant
どんな引数でも受け入れられる
SがAny
Sがsupertype的であるほどFunction1はsubtype的になる。
contravariant
19.7 Object private data
class Queue[+T] private (
private[this] var leading: List[T],
private[this] var trailing: List[T]
) { ... }
leading, trailingをvarにすればQueueの性能を上げられる。
varにしても引数の値のみで関数の戻り値が決まると言う性質は変わらない。
Queueの外側からはQueueがvarを使っていることが完全に隠蔽されている。
leading, trailingがprivate[this]だから
Queueはvarを含んでも純粋関数的(purely functional)と言える。
varがあってもそれはcacheしているだけで毎回計算しているのと同等。
covariantにvarを含んでいても出来る。
leading, trailingがprivate[this]だから
Queueの外側からはvarを使っていない時と同じ振る舞いに見える。
private[this]の場合のみ同じvariantのチェックが省略される。
?? only in positions that have the same variance classification??
privateだとerrorになる。
19.8 Upper bounds
[T <: U]
type parameter TをUのsubtypeに制限したい場合。
def max[T <: Ordered[T]](x: T, y: T) = if (x > y) x else y
x, yの型をOrdered[T]のsubtypeに制限しているので比較演算>が使える。
[T >: S <: U]
lowerとupperを両方指定することも出来る。
?? SもUのsubtypeの必要あり??
?? Tを複数のU1,U2のsubtypeに制限したい場合は??
max(1, 2)は出来ない!!
Int <: Ordered[Int]ではないから。
implicit parameterを使えば出来る。Section 21.6
19.9 Conclusion
information hiding:
private constructors, factory methods, type abstraction, object private members
type variance
variance annotations, lower/upper bounds, private[this] annotation
type parameterizationについて説明する。
scalaではtypeは何かに特定しなくてはならない。
javaではraw typeを許しているのと異なる。
information hiding
type parameterizationを使って行う。
purely functional queues
information hidingの実例として取り上げる。
19.1 Functional queues
Listの様にimmutableなpurely functional queuesを考える。
head, tail, appendのoperationが必要。
mutableと同様にO(1)でのoperationを行いたい。
head, tailはListと同様にしてもappendはO(n)になってしまう。
要素を前半leadingと後半trailingの二つのListに分ける。
leading ::: trailing.reverse がqueueの全体像。
leadingがemptyの時のみhead, tail時にtrailing.reverseでmirrorする。
reverseはQ(n)だがtailすればhead, tailのO(1)の実施をn回分charge出来る。
head, tail, appendが同回数ならasymptotically(漸近的)にO(1)となる。
class Queue[T](private val leading: List[T], private val trailing: List[T]) {
private def mirror =
if (leading.isEmpty) new Queue(trailing.reverse, Nil)
else this
def head = mirror.leading.head
def tail = { val q = mirror; new Queue(q.leading.tail, q.trailing) }
def append(x: T) = new Queue(leading, x :: trailing)
}
19.2 Information hiding
先のclass Queueのコンストラクタは前半と後半のリバースと言う不自然な使用。
効率のよって使いやすが犠牲にされている。
内部の実装がAPIにみえてしまっている。
どう隠蔽するか?
Private constructors and factory methods
privateを付けることでprimary constructorも非公開に出来る。
class Queue[T] private (...)
typeとしては公開されたまま。コンストラクタのみが非公開。
コンストラクタはクラス内とcompanion objectから呼べる。
auxiliary constructorは使える。
def this(elems: T*) = this(elems.toList, Nil)
T*は引数の任意回の繰り返し。Section 8.8
Array[T]として渡される。
factory methodをcompanion objectに定義する。
object Queue {
// constructs a queue with initial elements `xs'
def apply[T](xs: T*) = new Queue[T](xs.toList, Nil)
}
classとobjectを同じファイルで置くことでcompanion objectになる。
Queue(1, 2, 3)の様に自然な形で初期化出来る。
global objectのapply methodはobject名で呼べるのでglobal関数に見える。
実際はscalaではmethodは必ずclassかobjectに含まれている。
An alternative: private classes
trait Queue[T] { def head: T; ... }
object Queue {
def apply[T](xs: T*): Queue[T] = { ... }
private class QueueImpl[T](...) { ... }
}
traitでpublic interfaceのみを公開する。
class全体をobject Queueのprivateのclassとして隠ぺいする。
19.3 Variance annotations
trait Queue[T]自体はtypeではない。type parameterを取るので。
typeではないので、値を定義できない。
def doesNotCompile(q: Queue) {} はコンパイルエラーになる。
type parameterを特定すれば(parameterized)型になる。
Queue[String], Queue[Int]は型。
def doesCompile(q: Queue[Int]) {} はコンパイル出来る。
type parameterを取るtrait, classなどをtype constructorと呼ぶ。
type constructorはfamily of typesをgenerateする。
type parameterを取るtrait, classなどをgenericとも呼ぶ。
個々の型を一般化generalizeしたものだから
type parameterのsubtypingと生成された型の関係をvariantと言う。
covariant (flexible)
型に+を付けて表現する。
trait Queue[+T] { ... }
SがTのsubtypeならQueue[S]もQueue[T]のsubtypeになる。
Queue[T]をQueue[S]の型の変数に代入出来るということを。
Tを戻り値の型として使う時。
Queue[T]に実施出来る演算は、Queue[S]にも出来ると言う事。
immutableなら問題ない場合が多い。(全てではない)
mutableの場合は矛盾した操作が出来てしまう可能性あり注意必要。
contravariant
型に-を付けて表現する。
trait Queue[-T] { ... }
SがTのsubtypeならQueue[T]はQueue[S]のsubtypeになる。
covariantの反対。上の例は不自然。。。Section 19.6
Tを引数の型として使うとき。
Tが一般化するとそれを引数とする関数は特殊化する。
nonvariant (rigid)
型に-に何もつけない場合。
trait Queue[T] { ... }
SがTのsubtypeでもQueue[S]とQueue[T]は無関係。
mutableの場合はこの方が安全??
Variance and arrays
scalaのarrayはnonvariant(rigid)
だだし、javaとの互換性のためにArray[Object]型には何でもup cast出来る。
javaのarrayはcovariant(flexible)
type parameterが無かった時からの互換性のため。
19.4 Checking variance annotations
covariant, contravariantに出来るかは、type parameterの使われ方による。
mutableのfieldでNGなのも、setterのdef x_=(x: T)があるから。
imutableでもメソッドの引数にtype parameterの使われたらcovariantに出来ない。
compilerでtype parameterの使われ方がチェックされる。
全てのtype parameterの使用場所を3つに分類する。
covariant(+)のtype parameterが使えるのpositiveな場所のみ。
contravariant(-)のtype parameterが使えるのはnegative場所のみ。
nonvariantはneutralな場所を含め全ての場所で使える。
top levelでのクラス宣言はpositive
原則、ネストされた場所は外側の場所と同じ分類になる。
ネストと言うのは型パラメタ[]のネストと言う意味。
Array[List[T]]のようなネスト。
例外も幾つかある。
メソッドの値引数の型は外側の分類と逆(flipped)になる。
positive <-> negative, neutralはそのまま。
メソッドのtype parameterは外側の分類と逆(flipped)になる。
途中で使われるクラスのtype parameterはそのtype parameterの宣言による。
type parameterが+で宣言されていると変わらない。
type parameterが-宣言されていると逆(flipped)になる。
type parameterがnonvariantなら分類もneutralになる。
一回neutralになるとその内側の場所は全部neutralになる。
追うのが大変なので整合性のチェックはcomilerに任せた方が良い。
abstract class Cat[-T, +U] {
def meow[W^-](volume: T^-, listener: Cat[U^+, T^-]^-)
: Cat[Cat[U^+, T^-]^-, U^+]^+
}
Wはメソッドのtype parameterなので逆(flipped)になって-
volume, listenerはメソッドのvalue parameterなので逆(flipped)になって-
listenerのCat[U, T]
Uはclass Cat[-T, +U]の第一型パラメタが-なので-から逆(flipped)になって+
Tはclass Cat[-T, +U]の第二型パラメタが+なので-のまま。
戻り値の型のCat[Cat[U, T], U]
戻り値の型全体としてはtop levelなので+
型引数Cat[U, T]
全体としては、class Cat[-T, +U]の第一型パラメタが-なので+から逆で-
Uはclass Cat[-T, +U]の第一型パラメタが-なので-から逆(flipped)になって+
Tはclass Cat[-T, +U]の第二型パラメタが+なので-のまま。
型引数U
class Cat[-T, +U]の第二型パラメタが+なので+のまま。
** 上の例を全部追えた!!
?? 直感的にはよくわからない。。。
19.5 Lower bounds
Lower bounds
type parameterの下限を指定できる。
[U >: T]
UをTのsuper classのみに制限出来る。
class Queue[T](private val leading: List[T], private val trailing: List[T]) {
...
def append(x: T) = new Queue(leading, x :: trailing)
}
Queue[T]のTはpositive、append(x: T)のTはnegative => Tをcovariantに出来ない。
class Queue[+T](private val leading: List[T], private val trailing: List[T]) {
...
def append[U >: T](x: U) = new Queue[U](leading, x :: trailing)
}
Uがnegativeになるだけなので、Tはcovariantに出来る。
直感的には、xとTの共通のsuper class Uを型推論で導き出すと言う事。
contravariantは最大公約数的な発想。
自分の要素と演算対象の要素の型が異なる場合は共通の演算しかできない。
type-driven design
型インタフェースによって実装の方法をガイドする。
型設計の概念を入れることで設計が整理しやすくなる。
declaration-site variance
scala、variantを明示的に宣言する。
コンパイラでチェックできる。
use-site variance
javaのwildecard、variantは使う側が暗黙的に決める。
コンパイラでチェック出来ない。
variant複雑で間違いやすいので、結局難し過ぎて使えないと言う事になりがち。
19.6 Contravariance
contravarianceの使用が自然である場合の例
trait OutputChannel[-T] {
def write(x: T)
}
OutputChannel[AnyRef]はOutputChannel[String]のsubtype
AnyRefをwrite出来る場合はStirngをwriteしても安全。
OutputChannel[AnyRef]の使用場所でOutputChannel[String]に置き換えても安全。
OutputChannel[AnyRef]型の値をOutputChannel[String]型の変数に代入出来る。
OutputChannel[AnyRef]がsubtypeでOutputChannel[String]がsuper type
代入する側か、される側か
val super: T = sub の使いかたならTとこの表現を含む部分はcovariant
val super = sub: T の使いかたならTとこの表現を含む部分はcontravariant
両方の表現を含む部分はTとnonvariantにしか出来ない。
戻り値か、引数か
f(x: U): T
Tとfはcovariantで、Uとfはcontravariant
引数は関数の要求、条件、制約
戻り値は関数の提供する機能
型システム設計の一般原則 - Liskov Substitution Principle
TがUのsubtypeならUの代わりにTが使える。
TはUと同等以上のオペレーションをサポートしている。
TのオペレーションはUよりも要求(条件、制約)が少ない。
Tのオペレーションの結果はUの結果の同等以上(subtype的)
** 置き換えられるか(substitution, reasoning)が重要。
** 型システムで置き換え可能であることを保証する。
trait Function1[-S, +T] {
def apply(x: S): T
}
subtype的な関数 - どの関数の代わりとしても使える関数
戻り値がどんな事でも実施できる
Tが全てのtraitをmix-inしたような全てのsubtypeであるような型
Tがsubtype的であるほどFunction1はsubtype的になる。
covariant
どんな引数でも受け入れられる
SがAny
Sがsupertype的であるほどFunction1はsubtype的になる。
contravariant
19.7 Object private data
class Queue[+T] private (
private[this] var leading: List[T],
private[this] var trailing: List[T]
) { ... }
leading, trailingをvarにすればQueueの性能を上げられる。
varにしても引数の値のみで関数の戻り値が決まると言う性質は変わらない。
Queueの外側からはQueueがvarを使っていることが完全に隠蔽されている。
leading, trailingがprivate[this]だから
Queueはvarを含んでも純粋関数的(purely functional)と言える。
varがあってもそれはcacheしているだけで毎回計算しているのと同等。
covariantにvarを含んでいても出来る。
leading, trailingがprivate[this]だから
Queueの外側からはvarを使っていない時と同じ振る舞いに見える。
private[this]の場合のみ同じvariantのチェックが省略される。
?? only in positions that have the same variance classification??
privateだとerrorになる。
19.8 Upper bounds
[T <: U]
type parameter TをUのsubtypeに制限したい場合。
def max[T <: Ordered[T]](x: T, y: T) = if (x > y) x else y
x, yの型をOrdered[T]のsubtypeに制限しているので比較演算>が使える。
[T >: S <: U]
lowerとupperを両方指定することも出来る。
?? SもUのsubtypeの必要あり??
?? Tを複数のU1,U2のsubtypeに制限したい場合は??
max(1, 2)は出来ない!!
Int <: Ordered[Int]ではないから。
implicit parameterを使えば出来る。Section 21.6
19.9 Conclusion
information hiding:
private constructors, factory methods, type abstraction, object private members
type variance
variance annotations, lower/upper bounds, private[this] annotation
2014年5月15日木曜日
emacs: desktop-mode
emacsには現状のバッファのステータスを保存、読み込みを行うdesktop-modeがある。
起動時に自動読み込み、終了時に自動保存するようにしておくと便利。
また、2個目のemacsについては同じdesktopを共有するとconflictするので、desktopを使わない様にした方が使いやすい。
下記がその設定。
;;; desktop
(desktop-save-mode 1) ; enable
;; 他のemacs processでdesktopを使用中の場合はconflictするので使わない。
(setq desktop-save 'if-exists) ; save only if desktop file exists
(setq desktop-load-locked-desktop nil) ; don't load if the desktop is locked.
;; don't save if not loaded.
(add-hook 'desktop-not-loaded-hook '(lambda() (desktop-save-mode -1)))
起動時に自動読み込み、終了時に自動保存するようにしておくと便利。
また、2個目のemacsについては同じdesktopを共有するとconflictするので、desktopを使わない様にした方が使いやすい。
下記がその設定。
;;; desktop
(desktop-save-mode 1) ; enable
;; 他のemacs processでdesktopを使用中の場合はconflictするので使わない。
(setq desktop-save 'if-exists) ; save only if desktop file exists
(setq desktop-load-locked-desktop nil) ; don't load if the desktop is locked.
;; don't save if not loaded.
(add-hook 'desktop-not-loaded-hook '(lambda() (desktop-save-mode -1)))
Cousera: Functional Programming Principles in Scalaのgamification視点からの分析
Courseraにハマってしまって今週月曜、火曜と寝るのがAM4時前に。。。流石に体に悪そう。
どうしてそれだけ強い動機付けになっているのかgamification視点から分析してみると面白そう。
[ゴール: 最終的な目的]
やはり本来の目的と言うのが最後は重要になる。
それが自分にとって価値が低ければgamificationの手法で一時的に動機付けしても長続きしない。
「関数型プログラミングについての理解を深めること」「Scalaに関する理解を深めること」と言う「知識獲得」がそもそもの目的としてベースにある。
[目標: 小目標、中目標]
最終的な目的が重要と分かっていても、人は目の前の欲求にすぐに負けてしまう。
最終的な目的に至る過程を細かい中間的な目標に置き換える事が重要。
(実はこの小目標自体はポイントを貯めるなど直接目的と結びついていなくてもOK)
中目標として、毎週のクラス(ビデオ講義とプログラム課題)がある。
プログラム課題は2週間、3週間の2段階期限と自動採点があり目標が明確化されている。
ビデオ講義が15分x4本程度に分割されてるので、個々のビデオが小目標になる。
さらにビデオ内の小クイズも小目標となる。
プログラム課題も数ステップに分かれていて小目標として機能している。
[可視化]
可視化による目標の明確化と目標達成へのフィードバクが重要。
所謂ポイントやバッジなどのリワードも可視化の一つと言える。
実施した内容に対して細かく直ぐにフィードバックが掛かるのが重要。
勉強の成果と言うのは形に見えにくいものだが、勉強したと言う努力を形にして実感したいと言うのもあるかもしれない。
プログラム課題の高速自動採点と採点結果表示
各ビデオ講義の視聴済チェックマーク表示
プログラム課題の2週間、3週間の2段階期限
コース終了条件の明確化
修了証の発行
掲示板のポイント
[オンボーディング]
何か始めるときは腰が重くなるのが普通。現状維持バイアスが働くので。
これを乗り切るために最初の取っ掛かりは特に簡単に楽しく出来ることが重要。
開始前の準備課題やチュートリアル、FAQ、掲示板で初めての実施を容易にしている。
[世界観]
構築された世界観に染まることが出来れば、現実世界では難しくてもその世界のルールにしたがって容易に出来る可能性がある。
特に仮想世界には現実世界のような制約がないので、現実世界よりその世界の理想に従って行動しやすい。
仮想世界の理想を目指す事と、ゴールの達成が間接的にリンクしていると良い。
Courseraでは特に独自の世界観は構築されていない??
[ソーシャル]
他人と刺激しあう事でモチベーションを高める。
他人からのメッセージや「いいね!」ボタンなどフィードバック。
他人へフィードバックする事も自分の組織への帰属意識を高めたり出来る。
他人の状況を見たり、他人から見られていると意識出来ることも重要。(モラルハザード)
掲示板(いいねボタンあり)、オフ会、講師や管理者からのメール、アナウンス
掲示板で他人の考えや状況を見ると刺激にはなる。もっと発信出来れば良いのだが。
[上級者向け]
[チューニング]
上級者しか達成できない難しいタスク(レアアイテム入手)で継続的な実施を啓発。
個別の状況に応じてタスクの難易度等を個別にチューニングする。
追加の学習資料の提示。掲示板で他人に教える。
FAQやチュートリアルや掲示板での質問で難易度をある程度コントロール。
講義ビデオの早見。スライド。サブタイトルで講義に掛ける工数をコントロール。
[おもてなし]
究極的にはゴールを目指す過程の心理的負担を如何に減らすかと言う事。
どうやったら気分よくゴールを目指せるかと言う事。
相手の心理的影響を細かく配慮する「おもてなし」の心に通じる。
Courseraも受講環境の完成度は結構高く、快適に受講できる。
どうしてそれだけ強い動機付けになっているのかgamification視点から分析してみると面白そう。
[ゴール: 最終的な目的]
やはり本来の目的と言うのが最後は重要になる。
それが自分にとって価値が低ければgamificationの手法で一時的に動機付けしても長続きしない。
「関数型プログラミングについての理解を深めること」「Scalaに関する理解を深めること」と言う「知識獲得」がそもそもの目的としてベースにある。
[目標: 小目標、中目標]
最終的な目的が重要と分かっていても、人は目の前の欲求にすぐに負けてしまう。
最終的な目的に至る過程を細かい中間的な目標に置き換える事が重要。
(実はこの小目標自体はポイントを貯めるなど直接目的と結びついていなくてもOK)
中目標として、毎週のクラス(ビデオ講義とプログラム課題)がある。
プログラム課題は2週間、3週間の2段階期限と自動採点があり目標が明確化されている。
ビデオ講義が15分x4本程度に分割されてるので、個々のビデオが小目標になる。
さらにビデオ内の小クイズも小目標となる。
プログラム課題も数ステップに分かれていて小目標として機能している。
[可視化]
可視化による目標の明確化と目標達成へのフィードバクが重要。
所謂ポイントやバッジなどのリワードも可視化の一つと言える。
実施した内容に対して細かく直ぐにフィードバックが掛かるのが重要。
勉強の成果と言うのは形に見えにくいものだが、勉強したと言う努力を形にして実感したいと言うのもあるかもしれない。
プログラム課題の高速自動採点と採点結果表示
各ビデオ講義の視聴済チェックマーク表示
プログラム課題の2週間、3週間の2段階期限
コース終了条件の明確化
修了証の発行
掲示板のポイント
[オンボーディング]
何か始めるときは腰が重くなるのが普通。現状維持バイアスが働くので。
これを乗り切るために最初の取っ掛かりは特に簡単に楽しく出来ることが重要。
開始前の準備課題やチュートリアル、FAQ、掲示板で初めての実施を容易にしている。
[世界観]
構築された世界観に染まることが出来れば、現実世界では難しくてもその世界のルールにしたがって容易に出来る可能性がある。
特に仮想世界には現実世界のような制約がないので、現実世界よりその世界の理想に従って行動しやすい。
仮想世界の理想を目指す事と、ゴールの達成が間接的にリンクしていると良い。
Courseraでは特に独自の世界観は構築されていない??
[ソーシャル]
他人と刺激しあう事でモチベーションを高める。
他人からのメッセージや「いいね!」ボタンなどフィードバック。
他人へフィードバックする事も自分の組織への帰属意識を高めたり出来る。
他人の状況を見たり、他人から見られていると意識出来ることも重要。(モラルハザード)
掲示板(いいねボタンあり)、オフ会、講師や管理者からのメール、アナウンス
掲示板で他人の考えや状況を見ると刺激にはなる。もっと発信出来れば良いのだが。
[上級者向け]
[チューニング]
上級者しか達成できない難しいタスク(レアアイテム入手)で継続的な実施を啓発。
個別の状況に応じてタスクの難易度等を個別にチューニングする。
追加の学習資料の提示。掲示板で他人に教える。
FAQやチュートリアルや掲示板での質問で難易度をある程度コントロール。
講義ビデオの早見。スライド。サブタイトルで講義に掛ける工数をコントロール。
[おもてなし]
究極的にはゴールを目指す過程の心理的負担を如何に減らすかと言う事。
どうやったら気分よくゴールを目指せるかと言う事。
相手の心理的影響を細かく配慮する「おもてなし」の心に通じる。
Courseraも受講環境の完成度は結構高く、快適に受講できる。
2014年5月14日水曜日
Functional Programming Principles in Scala (Week 3)
Functional Programming Principles in Scala (Week 3: Data and Abstraction)
==== Lectures ====
Lecture 3.1 - Class Hierarchies
abstract classやsuper/sub classの説明。
binary treeを例にしているのでAssignmentに役たちそう。
今回もsubstitution(置き換え)を使ってメソッドの評価を説明していた。
Lecture 3.2 - How Classes Are Organized
package, scaladoc, trait, class hierarchy
import xxx.yyy.{aaa, bbb} で複数のクラスをimport出来る。
Any, AnyRef, AnyVal, Null, Nothing
if (true) 1 else false のtypeはAnyVal。1とfalseの共通の親クラスまで遡る。
?? traitもextendでもwithでも継承できるが、extendとwithをどうして分ける必要があるのか??
Lecture 3.3 - Polymorphism
type parameter: Cons Listを例に説明。
type erasure
scala, java, Haskell, ML, OCamlは実行時は型情報を保持していない。
C++ C# F#は実行時も型を保持している
polymorphism
subtyping: 継承によって実現する
generics: type parameterによって実現する。
==== Assignments ====
[Object-Oriented Sets]
?? abstraction classで実装すべきか、sub classで実装すべきかの問いがあるが??
?? 同じ内容のtweetが入力された場合の仕様は定義されている??
=> サポート外。
?? 同じ回数のretweetの場合のmostRetweetの仕様は実装依存?
=> 実装依存。どれを返しても問題はない。。
通常処理でexceptionを発生させるのは性能上良くない。別の方法にすべき。
accを使わなくても書けるが、使えば性能を上げられる。末尾再帰には拘らなくて良いみたい。
存在しないtweetをremoveした場合は元のTweetSetを返す。
内容の大小は.textのStringなので=,<,>が使える。
一回目の提出で7.09/10.00だった。。。
unit testで70/110。4つのテストでfailがあり理由はすべてtimeout。無限ループあり?
無限ループでは無さそう。実装したアルゴリズムの性能の問題。
Forums / Assignments / Week 3: Data and Abstraction objsets FAQ
に色々とヒントが書いてあった。性能に依存する所あり思ったより難しい。
2回目の提出で10/10獲得!!
==== Etc. ====
Lectureの途中でVideoに埋め込まれたQuizがあった。
Assignmentのソースのコメントにtypoが多過ぎる。。。
Lecture3.1のsubtitleが全然合っていなかった様な気がする。別物?
今回はlectureを1.25~1.75倍速で速見した。意味が分かったのか、元々知っていたかは?
Assignmentの一部の実装が決めきれずに時間が掛かってしまった。
あまり深く考えずにサクサク進めるべき。
Assignmentに関する議論はネタバレにならないようにdeadlineが過ぎてから行うべき?
性能が問題になるケースがあり、そこも考慮必要で思ったより難しい。
==== Log ====
2014/5/13 Lecture 3.1 Assignments 準備 00:40
2014/5/14 Lecture 3.2-3 00:50
2014/5/14 Assignments 03:00
2014/5/15 Assignments 03:30
==== Lectures ====
Lecture 3.1 - Class Hierarchies
abstract classやsuper/sub classの説明。
binary treeを例にしているのでAssignmentに役たちそう。
今回もsubstitution(置き換え)を使ってメソッドの評価を説明していた。
Lecture 3.2 - How Classes Are Organized
package, scaladoc, trait, class hierarchy
import xxx.yyy.{aaa, bbb} で複数のクラスをimport出来る。
Any, AnyRef, AnyVal, Null, Nothing
if (true) 1 else false のtypeはAnyVal。1とfalseの共通の親クラスまで遡る。
?? traitもextendでもwithでも継承できるが、extendとwithをどうして分ける必要があるのか??
Lecture 3.3 - Polymorphism
type parameter: Cons Listを例に説明。
type erasure
scala, java, Haskell, ML, OCamlは実行時は型情報を保持していない。
C++ C# F#は実行時も型を保持している
polymorphism
subtyping: 継承によって実現する
generics: type parameterによって実現する。
==== Assignments ====
[Object-Oriented Sets]
?? abstraction classで実装すべきか、sub classで実装すべきかの問いがあるが??
?? 同じ内容のtweetが入力された場合の仕様は定義されている??
=> サポート外。
?? 同じ回数のretweetの場合のmostRetweetの仕様は実装依存?
=> 実装依存。どれを返しても問題はない。。
通常処理でexceptionを発生させるのは性能上良くない。別の方法にすべき。
accを使わなくても書けるが、使えば性能を上げられる。末尾再帰には拘らなくて良いみたい。
存在しないtweetをremoveした場合は元のTweetSetを返す。
内容の大小は.textのStringなので=,<,>が使える。
一回目の提出で7.09/10.00だった。。。
unit testで70/110。4つのテストでfailがあり理由はすべてtimeout。無限ループあり?
無限ループでは無さそう。実装したアルゴリズムの性能の問題。
Forums / Assignments / Week 3: Data and Abstraction objsets FAQ
に色々とヒントが書いてあった。性能に依存する所あり思ったより難しい。
2回目の提出で10/10獲得!!
==== Etc. ====
Lectureの途中でVideoに埋め込まれたQuizがあった。
Assignmentのソースのコメントにtypoが多過ぎる。。。
Lecture3.1のsubtitleが全然合っていなかった様な気がする。別物?
今回はlectureを1.25~1.75倍速で速見した。意味が分かったのか、元々知っていたかは?
Assignmentの一部の実装が決めきれずに時間が掛かってしまった。
あまり深く考えずにサクサク進めるべき。
Assignmentに関する議論はネタバレにならないようにdeadlineが過ぎてから行うべき?
性能が問題になるケースがあり、そこも考慮必要で思ったより難しい。
==== Log ====
2014/5/13 Lecture 3.1 Assignments 準備 00:40
2014/5/14 Lecture 3.2-3 00:50
2014/5/14 Assignments 03:00
2014/5/15 Assignments 03:30
2014年5月12日月曜日
Programming in Scala, First Edition Chapter 18
18. Stateful Objects
変化するオブジェクトをモデル化する場合は自然とstatefulになる。
immutableに出来るならそのが望ましい場合が多いが。
scalaではmutableなobjectも制約なく使える。
デジタル回路のシミュレーションのためのDSL(domain specific language)も例上げる。
stateful objectを使う。
DES(discrete event simulation) 離散事象シミュレーション
18.1 What makes an object stateful?
純粋関数的かstatefulかは実装を見なくても振る舞いから分かる。
純粋関数的ならメソッド実行の結果は毎回同じになる。
statefulならそれまでの操作に応じて異なる結果になる。
銀行口座をモデル化したobjectがその例。
varがあればstatefulか?
簡単には判断出来ない。
varがなくても呼び出しているobjectがstatefulならstatefulになる。
varがあっても振る舞いが常に同じなら純粋関数的(stateless)。
計算結果を必要に応じてcacheするような場合は外部からはstatelessに見える。
外部からstatelessに見えればstateless
18.2 Reassignable variables and properties
書き換え可能な変数の基本操作は参照と設定。
non-privateのvarのfieldには自動的にgetter,setterメソッドが追加される。
実際はfieldが内部的なprivate[this]な別名に変換されている。
class X {
var x: Int = _
}
だと
class X {
private[this] var xx: Int = _
def x: Int = xx
def x_=(a: Int) { xx = a }
}
に変換される。
x = a が x_=(a) にコンパイラでsyntactic sugarで解釈される。
private[this]はこのクラスからしかアクセス出来なくしている。
x: Int = _ はxをIntの初期値(0)で初期化している。
x: Int とは書けない。
これはabstract variableの宣言となりclass Xが抽象クラスになる。
自動生成されるgetter, setterのアクセスは元のvarのアクセス制限による。
varがpublicならpublic, varがprotectedならprotected。
getter, setterメソッドさえ定義すれば、実際のfieldの有無はどうでも良い。
使う側からはnon-privateなvarのfieldは直接見えずにメソッドしか見えないので。
def field: T = {...}, def field_=(x: T) {...} が定義されていれば良い。
メソッドのbodyは自由に定義出来る。
意味的には値を返したり、設定している様に見せる必要はあるが。
値のチェックや、別のオブジェクトへの通知や、ログ記録等をやっても良い。
18.3 Case study: Discrete event simulation
stateful objectsとfirst-class function valuesの組み合わせ方法を見る。
デジタル回路のシミューレータの設計と実装。
デジタル回路のためのDSL(言語)。
離散事象シミュレーションのための簡単で一般的なフレームワーク。
シミュレーションモデルの構築のためのライブラリ。
フレームワークを利用したシミュレーションモデルの構築。
Structure and Interpretation of Computer Programs by Abelson and Sussman
これの課題をscheme版からscala版に変更して使う。
18.4 A language for digital circuits
WireとInverter, And-gate, Or-gateのfunction boxからなる。
Wireはtrue, falseの2値のクラス。
各gateは入出力がWireのメソッド。
gateはdelayを持っていて結果のoutputは少し後になる。
gateとWireの組み合わせでより複雑な回路も表現できる。
加算等
各メソッドの名前は通例では動詞だが、今回は名詞。
副作用がある。DSLの特性による。
18.5 The Simulation API
抽象クラスとしてSimulationのフレームワークを定義する。
個々のSimulationはそのサブクラスで定義して実行する。
type Action = () => Unit
型を表すalias。Section 20.6
private var curtime: Int = 0
def currentTime: Int = curtime
curtimeをクラスの外からは参照のみで変更出来なくする。
case class WorkItem(time: Int, action: Action)
caseにするとfactory methodやparameterのaccessorが自動生成されて便利。
nested classについてはSection 20.7
def afterDelay(delay: Int)(block: => Unit) {...}
by-name parameterでblockを評価せずに渡す。
curry化によってbuilt-inのcontrol structureの様に書ける。
(agenda: @unchecked) match { case item :: rest => ... }
このmatchではagendaから先頭要素itemを取り出すことのみを行う。
agendaがemptyにならないと分かっているのでcase _は書いていない。
compilerがwarning: match is not exhaustive!を出すので@uncheckedで抑制。
Section 15.5
18.6 Circuit Simulation
18.5のframeworkから18.4のDSLを定義する。
delayは個々の回路に依存するのでabstraction classとして定義する。
actions foreach (_ ()) // actions: List[() => Unit]
actionsの要素が関数値なので、_ ()で各要素の関数値の関数適用を行うと言う事。
_ () は f => f() の短縮形。関数値を取ってそれを適用する関数値。
val input1, input2, sum, carry = new Wire
input1, input2, sum, carryに対して別々にnewでインスタンスが割り当てられる。
val input1 = mew Wire; val input2 = new Wire;... と同じ意味。
18.7 Conclusion
mutable state and higher-order functions
Mutable state は 状態を持った物理対象のモデルに使える。
Higher-order functions は特定のポイントでのアクションを実施する。
circuit simulationは上記の好例。更に複雑な回路を試してみるのも良い。
変化するオブジェクトをモデル化する場合は自然とstatefulになる。
immutableに出来るならそのが望ましい場合が多いが。
scalaではmutableなobjectも制約なく使える。
デジタル回路のシミュレーションのためのDSL(domain specific language)も例上げる。
stateful objectを使う。
DES(discrete event simulation) 離散事象シミュレーション
18.1 What makes an object stateful?
純粋関数的かstatefulかは実装を見なくても振る舞いから分かる。
純粋関数的ならメソッド実行の結果は毎回同じになる。
statefulならそれまでの操作に応じて異なる結果になる。
銀行口座をモデル化したobjectがその例。
varがあればstatefulか?
簡単には判断出来ない。
varがなくても呼び出しているobjectがstatefulならstatefulになる。
varがあっても振る舞いが常に同じなら純粋関数的(stateless)。
計算結果を必要に応じてcacheするような場合は外部からはstatelessに見える。
外部からstatelessに見えればstateless
18.2 Reassignable variables and properties
書き換え可能な変数の基本操作は参照と設定。
non-privateのvarのfieldには自動的にgetter,setterメソッドが追加される。
実際はfieldが内部的なprivate[this]な別名に変換されている。
class X {
var x: Int = _
}
だと
class X {
private[this] var xx: Int = _
def x: Int = xx
def x_=(a: Int) { xx = a }
}
に変換される。
x = a が x_=(a) にコンパイラでsyntactic sugarで解釈される。
private[this]はこのクラスからしかアクセス出来なくしている。
x: Int = _ はxをIntの初期値(0)で初期化している。
x: Int とは書けない。
これはabstract variableの宣言となりclass Xが抽象クラスになる。
自動生成されるgetter, setterのアクセスは元のvarのアクセス制限による。
varがpublicならpublic, varがprotectedならprotected。
getter, setterメソッドさえ定義すれば、実際のfieldの有無はどうでも良い。
使う側からはnon-privateなvarのfieldは直接見えずにメソッドしか見えないので。
def field: T = {...}, def field_=(x: T) {...} が定義されていれば良い。
メソッドのbodyは自由に定義出来る。
意味的には値を返したり、設定している様に見せる必要はあるが。
値のチェックや、別のオブジェクトへの通知や、ログ記録等をやっても良い。
18.3 Case study: Discrete event simulation
stateful objectsとfirst-class function valuesの組み合わせ方法を見る。
デジタル回路のシミューレータの設計と実装。
デジタル回路のためのDSL(言語)。
離散事象シミュレーションのための簡単で一般的なフレームワーク。
シミュレーションモデルの構築のためのライブラリ。
フレームワークを利用したシミュレーションモデルの構築。
Structure and Interpretation of Computer Programs by Abelson and Sussman
これの課題をscheme版からscala版に変更して使う。
18.4 A language for digital circuits
WireとInverter, And-gate, Or-gateのfunction boxからなる。
Wireはtrue, falseの2値のクラス。
各gateは入出力がWireのメソッド。
gateはdelayを持っていて結果のoutputは少し後になる。
gateとWireの組み合わせでより複雑な回路も表現できる。
加算等
各メソッドの名前は通例では動詞だが、今回は名詞。
副作用がある。DSLの特性による。
18.5 The Simulation API
抽象クラスとしてSimulationのフレームワークを定義する。
個々のSimulationはそのサブクラスで定義して実行する。
type Action = () => Unit
型を表すalias。Section 20.6
private var curtime: Int = 0
def currentTime: Int = curtime
curtimeをクラスの外からは参照のみで変更出来なくする。
case class WorkItem(time: Int, action: Action)
caseにするとfactory methodやparameterのaccessorが自動生成されて便利。
nested classについてはSection 20.7
def afterDelay(delay: Int)(block: => Unit) {...}
by-name parameterでblockを評価せずに渡す。
curry化によってbuilt-inのcontrol structureの様に書ける。
(agenda: @unchecked) match { case item :: rest => ... }
このmatchではagendaから先頭要素itemを取り出すことのみを行う。
agendaがemptyにならないと分かっているのでcase _は書いていない。
compilerがwarning: match is not exhaustive!を出すので@uncheckedで抑制。
Section 15.5
18.6 Circuit Simulation
18.5のframeworkから18.4のDSLを定義する。
delayは個々の回路に依存するのでabstraction classとして定義する。
actions foreach (_ ()) // actions: List[() => Unit]
actionsの要素が関数値なので、_ ()で各要素の関数値の関数適用を行うと言う事。
_ () は f => f() の短縮形。関数値を取ってそれを適用する関数値。
val input1, input2, sum, carry = new Wire
input1, input2, sum, carryに対して別々にnewでインスタンスが割り当てられる。
val input1 = mew Wire; val input2 = new Wire;... と同じ意味。
18.7 Conclusion
mutable state and higher-order functions
Mutable state は 状態を持った物理対象のモデルに使える。
Higher-order functions は特定のポイントでのアクションを実施する。
circuit simulationは上記の好例。更に複雑な回路を試してみるのも良い。
2014/5/10-12
==== 2014/5/10 ====
早起きできた!!
畑の学校。トウモロコシとネギを植えた。ミニトマトの苗とネギの苗をもらった!!
いちごの勉強机用の椅子を見に行った。思ったより色々な種類があった。
一日前の母の日を子供たちが開催。ハニーホットーケーキとハニーヨーグルトとハニーミルク。
いちごが母の日プレゼントに自主学習を頑張った!!
emacsにAspell導入。
==== 2014/5/11 ====
子供と一緒にたくさん寝られた。早起きも出来た!!
久々にトッキュウジャーとガイムを見た。ストーリーが難しすぎて分からない。。。
#codecademy 50streak達成!!
#coursera #posa-002 Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Syste スタート!!
#emacs window8のgnupackで日本語の入力が上手く行かないときがある。
立ち上げてからwindows key2回押してからCtrl-\で日本語にすれば入るような気がする。
大河ドラマを3話まとめて見れた。
いちごがお友達と遊ぶために前の日から宿題などを頑張って片づけていた。無事に遊べて良かった。
==== 2014/5/12 ====
早寝早起き出来た!!朝いちごのお見送りが出来た!!
あんずが着替えの準備をしてくれた。
子供が起きている時間に帰れた。
[100de名著]
孫子の第1-2回を見た。
そんなに目新しい話はなかった。
ただ、二千数百年前から人と言うのはあまり変わっていない部分も多いなあと感じた。
[eclipse]
OSGi framework上に構築されている。
javaのモジュールを動的に追加削除するための仕組み。
バージョン管理、依存関係管理、セキュリティ(署名)機能もある。
eclipseのruntaime自体もOSGiの部品であるハンドル。
[Coursera]
期限があるとズルズル実施しないのを防げる面では良い。
[データサイエンティスト]
と言う業種が注目されているらしい。
所謂ビッグデータの分析、活用を出来る人の事らしい。
Hadoop/DWH/BI
問題を「見つける」「解く」「使わせる」の内「見つける」「使わせる」が重要。
プロなら「解く」のは出来て当たり前。
[bitcoinと計算資源本位体制]
どの程度の計算資源を持っているかの指標となる?
でも、bitcoinを取引しても計算資源が取引されるわけでもない気がする。
また、bitcoinのマイニングに計算資源を使うのは資源の無駄遣いでは?
[Programming in Scala, First Edition]
2014/5/12 80 chapter18 7/7 chapter18 1/9
早起きできた!!
畑の学校。トウモロコシとネギを植えた。ミニトマトの苗とネギの苗をもらった!!
いちごの勉強机用の椅子を見に行った。思ったより色々な種類があった。
一日前の母の日を子供たちが開催。ハニーホットーケーキとハニーヨーグルトとハニーミルク。
いちごが母の日プレゼントに自主学習を頑張った!!
emacsにAspell導入。
==== 2014/5/11 ====
子供と一緒にたくさん寝られた。早起きも出来た!!
久々にトッキュウジャーとガイムを見た。ストーリーが難しすぎて分からない。。。
#codecademy 50streak達成!!
#coursera #posa-002 Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Syste スタート!!
#emacs window8のgnupackで日本語の入力が上手く行かないときがある。
立ち上げてからwindows key2回押してからCtrl-\で日本語にすれば入るような気がする。
大河ドラマを3話まとめて見れた。
いちごがお友達と遊ぶために前の日から宿題などを頑張って片づけていた。無事に遊べて良かった。
==== 2014/5/12 ====
早寝早起き出来た!!朝いちごのお見送りが出来た!!
あんずが着替えの準備をしてくれた。
子供が起きている時間に帰れた。
[100de名著]
孫子の第1-2回を見た。
そんなに目新しい話はなかった。
ただ、二千数百年前から人と言うのはあまり変わっていない部分も多いなあと感じた。
[eclipse]
OSGi framework上に構築されている。
javaのモジュールを動的に追加削除するための仕組み。
バージョン管理、依存関係管理、セキュリティ(署名)機能もある。
eclipseのruntaime自体もOSGiの部品であるハンドル。
[Coursera]
期限があるとズルズル実施しないのを防げる面では良い。
[データサイエンティスト]
と言う業種が注目されているらしい。
所謂ビッグデータの分析、活用を出来る人の事らしい。
Hadoop/DWH/BI
問題を「見つける」「解く」「使わせる」の内「見つける」「使わせる」が重要。
プロなら「解く」のは出来て当たり前。
[bitcoinと計算資源本位体制]
どの程度の計算資源を持っているかの指標となる?
でも、bitcoinを取引しても計算資源が取引されるわけでもない気がする。
また、bitcoinのマイニングに計算資源を使うのは資源の無駄遣いでは?
[Programming in Scala, First Edition]
2014/5/12 80 chapter18 7/7 chapter18 1/9
脱出! 暗闇プロジェクト第1-4回を読んで
日経コンピュータの「脱出! 暗闇プロジェクト」の第1-4回を読んだ。
教科書通には対処出来ない場合についての話があり、とても共感出来る内容が多かった。
[優先順位は理屈ではなく「声の大きさ」で]
理屈の通じない相手もいる。
理屈は論理バイアスで偏っている場合も多々ある。
目的が共有出来ていれば「声の大きさ」もそれなりに妥当性がある。
[矛盾する要求は解決せず「先送り」で]
[合意形成が難しい場合は「曖昧なまま」で]
その場ではお互いムキになって感情的に合意出来ない場合も多い。
可能性やそもそも論や理想論を言っているだけで、今回のプロジェクトでは妥協出来る部分も多い。
プロジェクト上諦めなくてはならないタイミングが来ると自然と妥協出来る場合も多い。
[半年前の合意は「期限切れ」]
古い合意は反故にされやすいので、定期的に確認してリフレッシュする必要あり。
[重要な会議は事前に根回しして「儀式」に]
会議では各部門の代表として建前を言う必要がある場合が多い。
事前にキーパーソンから個別に妥協点に関して根回しで同意と取っておく。
[理不尽さをあえて受け入れる]
上手く行っていないのだから理想とかけ離れているのは当たり前。
理想(べき論)とのギャップを呑み込めるのかが重要。
他人の考えを変えるより自分が折れる方が容易。
[KKD(勘、経験、度胸)]
これが重要だと言うのも共感出来る内容。
プロセス(方法論)もプロジェクト運営のツールとしては重要ではある。
PSPでも「データが実務者の感覚と合っている事」を重要視している。。
データは勘を修正、補完するために重要だが、勘と経験を上回ることは無さそう。
[不安は解消せずに上手く付き合う]
リスク管理は難しい。特にリスクを受容すると言う事に関しては。
リスクを受容の合意が形成出来ない場合は誰かが腹を括る必要があるかもしれない。
[モジュール分割を人間関係で決める]
仲の悪い人同士が共同作業しなくて良いようにモジュールを分割すると言う事。
モジュール分割は常識的には開発対象によって最適に分割すると言う事になっている。
実際はある程度に正しい分割は複数考えられるのでそこからメンバの特性に合ったものを選べば良いと思う。
作った人が違えば別のものになると言うのは、文章作成と一緒で当たり前の事。
[課題解決に劇薬は避ける]
問題メンバーがいてもなだめすかしながら穏便に進める方が無難な場合が多い。
そのメンバーを交代させても別の問題が発生する場合が多い。
大切なのは原因を取り除く事よりも問題のある状態を捌ける様になること。
[全メンバーで全情報を共有する]
[メンバー管理は放置プレーで]
担当者レベルが自律的に判断して動けるようにする。個々人に任せる。
[辻褄が合いすぎる報告書は信用しない]
辻褄を合わせるために改竄されている可能性を疑う。
[苦手なメンバーをチームに入れる]
メンバーを多様性を持たせてクロスチェックを有効に働くようにする。
教科書通には対処出来ない場合についての話があり、とても共感出来る内容が多かった。
[優先順位は理屈ではなく「声の大きさ」で]
理屈の通じない相手もいる。
理屈は論理バイアスで偏っている場合も多々ある。
目的が共有出来ていれば「声の大きさ」もそれなりに妥当性がある。
[矛盾する要求は解決せず「先送り」で]
[合意形成が難しい場合は「曖昧なまま」で]
その場ではお互いムキになって感情的に合意出来ない場合も多い。
可能性やそもそも論や理想論を言っているだけで、今回のプロジェクトでは妥協出来る部分も多い。
プロジェクト上諦めなくてはならないタイミングが来ると自然と妥協出来る場合も多い。
[半年前の合意は「期限切れ」]
古い合意は反故にされやすいので、定期的に確認してリフレッシュする必要あり。
[重要な会議は事前に根回しして「儀式」に]
会議では各部門の代表として建前を言う必要がある場合が多い。
事前にキーパーソンから個別に妥協点に関して根回しで同意と取っておく。
[理不尽さをあえて受け入れる]
上手く行っていないのだから理想とかけ離れているのは当たり前。
理想(べき論)とのギャップを呑み込めるのかが重要。
他人の考えを変えるより自分が折れる方が容易。
[KKD(勘、経験、度胸)]
これが重要だと言うのも共感出来る内容。
プロセス(方法論)もプロジェクト運営のツールとしては重要ではある。
PSPでも「データが実務者の感覚と合っている事」を重要視している。。
データは勘を修正、補完するために重要だが、勘と経験を上回ることは無さそう。
[不安は解消せずに上手く付き合う]
リスク管理は難しい。特にリスクを受容すると言う事に関しては。
リスクを受容の合意が形成出来ない場合は誰かが腹を括る必要があるかもしれない。
[モジュール分割を人間関係で決める]
仲の悪い人同士が共同作業しなくて良いようにモジュールを分割すると言う事。
モジュール分割は常識的には開発対象によって最適に分割すると言う事になっている。
実際はある程度に正しい分割は複数考えられるのでそこからメンバの特性に合ったものを選べば良いと思う。
作った人が違えば別のものになると言うのは、文章作成と一緒で当たり前の事。
[課題解決に劇薬は避ける]
問題メンバーがいてもなだめすかしながら穏便に進める方が無難な場合が多い。
そのメンバーを交代させても別の問題が発生する場合が多い。
大切なのは原因を取り除く事よりも問題のある状態を捌ける様になること。
[全メンバーで全情報を共有する]
[メンバー管理は放置プレーで]
担当者レベルが自律的に判断して動けるようにする。個々人に任せる。
[辻褄が合いすぎる報告書は信用しない]
辻褄を合わせるために改竄されている可能性を疑う。
[苦手なメンバーをチームに入れる]
メンバーを多様性を持たせてクロスチェックを有効に働くようにする。
プロマネに役立つ「内省術」最終回を読んで
日経コンピュータの内省術の最終回を読んだ。
[実践の繰り返し]
良いと思う改善アイデアが浮かんでも一度で上手く行くほど甘くないので、繰り返し挑戦し続けられるかが重要。ポイントは下記の3点。
[失敗を受け入れる]
[小さな変化を見逃さない]
[自分で考えて試行錯誤する]
[ソーシャルパワー]
ポイントの実施にはソーシャルパワーを活用出来ると良い。これはgamificationとも通じる所。
例えば同様の悩みを持つリーダクラスで定期的なワークショップを持つもの有効。
新しい気づきが得られたり、自分の考えを発言することで整理出来たり、他人の事例なら冷静に見れるので、自分の事例にフィードバック出来たりする。
[気軽に始めてみる]
最後に述べられていたのが気軽に実践してみると言う事。
特にこうしなければならないとかに捕らわれずに、やり易いやり方で。
そうは言っても結構敷居は高く感じる。
何処かで仕入れて良さそうだからやってみて失敗した例は沢山見てきた気がする。。。
ただ、これ自体も「失敗を受け入れて繰り返し挑戦する」の適用対象になりそうだが。
[メモの取り方]
具体例の紹介のなかで、思いついたことを直ぐにメモ出来る様にノートを持ち歩いていると話や、それに対して、電子化した方が追記検索等が出来て便利等の別の視点からの指摘もあり面白かった。
[内省術の連載全体を通して]
個々のパーツの考え方は普通の事で、特に目新しいと言う事はなかった。
別の言い方をすると、その「普通の事」を如何に実践するかが重要と言う事。
個々のパーツを一連の流れのフレームワークの例として紹介ているのは実践への敷居を下げるという意味で有用。
これはPSPのスクリプト作成と実践を分けるという考えに通じる。
紹介されていた事例が具体的で共感できる内容で、説得力があり良かった。
[実践の繰り返し]
良いと思う改善アイデアが浮かんでも一度で上手く行くほど甘くないので、繰り返し挑戦し続けられるかが重要。ポイントは下記の3点。
[失敗を受け入れる]
[小さな変化を見逃さない]
[自分で考えて試行錯誤する]
[ソーシャルパワー]
ポイントの実施にはソーシャルパワーを活用出来ると良い。これはgamificationとも通じる所。
例えば同様の悩みを持つリーダクラスで定期的なワークショップを持つもの有効。
新しい気づきが得られたり、自分の考えを発言することで整理出来たり、他人の事例なら冷静に見れるので、自分の事例にフィードバック出来たりする。
[気軽に始めてみる]
最後に述べられていたのが気軽に実践してみると言う事。
特にこうしなければならないとかに捕らわれずに、やり易いやり方で。
そうは言っても結構敷居は高く感じる。
何処かで仕入れて良さそうだからやってみて失敗した例は沢山見てきた気がする。。。
ただ、これ自体も「失敗を受け入れて繰り返し挑戦する」の適用対象になりそうだが。
[メモの取り方]
具体例の紹介のなかで、思いついたことを直ぐにメモ出来る様にノートを持ち歩いていると話や、それに対して、電子化した方が追記検索等が出来て便利等の別の視点からの指摘もあり面白かった。
[内省術の連載全体を通して]
個々のパーツの考え方は普通の事で、特に目新しいと言う事はなかった。
別の言い方をすると、その「普通の事」を如何に実践するかが重要と言う事。
個々のパーツを一連の流れのフレームワークの例として紹介ているのは実践への敷居を下げるという意味で有用。
これはPSPのスクリプト作成と実践を分けるという考えに通じる。
紹介されていた事例が具体的で共感できる内容で、説得力があり良かった。
2014年5月9日金曜日
現状維持バイアス、問題先送りバイアス
ついつい、やらなくてはならないことをズルズルと先送りしてしまうことが多い。
今日、些細な例について考えた。
朝はNHK総合を見ているのだが、家を出るのが8時過ぎになることが多い。
8時5分位に出るとちょうど良くて、それより遅くなると多少走ったりする必要がある。
ここで問題になるのが毎日見ている朝ドラが流れていると言う事。
録画していて帰ってから見直しているので、朝見る必要はないのだが、ついつい見入ってしまって、家を出るのがギリギリになってしまう。
これは行動経済学で言うところの「現状維持バイアス」「問題先送りバイアス」が働いているとも考えられる。
毎朝朝ドラを途中で打ち切って家を出ると言うのは、バイアスを打ち破るためのちょっとしたトレーニングになっているとも言えなくはないかも。
今日、些細な例について考えた。
朝はNHK総合を見ているのだが、家を出るのが8時過ぎになることが多い。
8時5分位に出るとちょうど良くて、それより遅くなると多少走ったりする必要がある。
ここで問題になるのが毎日見ている朝ドラが流れていると言う事。
録画していて帰ってから見直しているので、朝見る必要はないのだが、ついつい見入ってしまって、家を出るのがギリギリになってしまう。
これは行動経済学で言うところの「現状維持バイアス」「問題先送りバイアス」が働いているとも考えられる。
毎朝朝ドラを途中で打ち切って家を出ると言うのは、バイアスを打ち破るためのちょっとしたトレーニングになっているとも言えなくはないかも。
ぼんやりと移動する時間
出張で移動中に考えたとこと。
普段通らない場所を通るとそこから色々と考えるネタになる。
テレビでも普段見ないものを見ているはずだがテレビの場合はあまり考えが浮かばない。
これはテレビでは何らかの情報を得ようとしているので、それに意識が奪われているから?
単なる移動だと特定の目的の情報処理がある訳ではないので、色々と想起されやすいのかもしれない。
これは唯ぼんやりと移動する時間も無駄ではないと言う事か。
普段通らない場所を通るとそこから色々と考えるネタになる。
テレビでも普段見ないものを見ているはずだがテレビの場合はあまり考えが浮かばない。
これはテレビでは何らかの情報を得ようとしているので、それに意識が奪われているから?
単なる移動だと特定の目的の情報処理がある訳ではないので、色々と想起されやすいのかもしれない。
これは唯ぼんやりと移動する時間も無駄ではないと言う事か。
Programming in Scala, First Edition Chapter 17
17. Collections
scalaはcollectionsの豊富なライブラリを持っている。
既にarray, list, set, mapについて見て来た。
collectionsの継承階層を見る。
色々なcollectionsの使い方を見る。
speed, space, requirements on input dataのトレードオフ等。
17.1 Overview of the library
scalaのcollectionsライブラリは多くのclass, traitを巻き込んでいる。
全体像をScaladocから描き出すのは簡単ではない。
全体像を理解するために必要なtraitのみを下記に示す。
+- Seq // 順番ありの並び(sequence), array, list
Iterable <-+- Set // 重複無しの要素の集まり。重複は==で決める。
+- Map // keyとvalueの組の集まり。
Iterable
Iterable[A]のIterator[A]を生成するメソッドを有する。
def elements: Iterator[A]
elementsは唯一の抽象メソッド。
具象メソッドも多数定義している。
全てelementsが返すIteratorを使用して実装されている。
Iterator
Iterableと同じ多数のメソッドを持っている。
継承階層は異なる。
AnyRef <--- Iterator
Iterableは繰り返しが可能な型表現する。
** Iteratorを生成出来る型。
複数回走査されるかもしれない。
Iteratorは繰り返しに使われるメカニズムそのもの。
一回しか走査出来ない。
再度走査した場合はもういちどIteratorを生成する必要ある。
next, hasNext
多くの具象メソッドがnext, hasNextを使ってIteratorに実装されている。
next, hasNextは抽象メソッドでmix-inする側で定義する。
17.2 Sequences
trait Seqを継承している、順序付きのデータ列のクラス。
1番目、2番目、103番目などの順番が存在する。
Lists
一番重要なsequence type。
先頭への追加削除は早い。
後ろの要素へのアクセスはリストを走査するので遅い。
この実装は多くのアルゴリズムを実装するのに適している。
パターンマッチングなど。
Arrays
任意の要素に効率良くアクセス、更新できる。
0始まりのインデックス。
大きさは固定。
要素は変更可能(mutalble)
javaの配列と互換性がある。
ただし()で要素にアクセスするので注意。
List buffers
import scala.collection.mutable.ListBuffer
mutable
先頭に加えて末尾にも効率良く要素を追加できる。
+= append (末尾に追加)
+: prepend (先頭に追加)
目的のリストを生成したらtoListでListを取得出来る。
?? これが主な使い方? ListからListBuffersへの変換は?
末尾再帰以外の場合のstack overflowを避けるためにも使える。
再帰の代わりにforやwhileとListBufferを組み合わせて使う。Section 22.2
Array buffers
import scala.collection.mutable.ArrayBuffer
長さを変更可能Array
Arrayで出来ることもほとんど実施可能。少しだけ遅い。
先頭と末尾から追加(+=, +:)削除(-=)可能。
平均固定時間で実行できるが、メモリ確保のために線形時間が掛かる場合もある。
?? 末尾から削除のメソッドが分からない。?
Queues
mutable, immutable両方のクラスがある。
importや階層を明示的に指定して使い分ける。
import scala.collection.immutable.Queue
scala> val has1 = empty.enqueue(1)
scala> val has123 = has1.enqueue(List(2, 3))
scala> val (element, has23) = has123.dequeue
import scala.collection.mutable.Queue
scala> val queue = new Queue[String]
scala> queue += "a"
scala> queue ++= List("b", "c")
scala> queue.dequeue
Stacks
mutable, immutable両方のクラスがある。
importや階層を明示的に指定して使い分ける。
import scala.collection.immutable.Stack
import scala.collection.mutable.Stack
push, pop, top(peekの意味)でアクセスする。
Strings (via RichString)
string自体はcollectionではない。
stringにない操作を行った場合RichStringにimplicit conversionされる。
Predefにimplicit conversionが定義されている。
RichStringはSeq[Char]
17.3 Sets and maps
mutableとimmutable両方のtraitがある。
MapやSetという名前のtraitは3種類ある。
defaultではimmutableのtraitが使われる。
immutableを推奨する意図があるから。
** 色々できるが黙って使うと推奨になると言うのが良い。
object Predef {
type Set[T] = scala.collection.immutable.Set[T]
type Map[K, V] = scala.collection.immutable.Map[K, V]
val Set = scala.collection.immutable.Set
val Map = scala.collection.immutable.Map
// ...
}
上記のPredefでの定義でdefaultの動作を決めている。
type~はfull nameのalias
val~はsingleton objectへの参照を保存。
mutable, immutable両方使いたいとき。
import scala.collection.mutable
val mutaSet = mutable.Set(1, 2, 3)
val immutaSet = Set(1, 2, 3)
Using sets
重複なしの要素を含むcollection
重複は==メソッドで判定する。
** Mapのkey部分のみと似ている。
immutable
+, - で要素の追加削除
++, -- で要素Listの追加削除
mutable
+=, -= で要素の追加削除
++=, --= で要素Listの追加削除
clear で全要素削除
共通
Set(1, 2, 3)で生成
Set.empty[T]で空のSetを生成
size, contains
Using maps
keyとvalueの両方の型指定が必要
var m = mutable.Map.empty[String, Int]
keyとvalueの組の辞書、連想配列。
配列はkeyが0始まりで連続の整数のMapと似ている。
値の設定、参照はArrayと同様。
m("hoge") = 1, val i = m("hoge")
key -> value
(key, value): Tuple2[K, V] のsyntactic sugar。
immutable
+, - で要素の追加削除
++, -- で要素Listの追加削除
mutable
+=, -= で要素の追加削除
++=, --= で要素Listの追加削除
m(k) = v
共通
Map(k1 -> v1, k2 -> v2, ...)
Map.empty[K, V]
v = m(k)
m.keySet でキーのSet, Set(k1, k2, ...)
m.keys, m.values でキー、値のIterator
size, contains, isEmpty
Default sets and maps
mutable
defaultではHashSet, HashMapなどが使われる。
効率良いO(1)のアクセスが可能。
immtable
5より小さい場合は効率化のため各サイズに合わせてた専用のクラスが使われる。
たとえば、scala.collection.immutable.Set3 等。
5以上の場合はmutableと同様にHashSetなどが使われる。
Sorted sets and maps
immutableのSetもしくはMapのkeyに対して順番に並べられたSortedSet,Mapがある。
mutableはなし
実装はred-black treeをつかったTreeSet, Mapがある。
red-black treeはself-balancing binary search tree
順序はOrdered traitをmix-inするかimplicit conversion出来るtypeを使う。
順序通り走査ができるIteratorを使える。
Synchronized sets and maps
thread-safeなMapを使いたい場合あはSynchronizedMap traitをmix-inする。
new HashMap[String, String] with SynchronizedMap[String, String] {
override def default(key: String) = "Why do you want to know?"
}
コンパイラはHashMapにSynchronizedMapをmix-inした人工サブクラスを生成。
defaultメソッドのoverrideも出来る。
keyが存在しない時に行う動作を定義できる。
newでそのインスタンスを生成する。
java.util.concurrentが使える場合もある。
unsynchronized collectionsをScala actorsと一緒に使う方法もある。Chapter 30
17.4 Selecting mutable versus immutable collections
mutableとimmutableどちらが良いかはケースバイケース。
迷ったらimmutableにするのを推奨。後で必要になったらmutableに変更する。
mutableで作ってあるコードが分かり難かったらimmutableにした方が良いかも。
特にちゃんとコピーを取っているか心配だったり誰が変更するのかきになるとき。
mutableとimmutableだとimmutableの方が小さくて早い。
mutableのHashMapは空で80byte, 各要素16byteのオーバーヘッドあり
immutableだと空は一つのオブジェクト共有するのでポインタ領域のみ。
さらに1~4要素は個別タイプがあるので16~40byteしか使わない。
少ない要素数ならimmutableを使った方が効率が良い。
mutableからimmutableへの変更
immutableは+=などの=を使ったメソッドが定義されていない。
a += b がない場合はsyntactic sugarで a = a + b と解釈される。
a はvar, mutableである必要がある。
+=だけではなくて、=を使ったすべてのメソッドに適用される。
collectionに限らず全ての型に対してこのsyntactic sugarを使える。
17.5 Initializing collections
コレクションの初期化方法についての考察。
factory methodに初期要素を渡す。
companion objectのapply methodを使う。
一番一般的な方法。
要素の型については通常はコンパイラの型推論に従えば問題ない。
明示的な型指定をした方が良い場合もある。
初期要素よりも上位の型を指定したい場合等。
特に後から要素が変更になるmutableの場合。
他のコレクションの要素で初期化したい場合。
空のコレクションを作って++でListを渡して作成する。
TreeSet[String]() ++ List("c", "b", "a")
Converting to array or list
toArrayやtoListを実行すれば良い。
順序は変換前のcollectionのIteratorの順序になる。
初期化に使ったList等の順に戻る訳ではない。
TreeSet[String]() ++ List("c", "b", "a").toList => List("a", "b", "c")
通常は全要素のコピーになるので大量だと時間が掛かる。
少ない要素数であればあまり気にする必要はない。
?? 少ない要素の場合が多いと言いたい?
Converting between mutable and immutable sets and maps
mutable<->immutableで変換したい場合も空のコレクションと++メソッドが使える。
変換後のからのコレクションに++で変換前のコレクションを追加する。
17.6 Tuples
Tuple少ない固定数の要素の組を一つにまとめて扱うためのもの。
複数の型を混ぜて格納出来る。
List[Any]やArray[Any]も色々な型を格納している様に見えるが、そうではない。
Anyと言う単一の型を格納しているだけ。Anyに適用出来ることしか出来ない。
val x :: y :: z :: nil = List[Any](1, 2, "abc")
val a = x + y // 出来ない
val b = z.toList // 出来ない
同等のことを実施するためにはdown castが必要。
Tuple複数の型を格納出来る。
それぞれの要素にはその型に適用できることが出来る。
val (x, y, z) = (1, 2, "abc")
val a = x + y // 出来る
val b = z.toList // 出来る
down castしなくても型情報が保持されているので問題ない。
意味的にまとまりのない複数の値を組み合わせて扱いたい場合に便利。
複数の値を返すメソッドを作りたい場合に便利。
型(class)を定義しても同じことは出来る。
型を定義するまでもないときはtupleが有効。
意味のあるまとまりの場合はclassにすべき。
たとえば年、月、日の組み合わせならDateクラスを定義すべき。
簡単なのでtupleを乱用しない様注意が必要!!
各要素へのアクセスは._N。Nは1始まり。
(1, 2)._2
パターンマッチングで各要素を取り出すこともできる。
val (x, y) = (1, 2)
()がないと別の意味に解釈されるので注意!!
multiple definitionと解釈される。Chapter 18
17.7 Conclusion
collection libraryと重要なclass, traitの概要。
Scaladocから詳細な情報を読み取れる様になったはず。
scalaはcollectionsの豊富なライブラリを持っている。
既にarray, list, set, mapについて見て来た。
collectionsの継承階層を見る。
色々なcollectionsの使い方を見る。
speed, space, requirements on input dataのトレードオフ等。
17.1 Overview of the library
scalaのcollectionsライブラリは多くのclass, traitを巻き込んでいる。
全体像をScaladocから描き出すのは簡単ではない。
全体像を理解するために必要なtraitのみを下記に示す。
+- Seq // 順番ありの並び(sequence), array, list
Iterable <-+- Set // 重複無しの要素の集まり。重複は==で決める。
+- Map // keyとvalueの組の集まり。
Iterable
Iterable[A]のIterator[A]を生成するメソッドを有する。
def elements: Iterator[A]
elementsは唯一の抽象メソッド。
具象メソッドも多数定義している。
全てelementsが返すIteratorを使用して実装されている。
Iterator
Iterableと同じ多数のメソッドを持っている。
継承階層は異なる。
AnyRef <--- Iterator
Iterableは繰り返しが可能な型表現する。
** Iteratorを生成出来る型。
複数回走査されるかもしれない。
Iteratorは繰り返しに使われるメカニズムそのもの。
一回しか走査出来ない。
再度走査した場合はもういちどIteratorを生成する必要ある。
next, hasNext
多くの具象メソッドがnext, hasNextを使ってIteratorに実装されている。
next, hasNextは抽象メソッドでmix-inする側で定義する。
17.2 Sequences
trait Seqを継承している、順序付きのデータ列のクラス。
1番目、2番目、103番目などの順番が存在する。
Lists
一番重要なsequence type。
先頭への追加削除は早い。
後ろの要素へのアクセスはリストを走査するので遅い。
この実装は多くのアルゴリズムを実装するのに適している。
パターンマッチングなど。
Arrays
任意の要素に効率良くアクセス、更新できる。
0始まりのインデックス。
大きさは固定。
要素は変更可能(mutalble)
javaの配列と互換性がある。
ただし()で要素にアクセスするので注意。
List buffers
import scala.collection.mutable.ListBuffer
mutable
先頭に加えて末尾にも効率良く要素を追加できる。
+= append (末尾に追加)
+: prepend (先頭に追加)
目的のリストを生成したらtoListでListを取得出来る。
?? これが主な使い方? ListからListBuffersへの変換は?
末尾再帰以外の場合のstack overflowを避けるためにも使える。
再帰の代わりにforやwhileとListBufferを組み合わせて使う。Section 22.2
Array buffers
import scala.collection.mutable.ArrayBuffer
長さを変更可能Array
Arrayで出来ることもほとんど実施可能。少しだけ遅い。
先頭と末尾から追加(+=, +:)削除(-=)可能。
平均固定時間で実行できるが、メモリ確保のために線形時間が掛かる場合もある。
?? 末尾から削除のメソッドが分からない。?
Queues
mutable, immutable両方のクラスがある。
importや階層を明示的に指定して使い分ける。
import scala.collection.immutable.Queue
scala> val has1 = empty.enqueue(1)
scala> val has123 = has1.enqueue(List(2, 3))
scala> val (element, has23) = has123.dequeue
import scala.collection.mutable.Queue
scala> val queue = new Queue[String]
scala> queue += "a"
scala> queue ++= List("b", "c")
scala> queue.dequeue
Stacks
mutable, immutable両方のクラスがある。
importや階層を明示的に指定して使い分ける。
import scala.collection.immutable.Stack
import scala.collection.mutable.Stack
push, pop, top(peekの意味)でアクセスする。
Strings (via RichString)
string自体はcollectionではない。
stringにない操作を行った場合RichStringにimplicit conversionされる。
Predefにimplicit conversionが定義されている。
RichStringはSeq[Char]
17.3 Sets and maps
mutableとimmutable両方のtraitがある。
MapやSetという名前のtraitは3種類ある。
defaultではimmutableのtraitが使われる。
immutableを推奨する意図があるから。
** 色々できるが黙って使うと推奨になると言うのが良い。
object Predef {
type Set[T] = scala.collection.immutable.Set[T]
type Map[K, V] = scala.collection.immutable.Map[K, V]
val Set = scala.collection.immutable.Set
val Map = scala.collection.immutable.Map
// ...
}
上記のPredefでの定義でdefaultの動作を決めている。
type~はfull nameのalias
val~はsingleton objectへの参照を保存。
mutable, immutable両方使いたいとき。
import scala.collection.mutable
val mutaSet = mutable.Set(1, 2, 3)
val immutaSet = Set(1, 2, 3)
Using sets
重複なしの要素を含むcollection
重複は==メソッドで判定する。
** Mapのkey部分のみと似ている。
immutable
+, - で要素の追加削除
++, -- で要素Listの追加削除
mutable
+=, -= で要素の追加削除
++=, --= で要素Listの追加削除
clear で全要素削除
共通
Set(1, 2, 3)で生成
Set.empty[T]で空のSetを生成
size, contains
Using maps
keyとvalueの両方の型指定が必要
var m = mutable.Map.empty[String, Int]
keyとvalueの組の辞書、連想配列。
配列はkeyが0始まりで連続の整数のMapと似ている。
値の設定、参照はArrayと同様。
m("hoge") = 1, val i = m("hoge")
key -> value
(key, value): Tuple2[K, V] のsyntactic sugar。
immutable
+, - で要素の追加削除
++, -- で要素Listの追加削除
mutable
+=, -= で要素の追加削除
++=, --= で要素Listの追加削除
m(k) = v
共通
Map(k1 -> v1, k2 -> v2, ...)
Map.empty[K, V]
v = m(k)
m.keySet でキーのSet, Set(k1, k2, ...)
m.keys, m.values でキー、値のIterator
size, contains, isEmpty
Default sets and maps
mutable
defaultではHashSet, HashMapなどが使われる。
効率良いO(1)のアクセスが可能。
immtable
5より小さい場合は効率化のため各サイズに合わせてた専用のクラスが使われる。
たとえば、scala.collection.immutable.Set3 等。
5以上の場合はmutableと同様にHashSetなどが使われる。
Sorted sets and maps
immutableのSetもしくはMapのkeyに対して順番に並べられたSortedSet,Mapがある。
mutableはなし
実装はred-black treeをつかったTreeSet, Mapがある。
red-black treeはself-balancing binary search tree
順序はOrdered traitをmix-inするかimplicit conversion出来るtypeを使う。
順序通り走査ができるIteratorを使える。
Synchronized sets and maps
thread-safeなMapを使いたい場合あはSynchronizedMap traitをmix-inする。
new HashMap[String, String] with SynchronizedMap[String, String] {
override def default(key: String) = "Why do you want to know?"
}
コンパイラはHashMapにSynchronizedMapをmix-inした人工サブクラスを生成。
defaultメソッドのoverrideも出来る。
keyが存在しない時に行う動作を定義できる。
newでそのインスタンスを生成する。
java.util.concurrentが使える場合もある。
unsynchronized collectionsをScala actorsと一緒に使う方法もある。Chapter 30
17.4 Selecting mutable versus immutable collections
mutableとimmutableどちらが良いかはケースバイケース。
迷ったらimmutableにするのを推奨。後で必要になったらmutableに変更する。
mutableで作ってあるコードが分かり難かったらimmutableにした方が良いかも。
特にちゃんとコピーを取っているか心配だったり誰が変更するのかきになるとき。
mutableとimmutableだとimmutableの方が小さくて早い。
mutableのHashMapは空で80byte, 各要素16byteのオーバーヘッドあり
immutableだと空は一つのオブジェクト共有するのでポインタ領域のみ。
さらに1~4要素は個別タイプがあるので16~40byteしか使わない。
少ない要素数ならimmutableを使った方が効率が良い。
mutableからimmutableへの変更
immutableは+=などの=を使ったメソッドが定義されていない。
a += b がない場合はsyntactic sugarで a = a + b と解釈される。
a はvar, mutableである必要がある。
+=だけではなくて、=を使ったすべてのメソッドに適用される。
collectionに限らず全ての型に対してこのsyntactic sugarを使える。
17.5 Initializing collections
コレクションの初期化方法についての考察。
factory methodに初期要素を渡す。
companion objectのapply methodを使う。
一番一般的な方法。
要素の型については通常はコンパイラの型推論に従えば問題ない。
明示的な型指定をした方が良い場合もある。
初期要素よりも上位の型を指定したい場合等。
特に後から要素が変更になるmutableの場合。
他のコレクションの要素で初期化したい場合。
空のコレクションを作って++でListを渡して作成する。
TreeSet[String]() ++ List("c", "b", "a")
Converting to array or list
toArrayやtoListを実行すれば良い。
順序は変換前のcollectionのIteratorの順序になる。
初期化に使ったList等の順に戻る訳ではない。
TreeSet[String]() ++ List("c", "b", "a").toList => List("a", "b", "c")
通常は全要素のコピーになるので大量だと時間が掛かる。
少ない要素数であればあまり気にする必要はない。
?? 少ない要素の場合が多いと言いたい?
Converting between mutable and immutable sets and maps
mutable<->immutableで変換したい場合も空のコレクションと++メソッドが使える。
変換後のからのコレクションに++で変換前のコレクションを追加する。
17.6 Tuples
Tuple少ない固定数の要素の組を一つにまとめて扱うためのもの。
複数の型を混ぜて格納出来る。
List[Any]やArray[Any]も色々な型を格納している様に見えるが、そうではない。
Anyと言う単一の型を格納しているだけ。Anyに適用出来ることしか出来ない。
val x :: y :: z :: nil = List[Any](1, 2, "abc")
val a = x + y // 出来ない
val b = z.toList // 出来ない
同等のことを実施するためにはdown castが必要。
Tuple複数の型を格納出来る。
それぞれの要素にはその型に適用できることが出来る。
val (x, y, z) = (1, 2, "abc")
val a = x + y // 出来る
val b = z.toList // 出来る
down castしなくても型情報が保持されているので問題ない。
意味的にまとまりのない複数の値を組み合わせて扱いたい場合に便利。
複数の値を返すメソッドを作りたい場合に便利。
型(class)を定義しても同じことは出来る。
型を定義するまでもないときはtupleが有効。
意味のあるまとまりの場合はclassにすべき。
たとえば年、月、日の組み合わせならDateクラスを定義すべき。
簡単なのでtupleを乱用しない様注意が必要!!
各要素へのアクセスは._N。Nは1始まり。
(1, 2)._2
パターンマッチングで各要素を取り出すこともできる。
val (x, y) = (1, 2)
()がないと別の意味に解釈されるので注意!!
multiple definitionと解釈される。Chapter 18
17.7 Conclusion
collection libraryと重要なclass, traitの概要。
Scaladocから詳細な情報を読み取れる様になったはず。
ブログの検索について
bloggerの投稿内容はブログツールのgoogle検索だとあまり掛からない。
多分にこのブログが人気が無いせいだとは思うけど。。。(^^
blogの投稿画面の検索を使えば全部ヒットするが、タイトルのみ表示でそこから1件ずつ開かないと何が書いてあるかわからないので不便。
google検索の結果の様にヒット結果の前後が出せると良いのだけれど。
結局bloggerを自分のメモ帳代わりにして、後で検索して調べたりするのには不向きと言うこと?
Hatena等別のブログを使った方が良いのかも知れないが移行も面倒。。。
と思ったら、bloggerの閲覧画面の左上にある検索機能を使うと、関連度が高い投稿から順に表示されるので、これならそこそこ使えるかもしれない。
望ましいのは投稿の中で検索にヒットした部分だけが出る方が良いのだけれど。
多分にこのブログが人気が無いせいだとは思うけど。。。(^^
blogの投稿画面の検索を使えば全部ヒットするが、タイトルのみ表示でそこから1件ずつ開かないと何が書いてあるかわからないので不便。
google検索の結果の様にヒット結果の前後が出せると良いのだけれど。
結局bloggerを自分のメモ帳代わりにして、後で検索して調べたりするのには不向きと言うこと?
Hatena等別のブログを使った方が良いのかも知れないが移行も面倒。。。
と思ったら、bloggerの閲覧画面の左上にある検索機能を使うと、関連度が高い投稿から順に表示されるので、これならそこそこ使えるかもしれない。
望ましいのは投稿の中で検索にヒットした部分だけが出る方が良いのだけれど。
2014/5/8
#studyplus 他の人が勉強しているのを見ると、良い刺激にはなる。
#ME-Club ME Slotに当選!!
子供が寝る前にぎりぎり帰れた。あんずとサンと一緒に寝れた。
バスから見た研修所のツツジが綺麗だった。
電車からパルシステムの牛久センターが見えた。知っているところが見えると何故かちょっと嬉しくなる。
はまりゅうの味玉中華そばがあっさりしていて普通に美味しかった。
英語音声データダウンロード
昨日やったつもりだったが出来ていなかったと思ったら、再放送なだけだった。
英語で読む村上春樹を15min ESEを10min
TOEIC公式問題集のVol.5のリスニングのみで1.5h
#emacs desktopを使えばbufferのsnapshotを保存して次に同じ状態から再開できる。滅茶苦茶便利!!
(desktop-save-mode 1)だけ設定すればOK!!
[Programming in Scala, First Edition]
2014/5/8 30 chapter17 4/7
#ME-Club ME Slotに当選!!
子供が寝る前にぎりぎり帰れた。あんずとサンと一緒に寝れた。
バスから見た研修所のツツジが綺麗だった。
電車からパルシステムの牛久センターが見えた。知っているところが見えると何故かちょっと嬉しくなる。
はまりゅうの味玉中華そばがあっさりしていて普通に美味しかった。
英語音声データダウンロード
昨日やったつもりだったが出来ていなかったと思ったら、再放送なだけだった。
英語で読む村上春樹を15min ESEを10min
TOEIC公式問題集のVol.5のリスニングのみで1.5h
#emacs desktopを使えばbufferのsnapshotを保存して次に同じ状態から再開できる。滅茶苦茶便利!!
(desktop-save-mode 1)だけ設定すればOK!!
[Programming in Scala, First Edition]
2014/5/8 30 chapter17 4/7
2014/5/7
懸案だった写真印刷を行えた。今日の分まで印刷。サンの七五三は印刷していない。
でも、前に印刷したところをまた印刷している気もする。
どこまで印刷したかをちゃんと記録する事が大切。
#Coursera Functional Programming Principles in Scala (Week2)を完了!
#IntelliJ idea
ScalaWorksheetのコードと実施結果の行が合わなくて、コード下の方が見えなくなっている。。。
何か対応方法はある?
一応ゴミ箱ボタンを押して結果を消せばコードは全部見えるようにはなる。
かえる饅頭とずんだもちが美味しかった。
銀行で10年以上取引がないと休眠扱いになり利子もつかない。
通常は申請があれば払い戻しは可能だが、公には民法上権利消滅なので注意必要。
郵便局は民営化前の平成19年以前の契約なら20年2か月で権利消滅。
以降の契約は通常の銀行と同じ。
#emacs flyspell-modeでon-the-flyでスペルチェックができる。C-c $で修正。
でも、前に印刷したところをまた印刷している気もする。
どこまで印刷したかをちゃんと記録する事が大切。
#Coursera Functional Programming Principles in Scala (Week2)を完了!
#IntelliJ idea
ScalaWorksheetのコードと実施結果の行が合わなくて、コード下の方が見えなくなっている。。。
何か対応方法はある?
一応ゴミ箱ボタンを押して結果を消せばコードは全部見えるようにはなる。
かえる饅頭とずんだもちが美味しかった。
銀行で10年以上取引がないと休眠扱いになり利子もつかない。
通常は申請があれば払い戻しは可能だが、公には民法上権利消滅なので注意必要。
郵便局は民営化前の平成19年以前の契約なら20年2か月で権利消滅。
以降の契約は通常の銀行と同じ。
#emacs flyspell-modeでon-the-flyでスペルチェックができる。C-c $で修正。
2014/5/3〜2014/5/6
連休中にあった事。
[2014/5/3]
久々に沢山寝れた。10時間位。
いちごがポーチを紙で工作していた。中々上手にできた。
サンが空中逆上がり30回連続で出来たと言っていた。スゴイ!!
つくばエキスポセンターに行った。科学館系は結構面白い。
体験謎解きアドベンチャー『宝箱の暗号をさがせ!』に参加してゴム動力のスチロールプレーンのキットをもらった!!問題は結構難しかった。
[2014/5/4]
今日も沢山寝れた。11時間位。
上野動物園に行った。みどりの日で入場料が無料だった!!
駅まで車で行ったが、昼間300円の駐車場を見つけた。バス代より安い!!
駐車場から走って時間ギリギリに特別快速に乗れた!!
あんずが一日中動物園を自分の足で歩いて回れた。まだ3歳前なのにスゴイ!!
[2014/5/5]
Coursera: Programming Mobile Applications for Android Handheld Systems
Week1のAssignment完了!!
このコースは既にクローズしているので、今後どこまでやるかは微妙。
次のコースも始まってしまうので、やりながら様子を見ていくのが良いかな。
子供の日でマクドナルドのパッピーセットにミニソフト無料券が付いていた。なんと当日利用可能だったので即使った!!
マクドナルドのアボカドビーフバーガーが美味しかった!!
マクドナルドの景品でもらったマイクを持ってあんずがご機嫌に歌っていた!!
#emacs も色々進歩していて下記で自動インデントが有効になる。
(setq c-auto-newline t)
c++のstream operator <<, >>のoverloadについて調べた。
friend関数を定義すれば良いらしい。
[2014/5/6]
#codecademy 45streak達成!!
#Coursera Functional Programming Principles in Scala (Week2)を開始。
英語では普通、単語と数字の間にはスペースを入れる。 1.5 hour とか Week 2 とか。
日本語の感覚だとスペースは入らない方が自然だが。
ニトリにカラーボックスを買いに行った。
部屋風の家具の展示でにいちご、サン、あんずが大喜び!?
ショッピングモールの隅の空き地であんずとサンか駆けっこ。1分ダッシュx3本やった。
[2014/5/3]
久々に沢山寝れた。10時間位。
いちごがポーチを紙で工作していた。中々上手にできた。
サンが空中逆上がり30回連続で出来たと言っていた。スゴイ!!
つくばエキスポセンターに行った。科学館系は結構面白い。
体験謎解きアドベンチャー『宝箱の暗号をさがせ!』に参加してゴム動力のスチロールプレーンのキットをもらった!!問題は結構難しかった。
[2014/5/4]
今日も沢山寝れた。11時間位。
上野動物園に行った。みどりの日で入場料が無料だった!!
駅まで車で行ったが、昼間300円の駐車場を見つけた。バス代より安い!!
駐車場から走って時間ギリギリに特別快速に乗れた!!
あんずが一日中動物園を自分の足で歩いて回れた。まだ3歳前なのにスゴイ!!
[2014/5/5]
Coursera: Programming Mobile Applications for Android Handheld Systems
Week1のAssignment完了!!
このコースは既にクローズしているので、今後どこまでやるかは微妙。
次のコースも始まってしまうので、やりながら様子を見ていくのが良いかな。
子供の日でマクドナルドのパッピーセットにミニソフト無料券が付いていた。なんと当日利用可能だったので即使った!!
マクドナルドのアボカドビーフバーガーが美味しかった!!
マクドナルドの景品でもらったマイクを持ってあんずがご機嫌に歌っていた!!
#emacs も色々進歩していて下記で自動インデントが有効になる。
(setq c-auto-newline t)
c++のstream operator <<, >>のoverloadについて調べた。
friend関数を定義すれば良いらしい。
[2014/5/6]
#codecademy 45streak達成!!
#Coursera Functional Programming Principles in Scala (Week2)を開始。
英語では普通、単語と数字の間にはスペースを入れる。 1.5 hour とか Week 2 とか。
日本語の感覚だとスペースは入らない方が自然だが。
ニトリにカラーボックスを買いに行った。
部屋風の家具の展示でにいちご、サン、あんずが大喜び!?
ショッピングモールの隅の空き地であんずとサンか駆けっこ。1分ダッシュx3本やった。
2014年5月7日水曜日
Functional Programming Principles in Scala (Week 2)
Week 2: Higher Order Functions
[Lecture 2.1 - Higher-Order Functions]
無名関数、関数リテラルは下記のsyntactic sugarと言うことも出来る。
{def f(x1 : T1; :::; xn : Tn) = E;f} //fは任意の名前
[Lecture 2.2 - Currying]
forward referenceの話が出てきた。
worksheetを使っていると上から順に定義されるので、使う順で記載する必要あり??
[Lecture 2.3 - Example: Finding Fixed Points]
Fixed Pointsと言うのはf(x) = xになるxの値の事。
ニュートン法を使って近似的に求めることが出来る。
平方根の求め方はこの代表例。
使用する関数によっては収束しないことがあるので注意必要。
高レベルの抽象化は何時もベストの選択とは限らないが、使うべき所に適切に使えるように身につけておくべき重要なテクニック。
[Lecture 2.4 - Scala Syntax Summary]
ENBF記法を使った言語定義のまとめ。
| 選択
[] オプション(0..1)
{} 繰り返し(0..n)
この辺の厳密な定義を覚えた方が()や{}がいるとかいらないとかで迷わなくて済みそう。
[Lecture 2.5 - Functions and Data]
分数(有理数)クラスの定義を例にとって、オブジェクト指向的な要素の説明。
[Lecture 2.6 - More Fun With Rationals]
data abstraction、データ抽象化を行うことでクラスの実装の影響をクライアントコードに与えないように出来る。
インタフェースと実装の分離。
第二コンストラクタ以降はdef this(..)で定義出来る。
コンストラクタ中からthis(...)で別のコンストラクタも呼べる。
[Lecture 2.7 - Evaluation and Operators]
クラスがnewされた時に行われるのはコンストラクタの引数の置き換え相当だけ。
メソッドの適用もnewしたインスタンスに更にメソッドの引数を置き換えて計算するたけ。
クラスでも関数でも実行(評価)は定義から実体に置き換えていくだけ。
** スライドの概要説明と具体例説明で引数の記載順序が食い違っている様に見えるが?
Scalaの+,*等のオペレータも基本的には通常メソッド名と同様の単なる識別子。
ただし、:で終わるものを右結合としたり、単項演算子はsyntatic sugerを使ったり、自然に見えるように細かい細工が施してある。
[Assignments - Functional Sets]
整数の集合(Set)を扱う関数を考える。
集合そのものを集合の要素か否かをテストする関数で表現する。
前のクラスの時のFAQが上がっていた。参考に出来そう。
https://class.coursera.org/progfun-004/forum/thread?thread_id=451
集合論の用語については下記で分かりそう。
http://en.wikipedia.org/wiki/Basic_set_operations#Basic_operations
http://en.wikipedia.org/wiki/Algebra_of_sets
union: 和集合
intersect: 積集合
liner recursion
t0 = 0
tn = tn-1 + d
となる漸化式の事。
コード量は少ないが何だかんだで2時間位かかった。
型推論やplace holder _を使えば関数リテラルも短く書ける。
ScalaTestのテストコードを自分で書いたのは良い経験になった。
IntelliJ idea
ScalaWorksheetのコードと実施結果の行が合わなくて、コード下の方が見えなくなっている。。。
何か対応方法はある?
一応ゴミ箱ボタンを押して結果を消せばコードは全部見えるようにはなる。
[その他]
Week2のvideoやassignmentが登録されているのに、メールも来ないしコースのAnnouncementsにも載っていなかった。
正式な配布日になるまではアナウンスしない方針??
それにしてはWeek1の時はアナウンスも早かったような気がするが。。。
先週同様に何かの使いまわしなので、説明の中の週の切れ目と今回のコースの週の切れ目は合っていない。
かなり早いペースで進んでいる。
Programming in Scala, First Editionを読んでいる部分なので既に分かっている内容。
ただ、読んでいない所まで進むと調べながらやらないと難しそうな感じがする。
もっと詳細なノート作成も必要になりそう。
また、今回はLecture部分は流しているだけで実際にWorksheetで実行していない。
これも知らない部分ならやらないと分かりそうにない。
[ログ]
2014/5/6 Lecture 2.1-2.5 1.5 hour
2014/5/6 Assignments 0.5 hour
2014/5/7 Lecture 2.6-2.7 1 hour
2014/5/7 Assignments 2 hour
2014年5月5日月曜日
Programming Mobile Applications for Android Handheld Systems (Week 1)
#Coursera Programming Mobile Applications for Android Handheld Systems (Week1)
[Lecture]
video Lectureはスライドをざっと見た。
[Assignments]
Quizzesを完了!
Lab - Learn to Submitを完了!
Lab - Development Environment
Time Worked: XX minutes. Last Step Completed: YY.
の一行だけを記載したテキストファイルを提出する。
資料が50ページもある。一通りやれば結構練習になりそう。
7.2 Telnetでbrowserのキャッシュのクリアの仕方がわからない。設定画面が出せなかった。
-> F2もしくはブラウザ画面内の右上の四角い点々の所からメニューを出せた。
P43 7.5 HierarchyView Toolまで終わった。約180minutes (2014/4/30)
P50 7.9 Debugging and JUnit Testingまですべて完了。約120minutes (2014/5/5)
途中profileの部分がよく分からなかった。
Time Worked: 300 minutes. Last Step Completed: 7.9.
をテキストに記載して提出。
[その他]
Androidのeclipse開発環境ADT-bundleをインストール
HAXM: Androidの高速emulator
http://blog.clock-up.jp/entry/2014/04/24/android-haxm
上記を見ながらをインストール。BIOS設定で仮想化のサポートもenableにした。
androidのエミュレータを動かした感じだと速くなっている感じはする。
特にデメリットは無さそうだが、使わない時でもリソースを使わないかなどがちょっと気になる。(2014/5/2)
DoS promptからtelnetコマンドが無い?
とりあえずCygwinのtelnetが使えるので問題ないが。。
Javaもしばらく見ないうちに色々と追加されている様子。
「Java5以降のバージョンでは、正しくオーバーライドしていることをコンパイラにチェックさせるために@Overrideというアノテーションを明示的につけることが推奨されています。」
[Lecture]
video Lectureはスライドをざっと見た。
[Assignments]
Quizzesを完了!
Lab - Learn to Submitを完了!
Lab - Development Environment
Time Worked: XX minutes. Last Step Completed: YY.
の一行だけを記載したテキストファイルを提出する。
資料が50ページもある。一通りやれば結構練習になりそう。
7.2 Telnetでbrowserのキャッシュのクリアの仕方がわからない。設定画面が出せなかった。
-> F2もしくはブラウザ画面内の右上の四角い点々の所からメニューを出せた。
P43 7.5 HierarchyView Toolまで終わった。約180minutes (2014/4/30)
P50 7.9 Debugging and JUnit Testingまですべて完了。約120minutes (2014/5/5)
途中profileの部分がよく分からなかった。
Time Worked: 300 minutes. Last Step Completed: 7.9.
をテキストに記載して提出。
[その他]
Androidのeclipse開発環境ADT-bundleをインストール
HAXM: Androidの高速emulator
http://blog.clock-up.jp/entry/2014/04/24/android-haxm
上記を見ながらをインストール。BIOS設定で仮想化のサポートもenableにした。
androidのエミュレータを動かした感じだと速くなっている感じはする。
特にデメリットは無さそうだが、使わない時でもリソースを使わないかなどがちょっと気になる。(2014/5/2)
DoS promptからtelnetコマンドが無い?
とりあえずCygwinのtelnetが使えるので問題ないが。。
Javaもしばらく見ないうちに色々と追加されている様子。
「Java5以降のバージョンでは、正しくオーバーライドしていることをコンパイラにチェックさせるために@Overrideというアノテーションを明示的につけることが推奨されています。」
2014年5月2日金曜日
2014/5/2(金)
今日は平日だけど珍しく仕事は休み。サンの幼稚園の送り出しが出来た!!
あんずと二人でお留守番。散歩に行ったり、一緒に洗い物をしたりお掃除をしたり出来た!!
いちごの家庭訪問に参加できた。もしかしたらこれで最初で最後かも知れない。貴重な体験だった!!
久々にスシローに行った。家族5人で一つの苺ミルフィーユパフェを分け合って食べたのが美味しかった!!
朝日新聞の連載小説
宮部みゆきの荒神が終わって、林真理子のマイストーリーを読み始めた。
荒神は一年ちょっと毎日読み続けたが、その前の2連載に比べて、普通に面白かった。
考えてみると一年以上毎日欠かさずに続けられると言うのは中々スゴイこと。
これはインセンティブを上手く設計すれば継続する事をもっと楽に出来る可能性を示している。
#Coursera Programming Cloud Services for Android Handheld Systems
HAXMをインストール。BIOS設定で仮想化のサポートをenableにした。
androidのエミュレータを動かした感じだと速くなっている感じはする。
特にデメリットは無さそうだが、使わない時でもリソースを使わないかなどがちょっと気になる。
easy photo print exをインストール。
昔のバージョンの方が機能は少ないが、選択画面が大きくて沢山のサムネイルが同時に見れるのと、拡大画面の写真が大きかったので使いやすかったような気がする。。。
あんずと二人でお留守番。散歩に行ったり、一緒に洗い物をしたりお掃除をしたり出来た!!
いちごの家庭訪問に参加できた。もしかしたらこれで最初で最後かも知れない。貴重な体験だった!!
久々にスシローに行った。家族5人で一つの苺ミルフィーユパフェを分け合って食べたのが美味しかった!!
朝日新聞の連載小説
宮部みゆきの荒神が終わって、林真理子のマイストーリーを読み始めた。
荒神は一年ちょっと毎日読み続けたが、その前の2連載に比べて、普通に面白かった。
考えてみると一年以上毎日欠かさずに続けられると言うのは中々スゴイこと。
これはインセンティブを上手く設計すれば継続する事をもっと楽に出来る可能性を示している。
#Coursera Programming Cloud Services for Android Handheld Systems
HAXMをインストール。BIOS設定で仮想化のサポートをenableにした。
androidのエミュレータを動かした感じだと速くなっている感じはする。
特にデメリットは無さそうだが、使わない時でもリソースを使わないかなどがちょっと気になる。
easy photo print exをインストール。
昔のバージョンの方が機能は少ないが、選択画面が大きくて沢山のサムネイルが同時に見れるのと、拡大画面の写真が大きかったので使いやすかったような気がする。。。
2014/4/23〜2014/5/1の雑多な事
結局しばらくブログがかけず、雑多な日々のネタが溜まってしまったので、まとめて書くことに。。。
わざわざブログに書くような内容でもない気もするけど、備忘録として試しに書いてみる。
#3goodについては一応毎日twitterに上げられてはいるので、それと重複する部分も多い。
勉強したことの記録はstudypulsに上げている。
[2014/4/23]
textile記法の表の書き方が分かった!
ローソンのパン。久々に食べた。
飲み会参加できず。
[2014/4/24]
久々に中台でしゃぶしゃぶを食べた。トロピカルミックスも美味しかった!
中台から45分歩いて会社に戻ったが、散歩に気持ちの良い温度だった!
ESECのVIP特別招待状が届いた!
[2014/4/25]
#codecademy Great job finishing How to use APIs with JavaScript!
emacsのshellでのアプリケーション実行について
windows環境だとttyとの相性が悪くてssh等がうまく動作しない。
それを対処するためのfakecygptyというプログラムがあるらしい。
自分で作れないのだろうか。。。gnupackeのdevelopmentを入れる必要あり。
cygwin-gccでemacsをbuildした方がcygwinと相性が良い??
http://st63jun.hatenablog.jp/entry/2012/04/05/162314
fakecygptyにはcygwin環境必要。gnupackはmingwのgccなのでNGだった。
Vistorパターンとダブルディスパッチ
Vistorを引数に入れてAcceptorのaccept()呼ぶ。
accept()からVistorのvisit()呼び出すことでaccept()の振る舞いを変えられる。
overrideとoverloadについて考えた。
#Coursera Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Systemsに登録。
Programming in Scala, First Edition
case classは結構難しい?
pattern matchingをなんでそんなことが出来るか不思議なくらい強力。
C++のtempleteと似ている気がする。
[2014/4/26]
#codecademy 35 streak 達成!
サンといちごの一輪車教室に、家族で児童館に行った。
サンは初めてだった捕まって乗れるようになった。
いちごは片手で捕まれば乗れるようになっていた。
[2014/4/27]
沢山寝られた。寝られるとやっぱり体調が良い。
暖かい。気持ち良い天気
久しぶりに子供たちと戦いごっこをして上げられた。大はしゃぎ。
休日出勤だったが子供たちが寝る前に上がれた。
CourseraのAndroidのコースを調査。バラバラに受けても良い。
"Mobile Cloud Computing with Android" Specializationと言う3つの講義をまとめたものらしい。
capstone projectと言うのがあって、それはすべての講義を修了しないと参加できない。
有料のcertifyを取らないとだめ??
Programming Cloud Services for Android Handheld Systemsに登録。
kindle file hd 7 2gen はandroid 4.2.2 base。
[2014/4/28]
やっぱり毎日の事をブログに書くのは時間的に厳しいのかなあ。。。4/22(火)以降は書けていない。
その日のメモを全部書こうとするから難しくなる?
メモの体裁を整えようとするから難しくなる?
それに対してtwitterの#3goodは続けられている。
#Coursera Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Systems
FAQの5に良い事が書いてあった。下記抜粋。
In other words, watch the videos, keep track of what you know understand, and then use the resources available to you (e.g., via the web and the discussion forums) to fill in the gaps in your knowledge.
#Coursera Introduction to Computational Finance and Financial Econometrics に登録
R言語と言うのを使うらしい。下記で予習必要。
Introduction to R
https://www.datacamp.com/courses/introduction-to-r
仕事も忙しい上でCourseraを受講するのは大変だが、他にもやる事があると言うのは気分を楽にする効果あり。
子供達が起きている間に帰れた。熱烈歓迎!
#ME-Club 景品のメモ帳が届いた!!
[2014/4/29]
間食なし2営業日達成!!
サンといちごが起きているときに帰れた!!
[Programming in Scala, First Edition]
2014/4/29 180 chapter16 6/10
-printでコンパイルするとde-sugaredコードが出力される。
http://twitter.github.io/scala_school/index.html
http://twitter.github.io/effectivescala
scalaはtwitterのシステムに使われている。
カリー化と部分適用の違い
カリー化はカリー化された型の関数しか受け入れない操作をする場合に必要。
カリー化されていれば部分適用も簡単に可能。
[2014/4/30]
定形郵便物 (23.5cm x 12cm x 1cm) 50g以内 92円, 25g以内 82円
封筒の宛名印刷と切手貼り。
アプリバー: アプリの何も無いところで右クリック
Windows8.1にしてしまうとリカバーディスクを作れないらしい。Win8なら作れる。
http://tidoriashi.exblog.jp/21414082
Windows8.1でもUSBならリカバーディス作れる。DVDには作れない。(2014/8/29追記)
http://tidoriashi.exblog.jp/21697296
easy photo printもあり
[2014/5/1]
#codecademy Searching for YouTube Videosバッジ獲得!!
#codecademy 40 streak 達成!!
#codecademy JQuery 開始!!
[excel]
振り仮名の表示や、振り仮名のフォーマットを設定できる。
phonetic関数で振り仮名の文字列を取り出せる。
jis, asc関数で全角、半角変換が出来る。
[IME]
新しいユーザ辞書ファイルを作成する
テキストファイルから登録したいデータを取り込む
システム辞書に変換する
システム辞書を登録する
ユーザ辞書ファイルを元に戻す。
わざわざブログに書くような内容でもない気もするけど、備忘録として試しに書いてみる。
#3goodについては一応毎日twitterに上げられてはいるので、それと重複する部分も多い。
勉強したことの記録はstudypulsに上げている。
[2014/4/23]
textile記法の表の書き方が分かった!
ローソンのパン。久々に食べた。
飲み会参加できず。
[2014/4/24]
久々に中台でしゃぶしゃぶを食べた。トロピカルミックスも美味しかった!
中台から45分歩いて会社に戻ったが、散歩に気持ちの良い温度だった!
ESECのVIP特別招待状が届いた!
[2014/4/25]
#codecademy Great job finishing How to use APIs with JavaScript!
emacsのshellでのアプリケーション実行について
windows環境だとttyとの相性が悪くてssh等がうまく動作しない。
それを対処するためのfakecygptyというプログラムがあるらしい。
自分で作れないのだろうか。。。gnupackeのdevelopmentを入れる必要あり。
cygwin-gccでemacsをbuildした方がcygwinと相性が良い??
http://st63jun.hatenablog.jp/entry/2012/04/05/162314
fakecygptyにはcygwin環境必要。gnupackはmingwのgccなのでNGだった。
Vistorパターンとダブルディスパッチ
Vistorを引数に入れてAcceptorのaccept()呼ぶ。
accept()からVistorのvisit()呼び出すことでaccept()の振る舞いを変えられる。
overrideとoverloadについて考えた。
#Coursera Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Systemsに登録。
Programming in Scala, First Edition
case classは結構難しい?
pattern matchingをなんでそんなことが出来るか不思議なくらい強力。
C++のtempleteと似ている気がする。
[2014/4/26]
#codecademy 35 streak 達成!
サンといちごの一輪車教室に、家族で児童館に行った。
サンは初めてだった捕まって乗れるようになった。
いちごは片手で捕まれば乗れるようになっていた。
[2014/4/27]
沢山寝られた。寝られるとやっぱり体調が良い。
暖かい。気持ち良い天気
久しぶりに子供たちと戦いごっこをして上げられた。大はしゃぎ。
休日出勤だったが子供たちが寝る前に上がれた。
CourseraのAndroidのコースを調査。バラバラに受けても良い。
"Mobile Cloud Computing with Android" Specializationと言う3つの講義をまとめたものらしい。
capstone projectと言うのがあって、それはすべての講義を修了しないと参加できない。
有料のcertifyを取らないとだめ??
Programming Cloud Services for Android Handheld Systemsに登録。
kindle file hd 7 2gen はandroid 4.2.2 base。
[2014/4/28]
やっぱり毎日の事をブログに書くのは時間的に厳しいのかなあ。。。4/22(火)以降は書けていない。
その日のメモを全部書こうとするから難しくなる?
メモの体裁を整えようとするから難しくなる?
それに対してtwitterの#3goodは続けられている。
#Coursera Pattern-Oriented Software Architectures: Programming Mobile Services for Android Handheld Systems
FAQの5に良い事が書いてあった。下記抜粋。
In other words, watch the videos, keep track of what you know understand, and then use the resources available to you (e.g., via the web and the discussion forums) to fill in the gaps in your knowledge.
#Coursera Introduction to Computational Finance and Financial Econometrics に登録
R言語と言うのを使うらしい。下記で予習必要。
Introduction to R
https://www.datacamp.com/courses/introduction-to-r
仕事も忙しい上でCourseraを受講するのは大変だが、他にもやる事があると言うのは気分を楽にする効果あり。
子供達が起きている間に帰れた。熱烈歓迎!
#ME-Club 景品のメモ帳が届いた!!
[2014/4/29]
間食なし2営業日達成!!
サンといちごが起きているときに帰れた!!
[Programming in Scala, First Edition]
2014/4/29 180 chapter16 6/10
-printでコンパイルするとde-sugaredコードが出力される。
http://twitter.github.io/scala_school/index.html
http://twitter.github.io/effectivescala
scalaはtwitterのシステムに使われている。
カリー化と部分適用の違い
カリー化はカリー化された型の関数しか受け入れない操作をする場合に必要。
カリー化されていれば部分適用も簡単に可能。
[2014/4/30]
定形郵便物 (23.5cm x 12cm x 1cm) 50g以内 92円, 25g以内 82円
封筒の宛名印刷と切手貼り。
アプリバー: アプリの何も無いところで右クリック
Windows8.1にしてしまうとリカバーディスクを作れないらしい。Win8なら作れる。
http://tidoriashi.exblog.jp/21414082
Windows8.1でもUSBならリカバーディス作れる。DVDには作れない。(2014/8/29追記)
http://tidoriashi.exblog.jp/21697296
easy photo printもあり
[2014/5/1]
#codecademy Searching for YouTube Videosバッジ獲得!!
#codecademy 40 streak 達成!!
#codecademy JQuery 開始!!
[excel]
振り仮名の表示や、振り仮名のフォーマットを設定できる。
phonetic関数で振り仮名の文字列を取り出せる。
jis, asc関数で全角、半角変換が出来る。
[IME]
新しいユーザ辞書ファイルを作成する
テキストファイルから登録したいデータを取り込む
システム辞書に変換する
システム辞書を登録する
ユーザ辞書ファイルを元に戻す。
Functional Programming Principles in Scala (Week 1)
#Coursera Functional Programming Principles in Scala
Week 1: Functions & Evaluations
1週目が始まった。
資料の提供が予定より少し早いが、予定前には出すという意味かな。
字幕に間違いが多い。sbt->svtとか、call->coreとか、REPL->rippleとか。
知らないで見ていると余計に混乱するかもしれない。
今回は別にscala本を読んでいるので内容的に知っているところが多くて特に難しくないが、初めてのモノだと予習していないと結構つらいかも。
ノートを作る必要もあるかもしれない。
[Lecture 1.1]
smalltalkやrubyも関数型としていた。blockを渡せるのが関数値と同等。
[Lecture 1.2]
call by valueとcall by nameの説明。lazy評価と関係あり。call by nameの利点を挙げていた。
[Lecture 1.3]
call-by-value vs. call-by-name
scalaは通常はcbvを使う。
同じ計算を複数回行う必要がないので効率的。
命令型のサポートとも相性が良い。副作用の順番も自然になる。
cbnを使いたときはパラメータのannotationに=>を付ける。
cbnを使えば遅延評価となり値が必要となるまで評価されない。
[Lecture 1.4]
ここでもcbvとcbnの話が出てくる。この違いにこだわりがありそう。
defはcbnでvalはcbv
a && bはcbnでdef and(a: Boolean, b: => Boolean) if (a) b else falseと等価
&&, ||はshort-circuit evaluation
[Lecture 1.5]
ニュートン法による平方根の求め方。再帰の練習。適切な終了条件の考察あり。
[Lecture 1.6]
lexical name scope, blockの外側の値はパラメータ渡し無しで使うようにする。
置き換えモデルによる表現の簡略化が今後のセッションでも重要なツールになる。
[Lecture 1.7]
tail recursion, tail call
最大公約数(ユークリッド法)と階乗を求めるプログラムの比較。
substitution modelでどんどん長くならければtail recursion.
階乗を求めるプログラムもパラメータを増やすことでtail recursionに変更出来ていた。
** スライドが中途半端なのと2week-1だと言っている。。。資料の完成度は高くないのかも。
クイズはvideoの中の設問の事で別途問題を解く必要はないらしい。。。
[Assignment: Recursion]
パスカルの三角形、カッコの対応チェック、両替パターン数のカウントの3問
結構手間取ったが、1回目で10点満点を獲得!
[その他]
Week 1を完了!
IntelliJ Ideaのeclipseのプロジェクトインポートには時間が掛かる?
しばらく待っていたら、indexingとか表示されて、上手く表示されるようになった。
それでもimport common._はunusedと言われているが。。。
関数型プログラミングでは答えからそれに必要なものを遡って考える。
命令型では入力から答えを作り上げていく。
#CourseraのWeek1のRecursiveのAssignmentで改めて実感出来た。
そう考えるとcall-by-nameの方が相性が良さそう。
exceptionは副作用? 処理順に依存する。haskellでは?
純粋関数型ではexceptionは投げない。scalaのOption type的なもので処理する。
haskellでもI/Oモナド等の副作用があるものでexceptionを使っている。
Week 1: Functions & Evaluations
1週目が始まった。
資料の提供が予定より少し早いが、予定前には出すという意味かな。
字幕に間違いが多い。sbt->svtとか、call->coreとか、REPL->rippleとか。
知らないで見ていると余計に混乱するかもしれない。
今回は別にscala本を読んでいるので内容的に知っているところが多くて特に難しくないが、初めてのモノだと予習していないと結構つらいかも。
ノートを作る必要もあるかもしれない。
[Lecture 1.1]
smalltalkやrubyも関数型としていた。blockを渡せるのが関数値と同等。
[Lecture 1.2]
call by valueとcall by nameの説明。lazy評価と関係あり。call by nameの利点を挙げていた。
[Lecture 1.3]
call-by-value vs. call-by-name
scalaは通常はcbvを使う。
同じ計算を複数回行う必要がないので効率的。
命令型のサポートとも相性が良い。副作用の順番も自然になる。
cbnを使いたときはパラメータのannotationに=>を付ける。
cbnを使えば遅延評価となり値が必要となるまで評価されない。
[Lecture 1.4]
ここでもcbvとcbnの話が出てくる。この違いにこだわりがありそう。
defはcbnでvalはcbv
a && bはcbnでdef and(a: Boolean, b: => Boolean) if (a) b else falseと等価
&&, ||はshort-circuit evaluation
[Lecture 1.5]
ニュートン法による平方根の求め方。再帰の練習。適切な終了条件の考察あり。
[Lecture 1.6]
lexical name scope, blockの外側の値はパラメータ渡し無しで使うようにする。
置き換えモデルによる表現の簡略化が今後のセッションでも重要なツールになる。
[Lecture 1.7]
tail recursion, tail call
最大公約数(ユークリッド法)と階乗を求めるプログラムの比較。
substitution modelでどんどん長くならければtail recursion.
階乗を求めるプログラムもパラメータを増やすことでtail recursionに変更出来ていた。
** スライドが中途半端なのと2week-1だと言っている。。。資料の完成度は高くないのかも。
クイズはvideoの中の設問の事で別途問題を解く必要はないらしい。。。
[Assignment: Recursion]
パスカルの三角形、カッコの対応チェック、両替パターン数のカウントの3問
結構手間取ったが、1回目で10点満点を獲得!
[その他]
Week 1を完了!
IntelliJ Ideaのeclipseのプロジェクトインポートには時間が掛かる?
しばらく待っていたら、indexingとか表示されて、上手く表示されるようになった。
それでもimport common._はunusedと言われているが。。。
関数型プログラミングでは答えからそれに必要なものを遡って考える。
命令型では入力から答えを作り上げていく。
#CourseraのWeek1のRecursiveのAssignmentで改めて実感出来た。
そう考えるとcall-by-nameの方が相性が良さそう。
exceptionは副作用? 処理順に依存する。haskellでは?
純粋関数型ではexceptionは投げない。scalaのOption type的なもので処理する。
haskellでもI/Oモナド等の副作用があるものでexceptionを使っている。
Javaの32bit版と64bit版
intelliJのterminalのDosプロンプトやbashからc:\windows\system32\java.exe等が見えない。
多分64bitのjavaを32bitアプリケーションから使おうとしているためか?
program files\Java\jre\binをpathに指定すれば多分大丈夫。
32bit版を入れた方が安全かもしれない。
64bit windowsではC:\Windows\System32\の実体はC:\Windows\SysWoW64\なのでjava.exeをそこに入れれば実行できる。
基本的には32bit版のjavaも両方インストールすべき。
下記でコマンドのパスが分かる!
for %i in (java.exe) do @echo. %~$PATH:i
多分64bitのjavaを32bitアプリケーションから使おうとしているためか?
program files\Java\jre\binをpathに指定すれば多分大丈夫。
32bit版を入れた方が安全かもしれない。
64bit windowsではC:\Windows\System32\の実体はC:\Windows\SysWoW64\なのでjava.exeをそこに入れれば実行できる。
基本的には32bit版のjavaも両方インストールすべき。
下記でコマンドのパスが分かる!
for %i in (java.exe) do @echo. %~$PATH:i
Functional Programming Principles in Scala (Week 0)
CourseraのFunctional Programming Principles in Scalaが始まった。
まずは講義開始前の準備。
googleカレンダーに課題の締切日を登録。
既に課題を提出した人もいる様子。
[クイズ]
gradingとは無関係。
[assignment]
5回まで提出出来る。自動採点。
各10点満点
締切(2週間後)に遅れると20%減点。
デッドライン(3週間後)に遅れると点数はもらえない。
全体で60%以上でコース修了。
修了率は20%
これでトップレベルの高さ。初回は5万人受けて1万人。
今回で3回目のコース実施。
Getting Started!完了!
Forumに初投稿!
ScalaTestはすべてパスするように作る必要あり。
style guideの配点が2割あるので、それも気にする必要あり。
プロジェクトファイルの課題以外の部分が変更されると正しく採点されなくなる可能性あり。
sbtはterminalで動かす。
worksheetから実行して動作試せる。
ScalaTestはTestSuite上でRun xxxSuiteで実行。
[気になったところ]
例外は副作用?処理の順序に依存する。haskellでは?
ifではなくて&&や||を使う?
先にxs.headを評価させる?try-catchで例外を補足しする?isEmptyで判定して例外を投げる?
まずは講義開始前の準備。
googleカレンダーに課題の締切日を登録。
既に課題を提出した人もいる様子。
[クイズ]
gradingとは無関係。
[assignment]
5回まで提出出来る。自動採点。
各10点満点
締切(2週間後)に遅れると20%減点。
デッドライン(3週間後)に遅れると点数はもらえない。
全体で60%以上でコース修了。
修了率は20%
これでトップレベルの高さ。初回は5万人受けて1万人。
今回で3回目のコース実施。
Getting Started!完了!
Forumに初投稿!
ScalaTestはすべてパスするように作る必要あり。
style guideの配点が2割あるので、それも気にする必要あり。
プロジェクトファイルの課題以外の部分が変更されると正しく採点されなくなる可能性あり。
sbtはterminalで動かす。
worksheetから実行して動作試せる。
ScalaTestはTestSuite上でRun xxxSuiteで実行。
[気になったところ]
例外は副作用?処理の順序に依存する。haskellでは?
ifではなくて&&や||を使う?
先にxs.headを評価させる?try-catchで例外を補足しする?isEmptyで判定して例外を投げる?
登録:
投稿 (Atom)