Rubyの正規表現でそれぞれのケースへの変換
今日は正規表現に苦しんだので練習しました。
snake_case、camel_Case、Pascal_Caseのそれぞれへの変換です。
capitalizeなくても書けるけど一応。
m[0].upcase + m[1..-1]
はちょっと汚いですしね。
Rubular使えばテストケースが期待通りのマッチになるまで簡単に
トライ&エラーが出来ていいです。
class String def snake_to_camel self.gsub(/\b[a-z][a-z\d]*[a-z_\d]*\b/) do |match| match.gsub(/_[a-z\d]/) { |m| m[1..-1].capitalize} end end def snake_to_pascal self.gsub(/\b[a-z][a-z\d]*[a-z_\d]*\b/) do |match| match.gsub(/[a-z][a-z\d]*/) { |m| m.capitalize } end end def camel_to_snake self.gsub(/\b[a-z]+[A-Z][a-z\d]+\b/) do |match| match.gsub(/[A-Z][a-z\d]+/) { |m| "_" + m.downcase } end end def camel_to_pascal self.gsub(/\b[a-z]+[A-Z][a-z\d]+\b/) do |match| match.capitalize end end def pascal_to_snake self.gsub(/\b[A-Z][a-z\d]*([A-Z][a-z\d]+)*\b/) do |match| match.gsub(/[A-Z][a-z\d]*/) { |m| "_" + m }.downcase[1..-1] end end def pascal_to_camel self.gsub(/\b[A-Z][a-z\d]+([A-Z][a-z\d]+)*\b/) do |match| match.gsub(/\b[A-Z][a-z\d]*/) { |m| m.downcase } end end end
FLEXBOX FROGGYチートシート
FLEXBOX FROGGYをクリアしたのでやりながらまとめたものを貼ります.
Flexboxはここでやった部分しかしりませんが,これだけでも便利ですね.
コンテナ全体
- justify-content 水平方向への寄せなど
- align-content 垂直方向への寄せなど
- align-items
- flex-direction (先頭の方向を変えるのでjustify-content, align-itemsの挙動が変わる)
- row: 左から右に並べる
- row-reverse: 右から左に並べる
- column: 上から下に並べる
- column-reverse: 下から上に並べる
- flex-wrap
- nowrap: 一行で表示
- wrap: 行端までいくと新たに行を追加して表示する
- wrap-reverse: 反対から表示し,行端までいけば新たに行を追加して表示する
- flex-flow
個別の要素に対して
- order
- 現在位置を 0 として順番をずらす.一つ後ろにずらすなら1,一つ前なら-1.
- align-self
- 垂直方向の位置を変える.コマンドはalign-itemsと同じ.
fjordのリモートインターンに参加しました
昨日別ブログにも書きましたが,向こうはやめてこっちに書いていきます.
コードを書いてごはんが食べられるように頑張ります.
プログラミングの基礎を読み終わった.
プログラミングの基礎 (Computer Science Library)
- 作者: 浅井健一
- 出版社/メーカー: サイエンス社
- 発売日: 2007/03
- メディア: 単行本
- 購入: 17人 クリック: 409回
- この商品を含むブログ (126件) を見る
演習問題をほぼ解いて一週間くらいかかりました.
タイトルどおりに丁寧にプログラミングの基礎を習得出来る本でした.
デザインレシピを通して,プログラムの書き方を学んでいきます.
このデザインレシピがよく出来ていて,
簡単な関数ならこのやり方のまま迷わずに書いていけます.
さらに実行して期待する型が出力できる段階まで書けると,テストを書くようになっているので.
テストファーストも体験できます.
何度も問題を解いていくうちに型をちゃんと意識するようになりました.
SICPやっていた時も面倒なバグは大体型がおかしくなっていることに起因していたのですごくためになります.
再帰やリスト操作自体は慣れていましたが,パターンマッチによって操作していくのはおもしろかったです.
プログラミング初心者にも関数型言語初心者にもおすすめな内容だと思います.
プログラミングの基礎 16.4 最初の完動プログラム
プログラミングの基礎で作ったメトロネットワーク最短路問題の解答.
ダイクストラ法を使い求める.
ここまでのメトロネットワーク最短路問題に関係する問題の解答すべてここに書いてある.
(* サポートページからダウンロードしたglobal_ekimei_listとglobal_ekikan_list *) #use "metro.ml" (* 目的:ekimei_t型のデータを受け取り,「路線名,駅名(かな)」を返す *) (* hyoji : ekimei_t -> string *) let hyoji ekimei = match ekimei with {kanji = kanji; kana = kana; romaji = romaji; shozoku = shozoku;} -> shozoku ^ "," ^ kanji ^ "(" ^ kana ^ ")";; (* hyoji test *) print_string "hyouji test" let test1 = hyoji {kanji = "茗荷谷"; kana = "みょうがだに"; romaji = "myogadani"; shozoku = "丸ノ内線"} = "丸ノ内線,茗荷谷(みょうがだに)" (* 目的:ローマ字の駅名(文字列)と駅名リスト(ekimei_t list 型)を受け取り 園駅の漢字表記を返す *) (* romaji_to_kanji -> string -> ekimei_t list -> string *) let rec romaji_to_kanji name lst = match lst with [] -> "" | {kanji = kanji; kana = kana; romaji = romaji; shozoku = shozoku} :: rest -> if name = romaji then kanji else romaji_to_kanji name rest (* romaji_to_kanji test *) let test1 = romaji_to_kanji "" [] = "" let test2 = romaji_to_kanji "" global_ekimei_list = "" let test3 = romaji_to_kanji "myogadani" [] = "" let test4 = romaji_to_kanji "myogadani" global_ekimei_list = "茗荷谷" let test5 = romaji_to_kanji "aoyamaicchome" global_ekimei_list = "青山一丁目" let test6 = romaji_to_kanji "heiwadai" global_ekimei_list = "平和台" (* 目的:漢字の駅名を2つと駅間リストを受け取ったら,駅間リストの中からその2駅間の距離を返す *) (* get_ekikan_kyori : string -> string -> ekikan_t list -> float *) let rec get_ekikan_kyori eki1 eki2 lst = match lst with [] -> infinity | {kiten = kiten; shuten = shuten; keiyu = keiyu; kyori = kyori; jikan = jikan} :: rest -> if eki1 = kiten && eki2 = shuten then kyori else if eki2 = kiten && eki1 = shuten then kyori else get_ekikan_kyori eki1 eki2 rest (* get_ekikan_kyori test *) let test1 = get_ekikan_kyori "錦糸町" "住吉" [] = infinity let test2 = get_ekikan_kyori "錦糸町" "" global_ekikan_list = infinity let test3 = get_ekikan_kyori "" "錦糸町" global_ekikan_list = infinity let test4 = get_ekikan_kyori "横浜駅" "錦糸町" global_ekikan_list = infinity let test5 = get_ekikan_kyori "大手町" "三越前" global_ekikan_list = 0.7 let test6 = get_ekikan_kyori "三越前" "大手町" global_ekikan_list = 0.7 let test7 = get_ekikan_kyori "霞ヶ関" "日比谷" global_ekikan_list = 1.2 (* 目的:ローマ字の駅名を2つ受け取り,その間の距離を調べ,つながっている場合は 「A駅からB駅までのはxkmです」と返し,繋がっていない場合は 「A駅からB駅はつながっていません」と返す*) let kyori_wo_hyoji r1 r2 = let k1 = romaji_to_kanji r1 global_ekimei_list in let k2 = romaji_to_kanji r2 global_ekimei_list in let not_exist = "という駅は存在しません" in if k1 = "" then r1 ^ not_exist else if k2 = "" then r2 ^ not_exist else let kyori = get_ekikan_kyori k1 k2 global_ekikan_list in if kyori = infinity then k1 ^ "駅と" ^ k2 ^ "駅はつながっていません" else k1 ^ "駅から" ^ k2 ^ "駅までは" ^ string_of_float kyori ^ "kmです" (* kyori_wo_hyoji test *) let test1 = kyori_wo_hyoji "otemachi" "hibiya" = "大手町駅と日比谷駅はつながっていません" let test2 = kyori_wo_hyoji "" "kinsityo" = "という駅は存在しません" let test3 = kyori_wo_hyoji "yokohama" "kinsityo" = "yokohamaという駅は存在しません" let test4 = kyori_wo_hyoji "otemachi" "mitsukoshimae" = "大手町駅から三越前駅までは0.7kmです" let test5 = kyori_wo_hyoji "mitsukoshimae" "otemachi" = "三越前駅から大手町駅までは0.7kmです" let test6 = kyori_wo_hyoji "kasumigaseki" "hibiya" = "霞ヶ関駅から日比谷駅までは1.2kmです" type eki_t = { namae : string; (* 駅名(漢字の文字列) *) saitan_kyori : float; (* 最短距離(実数) *) temae_list : string list; (* 駅名(漢字の文字列)のリスト *) } (* 目的:string型の駅名(漢字)とekimei_t list型を受け取り, ekimei_t listをeki_t listに変え,その際駅名と一致する駅についてはshokikaする *) (* make_initial_eki_list : string -> ekimei_t list -> eki_t list *) let make_initial_eki_list name lst = List.map (fun eki -> match eki with {kanji = k; kana = a; romaji = r; shozoku = s} -> if k = name then {namae = k; saitan_kyori = 0.; temae_list = [k]} else {namae = k; saitan_kyori = infinity; temae_list = []}) lst;; (* make_initial_eki_list test *) let test1 = make_initial_eki_list "代々木上原" [{kanji="代々木上原"; kana="よよぎうえはら"; romaji="yoyogiuehara"; shozoku="千代田線"}] = [{namae = "代々木上原"; saitan_kyori = 0.; temae_list = ["代々木上原"]}];; let test2 = make_initial_eki_list "明治神宮前" [{kanji="代々木公園"; kana="よよぎこうえん"; romaji="yoyogikouen"; shozoku="千代田線"}; {kanji="明治神宮前"; kana="めいじじんぐうまえ"; romaji="meijijinguumae"; shozoku="千代田線"}] = [{namae = "代々木公園"; saitan_kyori = infinity; temae_list = []}; {namae = "明治神宮前"; saitan_kyori = 0.; temae_list = ["明治神宮前"]}];; let test3 = make_initial_eki_list "赤坂" [{kanji="表参道"; kana="おもてさんどう"; romaji="omotesandou"; shozoku="千代田線"}; {kanji="乃木坂"; kana="のぎざか"; romaji="nogizaka"; shozoku="千代田線"}; {kanji="赤坂"; kana="あかさか"; romaji="akasaka"; shozoku="千代田線"}] = [{namae = "表参道"; saitan_kyori = infinity; temae_list = []}; {namae = "乃木坂"; saitan_kyori = infinity; temae_list = []}; {namae = "赤坂"; saitan_kyori = 0.; temae_list = ["赤坂"]}];; (* 目的:ekimei_t型のレコードとekimei_t型のリストを受け取ったら,平仮名の昇順となる位置に ekimei_t型のレコードを挿入する.同じ駅がリストにあれば挿入しない. seiretsuのための補助関数*) (* ekimei_isnert : -> ekimei_t -> ekimei_t list -> ekimei_t list *) let rec ekimei_insert eki lst = match lst with [] -> [eki] | ({kanji = kanji; kana = kana; romaji = romaji; shozoku = shozoku;} as first) :: rest -> if kana = eki.kana then lst (* リストにあったほうが残る *) else if eki.kana < kana (* 駅のkana < first のkana *) then eki :: lst else first :: ekimei_insert eki rest (* test data *) let yoyogiuehara_tiyodasen = {kanji="代々木上原"; kana="よよぎうえはら"; romaji="yoyogiuehara"; shozoku="千代田線"} let otemachi_tiyodasen = {kanji="大手町"; kana="おおてまち"; romaji="otemachi"; shozoku="千代田線"} let otemachi_hanzoumonsen = {kanji="大手町"; kana="おおてまち"; romaji="otemachi"; shozoku="半蔵門線"} (* test *) let test1 = ekimei_insert otemachi_tiyodasen [] = [otemachi_tiyodasen] let test2 = ekimei_insert otemachi_tiyodasen [otemachi_hanzoumonsen] = [otemachi_hanzoumonsen] let test3 = ekimei_insert otemachi_tiyodasen [yoyogiuehara_tiyodasen] = [otemachi_tiyodasen; yoyogiuehara_tiyodasen] let test4 = ekimei_insert yoyogiuehara_tiyodasen [otemachi_tiyodasen] = [otemachi_tiyodasen; yoyogiuehara_tiyodasen] (* 目的:ekimei_t型のリストを受け取ったら,それを平仮名の順に整列し, さらに駅の重複を取り除いたekimei_t型のリストを返す *) (* seiretsu : ekimei_t -> ekimei_t *) let rec seiretsu lst = match lst with [] -> [] | first :: rest -> ekimei_insert first (seiretsu rest) let test1 = seiretsu [] = [] let test2 = [yoyogiuehara_tiyodasen] = [yoyogiuehara_tiyodasen] let test3 = seiretsu [otemachi_tiyodasen; otemachi_hanzoumonsen] = [otemachi_hanzoumonsen] let test4 = seiretsu [otemachi_tiyodasen; otemachi_hanzoumonsen; yoyogiuehara_tiyodasen] = [otemachi_hanzoumonsen; yoyogiuehara_tiyodasen] let otemachi = {namae = "大手町"; saitan_kyori = 0.; temae_list = ["大手町"]} let mitsukoshimae = {namae = "三越前"; saitan_kyori = infinity; temae_list = []} let shibuya = {namae = "渋谷"; saitan_kyori = infinity; temae_list = []} let aoyamaichome = {namae = "青山一丁目"; saitan_kyori = infinity; temae_list = []} (* 目的:直前に確定した駅 p (eki_t型)と味覚手の役のリスト v (eki_t list型)を受け取り 必要な更新処理を行った後の未確定の駅のリストを返す*) (* koushin -> eki_t -> eki_t list -> ekikan_t list -> eki_t list *) let koushin p v ekikan = List.map (fun q -> let kyori = get_ekikan_kyori p.namae q.namae ekikan in if kyori = infinity then q else let p_keiyu_q_kyori = p.saitan_kyori +. kyori in if p_keiyu_q_kyori < q.saitan_kyori then { namae = q.namae; saitan_kyori = p_keiyu_q_kyori; temae_list =(q.namae) :: p.temae_list} else q) v;; (* test data *) let otemachi = {namae = "大手町"; saitan_kyori = 0.; temae_list = ["大手町"]} let mitsukoshimae = {namae = "三越前"; saitan_kyori = infinity; temae_list = []} let shibuya = {namae = "渋谷"; saitan_kyori = infinity; temae_list = []} let aoyamaichome = {namae = "青山一丁目"; saitan_kyori = infinity; temae_list = []} let nagatacho = {namae = "永田町"; saitan_kyori = infinity; temae_list = []} let shinochanomizu = {namae = "新御茶ノ水"; saitan_kyori = infinity; temae_list = []} (* koushin test *) let koushin_test1 = koushin otemachi [mitsukoshimae; shibuya; shinochanomizu; aoyamaichome] global_ekikan_list =[{namae = "三越前"; saitan_kyori = 0.7; temae_list = ["三越前"; "大手町"]}; {namae = "渋谷"; saitan_kyori = infinity; temae_list = []}; {namae = "新御茶ノ水"; saitan_kyori = 1.3; temae_list = ["新御茶ノ水"; "大手町"]}; {namae = "青山一丁目"; saitan_kyori = infinity; temae_list = []}];; (* 目的:eki_t list型のリストを受け取り,「最短距離最小の駅」と 「最短距離最小の駅以外からなるリスト」の組を返す *) (* saitan_wo_bunri : eki_t list -> eki_t * eki_t list *) let saitan_wo_bunri eki_list = List.fold_right (fun first rest_saitan -> let (minimum, lst) = rest_saitan in if minimum.namae = "" then (first, lst) else if first.saitan_kyori <= minimum.saitan_kyori then (first, minimum :: lst) else (minimum, first :: lst)) eki_list ({namae = ""; saitan_kyori = infinity; temae_list = []}, []) let test1 = saitan_wo_bunri [{namae = "三越前"; saitan_kyori = 0.7; temae_list = ["三越前"; "大手町"]}; {namae = "渋谷"; saitan_kyori = 0.3; temae_list = ["渋谷"]}; {namae = "新御茶ノ水"; saitan_kyori = 1.3; temae_list = ["新御茶ノ水"; "大手町"]}; {namae = "青山一丁目"; saitan_kyori = infinity; temae_list = []}] =({namae = "渋谷"; saitan_kyori = 0.3; temae_list = ["渋谷"]}, [{namae = "三越前"; saitan_kyori = 0.7; temae_list = ["三越前"; "大手町"]}; {namae = "新御茶ノ水"; saitan_kyori = 1.3; temae_list = ["新御茶ノ水"; "大手町"]}; {namae = "青山一丁目"; saitan_kyori = infinity; temae_list = []}]);; (* 目的:eki_t list型の未確定の駅のリストとekikan_t list型の駅間のリストを受け取り ダイクストラのアルゴリズムにしたがって各駅について 最短距離と最短経路が正しく入ったリストを返す *) (* dijkstra_main : eki_t list -> ekikan_t list -> eki_t list *) let rec dijkstra_main eki_list ekikan = match eki_list with [] -> [] | first :: rest -> match (saitan_wo_bunri eki_list) with (saitan1, []) -> [saitan1] | (saitan2, rest) -> saitan2 :: (dijkstra_main (koushin saitan2 rest ekikan) ekikan) ;; (* test_data *) let otemachi = {namae = "大手町"; saitan_kyori = 1.7; temae_list = ["神保町"]};; let mitsukoshimae = {namae = "三越前"; saitan_kyori = infinity; temae_list = []};; let suitenguumae = {namae = "水天宮前"; saitan_kyori = infinity; temae_list = []};; let kiyosumishirakawa = {namae = "清澄白河"; saitan_kyori = infinity; temae_list = []};; let sumiyoshi = {namae = "住吉"; saitan_kyori = infinity; temae_list = []};; let dijkstra_test1 = dijkstra_main [otemachi; mitsukoshimae; suitenguumae; kiyosumishirakawa; sumiyoshi] global_ekikan_list = [{namae = "大手町"; saitan_kyori = 1.7; temae_list = ["神保町"]}; {namae = "三越前"; saitan_kyori = 2.4; temae_list = ["三越前"; "神保町"]}; {namae = "水天宮前"; saitan_kyori = 3.7; temae_list = ["水天宮前"; "三越前"; "神保町"]}; {namae = "清澄白河"; saitan_kyori = 5.4; temae_list = ["清澄白河"; "水天宮前"; "三越前"; "神保町"]}; {namae = "住吉"; saitan_kyori = 7.30000000000000071; temae_list = ["住吉"; "清澄白河"; "水天宮前"; "三越前"; "神保町"]}];; (* 目的:始点の駅名(ローマ字の文字列)と終点の駅名(ローマ字の文字列)を受け取り seiretsuを使ってglobal_ekimei_list の重複を取り除き, romaji_to_kanji を使って始点と終点の漢字表記を求め make_initial_eki_listを使って駅のリストを作り, dijkstra_mainを使って各駅までの最短路を確定し, その中空終点の駅のレコード(eki_t型)を返す*) (* dijkstra : string -> string -> eki_t *) let dijkstra siten shuten = let sorted_ekimei_list = seiretsu global_ekimei_list in let siten_kanji = romaji_to_kanji siten sorted_ekimei_list in let shuten_kanji = romaji_to_kanji shuten sorted_ekimei_list in let initialized_list = make_initial_eki_list siten_kanji sorted_ekimei_list in let saitan_list = dijkstra_main initialized_list global_ekikan_list in let rec serch item lst = match lst with [] -> {namae = ""; saitan_kyori = infinity; temae_list = []} | first :: rest -> if first.namae = item then first else serch item rest in serch shuten_kanji saitan_list;; (* test *) (* サポートページからのコピペ *) let test1 = dijkstra "shibuya" "gokokuji" = {namae = "護国寺"; saitan_kyori = 9.8; temae_list = ["護国寺"; "江戸川橋"; "飯田橋"; "市ヶ谷"; "麹町"; "永田町"; "青山一丁目"; "表参道"; "渋谷"]} let test2 = dijkstra "myogadani" "meguro" = {namae = "目黒"; saitan_kyori = 12.7000000000000028; temae_list = ["目黒"; "白金台"; "白金高輪"; "麻布十番"; "六本木一丁目"; "溜池山王"; "永田町"; "麹町"; "市ヶ谷"; "飯田橋"; "後楽園"; "茗荷谷"]}
OCamlの無名関数は再帰を定義できない?
わたろーです.
今プログラミングの基礎 (Computer Science Library)を読んでいます.
これはOCamlとデザインレシピでプログラミングの基礎を学ぶという内容なのですが,
名前のない関数という節で気になる文章がありました.
14.4 名前のない関数 p145
名前のない関数で定義できるのは再帰をしていない関数だけです.
OCamlはラムダ計算を元にしていると思っていたので驚きました.
Yコンビネータ使って再帰出来ないのって思ったので試してみました.
Yコンビネータは計算機プログラムの構造と解釈 第2版p233 問題4.21に載っていたものを使います.
;;; SICP ;;; 階乗計算 (lambda (n) ((lambda (fact) (fact fact n)) (lambda (ft k) (if (= k 1) 1 (* k (ft ft (- k 1)))))))
実行すると
gosh> ((lambda (n) ((lambda (fact) (fact fact n)) (lambda (ft k) (if (= k 1) 1 (* k (ft ft (- k 1))))))) 5) 120
これをOCamlで書いてみます.
# (fun n-> (fun fact -> fact fact n) (fun ft k -> if k = 1 then 1 else k * (ft ft (k - 1)))) 5;; Characters 33-37: fact fact n) ^^^^ Error: This expression has type 'a -> 'b -> 'c but an expression was expected of type 'a The type variable 'a occurs inside 'a -> 'b -> 'c
エラーですね.
型が解決されていないのでしょうか.
ググッてみると -rectypesを使ってインタプリタを起動すれば出来るようです.
# (fun n-> (fun fact -> fact fact n) (fun ft k -> if k = 1 then 1 else k * (ft ft (k - 1)))) 5;; - : int = 120
おお,動いた.
再帰型っていうのが必要になるわけなんですね.
まだまだわからないことだらけですが,型もおもしろそうです.
この辺探すのに行き着いたこのページのTaPLのまとめがすごくおもしろそうです.
おもしろそう.読みたい.すごく読みたい. でもまだ自分には厳しそう.
その前にプログラミング言語の基礎概念 (ライブラリ情報学コア・テキスト)を読みたい.
しかしその時間を作れるか.
そろそろお仕事探しのために動かないといけないかもって思ってきています.
勉強だけしていたい.
プログラミング初心者がSICP(計算機プログラムの構造と解釈)を読んでみた
読む前の状態と動機
- 読み始めた時点でプログラミング歴約1年
- もうひとつのscheme入門でプログラミングに入門するも,高階関数で挫折.
- Ruby本二冊,Rails Tutorialを二周.
- 他読み始めたけど途中で飽きた本が何冊か.
- 仕事(非IT)が忙しく,プログラミング始めて一年でこれくらいしか出来なかった.
- 基本的なところがしっくりこない.
- でもコード書くのは楽しいし,出来ればそれを仕事にしたいので基礎を身に着けたい.
- 無職になって時間もあるから基礎を身につけるためにSICPを読もう.
読むための準備
- Scheme手習いとプログラミングGaucheを読んでからSICPにとりかかった.
- メインで読んだのは2版の和田訳.読んでわからない時は原著や1版の元吉訳に当たる.
- 後半になると真鍋訳が登場したためこちらにも助けられた.
SICPを読む過程で得たもの
- 括弧が気にならなくなった
- S式のほうが読みやすいのになんで中置記法のほうがメジャーなの?
- 再帰的プロセスと反復的プロセス
- 第一級手続き
- 抽象の壁
- メッセージパッシング
- 型によるディスパッチと強制型変換
- イベントドリヴン
- 制約の拡散
- 破壊的代入が怖くなった
- ストリーム
- 遅延評価
- 超循環評価器の実装を通して評価戦略を理解した.
- レジスタマシンのシミュレータによって低レベルで何が行われているのか理解した.
- コンパイラとインタプリタの効率の違い
感想
4ヶ月半近くかかった.
SICPは基礎と聞いていたけど,やっぱり基礎でした.
今の段階で読んでおいてよかった.
問題全部解くつもりはなかったけど,だんだんと自力で解きたくなってきたため結局ほとんど自力で解いていた.
解けないと悔しい.
問題やってみて思うのは,時間がめちゃくちゃかかるけど解かないと理解できなかった.
特に4章からは本文のコードを動かすにもデバッグが大変で,問題解くにもデバッグが大変.
でもそのデバッグを通して何度もコードや本文を読むことでそこで何をしているのか理解していけた.
最後はソースがコメントだらけになった.
C言語でやる問題が2問残っているのでCを勉強してから解きたい.
プログラミング楽しい!にプログラミング言語おもしろい!も追加された.
プログラミング初心者からプログラミング初級者へレベルアップできた・・・はず.
これから読む人にはScheme手習いを読んでおくことを勧めたい.
読みにくいし後半急激に難しくなるけど,そこで継続を渡すことを覚えておくと楽になる.
デバッグ方法も覚えておかないと4章から辛いので
Gauche使うならプログラミングGaucheにも一通り目を通しておいたほうがいい.
かなり苦しんだけど,それでも楽しい・おもしろいのほうが勝ってる.
まだ半年は生きていけそうなのでまだまだ勉強してコード書く仕事につけるように頑張ります.
とりあえずプログラミングの基礎 (Computer Science Library)でMLとデザインレシピに触れてからK&Rを読もうと思ってます.
- 作者: ハロルドエイブルソン,ジュリーサスマン,ジェラルド・ジェイサスマン,Harold Abelson,Julie Sussman,Gerald Jay Sussman,和田英一
- 出版社/メーカー: 翔泳社
- 発売日: 2014/05/17
- メディア: 大型本
- この商品を含むブログ (2件) を見る
- 作者: Daniel P. Friedman,Matthias Felleisen,元吉文男,横山晶一
- 出版社/メーカー: オーム社
- 発売日: 2010/10/22
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 129回
- この商品を含むブログ (33件) を見る
- 作者: Kahuaプロジェクト,川合史朗
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/03/14
- メディア: 大型本
- 購入: 22人 クリック: 713回
- この商品を含むブログ (272件) を見る