プログラミング言語の入門書はプログラミングの入門書ではないのでプログラミングできるようにならない

(これはPR記事です)
「入門書を読んだけどプログラミングできるようにならない」という話はよく聞きます。

そこで「まあ経験や慣れが必要だからね」みたいな話になり、その後、経験を積んでもできるようにならない人は「センスがなかった」ということになったりします。
じゃあそのセンスっていうのは何かというと、結局のところ「できるようになった人にはセンスがあった」という生存者バイアスなだけで、運とそんなに違いないわけです。

でも、トップレベルを目指すとかではない限り、それなりの知識とトレーニングがあればほとんどの人はプログラミングできるようになるはずです。

で、まあ入門書を読んでプログラミングできるようにならないほは当然で、プログラミング言語の入門書のほとんどは、プログラミング言語の入門書であってプログラミングの入門書ではありません。

変数の説明にしても、箱だったり場所だったりで例えて「それが何であるか」の説明をがんばったりするのだけど、じゃあ実際どう使うかというのは説明してくれません。
プログラムで一番難しいのはループですが、ループの構文の説明があるだけで、ループのコードをどのように考えていく必要があるかというのは説明されてません。
クラスにしてもオブジェクト指向というなにやら壮大な言葉をもってきて、これがオブジェクト指向ですというプログラムを提示するのだけど、じゃあそのコードを実際のプログラミングでどう使うの?っていうのはわかりにくいわけです。「プログラミングはオブジェクト指向でやるから!」みたいにケムにまかれ、でも実際はオブジェクト指向でやらないのでそんなコードは出番がない。

ということで、変数の使い方をちゃんと提示していたり*1 、ループがどのように難しくなるか説明していたり、クラスの使い方を差分プログラミングとデータの分類にわけて説明したりしてる本が3/19に出るわけですね。

FAQ
Q 電子版はでますか?
A 紙版のあとに出る予定

Q 目次等は?
A もうしばらくお待ちを

*1:変数の使い方は、もうすこし整理できればと思ったけど紙面の都合でな・・・提示は している

JavaScriptはJavaのScript版(であろうと努力はした)

JavaJavaScriptを混同する人に、名前がかぶってるだけの別モノという指摘がされることもあります。間違いではない。
技術的にも実務的にもコミュニティ的にもそのとおりではあります。
ただ、そう言い続けられた結果、ほんとに単にLiveScriptの名前にJavaをもってきてJavaScriptにしただけという誤解があるようです。

JavaScriptJavaのScript版、少なくともそうであろうという努力はされていました。
JavaScriptリリース時のCNETの記事には「JavaScript is based on Java」という記述があります。
Netscape and Sun Unveil JavaScript - CNET

実際には、LiveScriptにJavaから文法やライブラリなどを持ち込んでリリースにこぎつけたというのがあります。
JavaScriptのDateはJavajava.util.Dateの移植なのですが、「Javaに似せるように」という圧が強すぎて2000年バグまでJavaScriptに持ち込んでしまうということもあったようです。
f:id:nowokay:20220207013618p:plain:w400
https://www.mozilla.org/js/language/ICFP-Keynote.ppt

JavaのほうのDateはバージョンアップして日付の扱いとしては妥当に、そして使いにくくなっていったのですけど、JavaScriptのDateはJava 1.0当時のままなので、日本の昔の文化なんだけど日本ではすでに行われてなくてヨーロッパの田舎のお祭りになぜか残ってる、みたいな感じがしていいですね。

当時の状況として、MicrosoftWindowsでデスクトップ市場を独占していて、脅威に思ったSun、IBMOracleなどがJavaの下に集まって対抗しようとしていました。合従の策だったわけですね。
そんな中で、MSはインターネットもInternet Explorerで独占する動きを見せ始めていました。初期のIEは機能的にはたいしたことありませんでしたが、当時のMSはOSシェアを利用した独占禁止法ギリギリアウトな手法で司法省に怒られながら市場を奪っていってたので、何か新しい製品を出せば内容に関わらず脅威だったのです。

上記のパワポみると、1994年後半にMSはNetscapeを買収しようとして失敗したようで、IEを使ってNetscapeを潰しにきたのが明らかだったのです*1。 そこで、SunとNetscapeは、ブラウザ上でアプリケーションを立ち上げるための入り口になる、デザイナが書くスクリプトとしてJavaScriptを用意したわけです。プログラマが書くアプリケーションはJava Appletとして作る前提です。

インターネットマガジン1996年11月号の記事でのNetsape+JavaScript+Java Applet と Internet Explorer + Visual Basic + ActiveXの対立構造の扱いはこんな感じ。
f:id:nowokay:20220209121322p:plain
https://i.impressrd.jp/files/images/bn/pdf/im199611-210-sp.pdf

ただまあ、CPUクロックが150MHzでメモリが数メガバイトという当時の環境ではJava VMの起動も実行も遅く、Java 1.0ではJarというパッケージングも用意されていなかったので数十のクラスファイルをダウンロードしなければならずそれも144Kbpsで速いほうだった当時のネット接続には重すぎて、Shockwaveのほうが流行りFlashに置き換わり、そしてHTML5にみんな殺されてしまいました。

MicrosoftWindowsで市場を独占するぜという方針を捨てIEも捨て、ブラウザ非依存のネットサービスでやっていく方針になり、JavaScriptJavaを連携させてMicrosoftに対抗するぜという機運は人々の記憶から消えたのでありました。

おしまい。

追記
Coders At Workの4章にJavaScript作者であり上記のパワポを作ったブレンダン・アイクの章があって、JS作成時の話が載ってるそうな。

追記2(2022/2/14)
JavaScriptの歴史については「JavaScript: the first 20 years」が面白いとのこと via @tad
https://dl.acm.org/doi/10.1145/3386327

著者のブログ
JavaScript: The First 20 Years

日本語での解説はこちら
JavaScriptの歴史については「JavaScript: The First 20 Years」を読む | Web Scratch

*1:そして実際に潰された。4000円くらいで売ってたNetscapeに対してIEを無償配布してきたわけで

情報収集について

情報収集をどうするか、という話をしたのでメモ。
ここではトレンドを追うための日々の情報収集の話です。プロジェクトの準備のためとかトピックが決まってる場合はまたちょっと違うかも。

まず情報収集であまり話題にのらないけど一番大事なのは、情報収集の優先度です。

情報収集は無限に深堀して無限に時間をかけることができるので、どこまで情報収集が大切なのかというのを考える必要があります。
まず情報収集自体がどれだけ大切かということで、ぼくの場合は、情報収集して発信することがある程度の役割としてあるので毎日それなりに時間をかけているけど、普通にエンジニアをやる場合はそこまで時間をかけるものでもないと思います。

で、収集する情報にも当然に優先度があります。これは雑に3段階くらいに分けると次のような感じになります。

  • 一般教養
  • 専門分野
  • 自分の強みになる分野

それぞれ情報の収集のしかたは変わるのだけど、そのまえに情報収集でなにが一番大切かという話。 日々の情報収集で一番大切なのは「どのくらいの量の情報が流れているか」です。セキュリティにあまり興味がなくても「最近Log4jの話がいっぱい流れてくるな」ていうのさえ知っていれば、実際に必要になったときにあとから確認できるので。

あと、人気ニュースが流れてくる系は情報収集という文脈ではあまりおすすめしません。センセーショナル・スキャンダラスなニュースが流れがちなので、情報収集というよりはコンテンツ消費になりがち。
情報収集するとき、情報収集をしていない人が知らない情報を得るというのが効果としては高いので、みんなが知ってることばかり知ってもあまり意味がないというのもあります。トレンドの後追いになってしまう。Twitterに流れない情報をおさえるというのも情報収集の役割だったりするので。
ただ逆に、情報収集に時間をかけれないという場合はトレンド後追いが一番効率がいいので、そういう場合は有用だと思います。

各分野について、まずは一般教養
これは世の中全体の流れを見る上で押さえておきたいところ。
情報収集という点では紙の新聞が一番理想なんだけど、物理の紙は現代において不便すぎて差し引きマイナスみたいな感じ。紙の新聞が理想なのは、デバイスとして大きいので一目で多くの記事が目にはいりながら面積で情報の大切さがわかるところ。特に面積でわかるというのは大切で、「どのくらいの量の情報が流れているか」が感覚としてつかめていいです。
ただまあ、現実的に難しいので、新聞社のサイトに課金してRSSを読むとなるのだけど、現状RSSを提供しているのは朝日新聞だけ。朝日新聞も、目立つ記事が批判されまくりで印象悪い人もいるかもしれないけど、ツイッターに流れてこないような目立たない記事がとてもいいです。地味な記事もちゃんと取材をして書かれているので、それは新聞社の力だなと思います。
各新聞社サイトで上位課金だと紙と同じレイアウトで見れるけど、紙というデバイスの優秀さがあってこそなのでそこまでしてPCで見てもなぁという感じもある
新聞社サイトじゃなければ、NHKかテレビ局のニュースサイトですね。

次に、順番前後するけど自分の強みになる分野
これは1次情報をちゃんとチェックするのがいいです。ぼくの場合はJavaなので、OpenJDKのメーリングリストやらをチェックしています。ここは範囲が狭い分 発信量がそんなに多くないはずなので、週1とかの間をあけたチェックでもいいし、日々の更新が多くないことを考えれば毎日みても問題ないはず。
めちゃ開発が盛んで日々の流量も多いホットな分野であれば、その流れに細かくついていく必要もないのでタイトルだけ眺めるでいいですね。

最後に、専門分野
押さえておかないといけないけど強みになるほどでもない、みたいなところ。
これはおそらくニュースをまとめてくれる人がいるので、そういうのを見つけてチェックするのがいいですね。Javaだと infoq.com に毎週Java News Roundupというのが出るのでそれをチェックするとか。英語版だけど「JDK 18, JDK 19, Groovy DSL for Spring Integration, JHipster, Micronaut Foundation」を日本語にしたところで、みたいな感じでもあるので、どの製品にどのくらいの分量の記述があるかってチェックだけでもやるといいです。
専門分野ごとのニュースサイトというのもありますね。public keyとか。
だれもまとめてる人がいなかったら自分でまとめるとモテるのでがんばっていいと思います。

まあ、情報収集は優先度があって、先取りして強みにしたいかタイムリーに話題にのりたいか後追いで知っておけばいいのか、それ考えて工夫したほうがいいよっていうのと、流量のチェックが大切っていうのが一番つたえたかったところ。

代数データ型の直積型と直和型の理解

代数データ型という考え方があって、型に対する代数的な操作を行うものっぽいです。代数的な操作というのは、足し算とか掛け算ですね。直和型と直積型というのがあります。

直積型は構造体のようなもので、Javaだとrecordが導入されましたね。

record A(int p1, boolean p2) {}

みたいなものです。
これがなぜ積なのかというと、このレコードAの取りうる値の組み合わせは、intの値のパターン数(2 ^ 32) × booleanの値のパターン数(2)で2 ^ 33になるからなんだと思います。

直和型は、型がこれかこれ、みたいになるやつです。Javaだとtry-catchのcatch句に直和型が指定できて、この例外かこの例外、みたいな書き方ができますね。

catch (NullPointerException | NumberFormatException ex) 

あとsealed classが導入されたので同じようなことができます。

sealed interface B permits C, D {
}
record C(int n) implements B{}
record D(boolean f) implements B{}

こうすると、型Bは型Cか型Dの値を扱えることになります。このとき、型Bの取りうる値の組み合わせは、型Cの取りうる値の組み合わせ(2 ^ 32)と型Dの取りうる値の組み合わせ(2)を足したものになって2 ^ 32 + 2になります。*1
なので直和型ですね。

ということを忘れないようにメモ

*1:Javaの場合、nullも扱えるので2 ^ 32 + 2 + 1になりますね。滅ぼすべき

基礎と低レイヤーは混同しがち。基礎とは何で、どう勉強するか。

基礎と低レイヤーは混同しがちという現象をみかけたのでメモ

よくあるのが、「IDEを使うと基礎が勉強できない、メモ帳でコードを書いてコマンドラインでjavac / javaするところから始めるべき」みたいな話。
ツールを使わずツールが隠してる部分を自分でやって勉強せよ、フレームワークを使わずフレームワークが隠してる部分を自分でやって勉強せよ、という話は、これ自体は間違いではないのだけど、これを「基礎」と言ってしまうと違った方向に行ってしまう。

これは基礎ではなくて低レイヤーではなかろうか。

そして、低レイヤーは「ツールを使わずにやれ」と言ってる人の想定する「ツールを使わず」というのもすでにツールを使っていたりする。ほんとに低レイヤー知りたいなら、javac使わずハンドコンパイルでしょう。Javaバイトコード知っておくべきでしょう。 と、だんだんマニアックなこと知ってる自慢になっていく。 こういうのは、知っておくほうがもちろんいいんだけど、それを勉強するのはある程度わかってからでよくて、最初にやることではないと思う。

じゃあ、基礎はなんなのかというのをちょっと考えてみた。 基礎というのは、楽器演奏ならスケールだったり、絵であれば球とか立方体のデッサンだったり、プログラミングなら条件分岐とループでロジックを書くことだったり、アプリケーションつくるなら入力を受け取って加工して表示とか保存とか。

つまり、基礎というのは、単純で退屈だけどこのパターンは必ず出てくるな、というものではないかと。
そういったパターンをまとめて共通部分を抜き出して抽象化したものは、より強い基礎になる。けど難しい。
なのでまずは具体的なパターンをいくつかやってみて、なんだか共通部分があるなと気づいたくらいで抽象的に考えるという具合に勉強を進めるのがいいのだと思う。

一方で低レイヤーは、細かくてめんどくさくて裏側こうなってたのかーというやつ。
これは勉強したほうがいいのだけど、やりたいことの実現が何に支えられているかという話で、やりたいことをいかに実現するかというのとは別。
楽器演奏なら楽器の仕組みだったり絵であれば画材の特性とか人体解剖図とか、プログラミングならライブラリの実装やアセンブラやCPUとか。

基礎の勉強として、もしかしたら何にでも通用するかもしれない注意点を思いついた。
「最後までやる」ということ。
基礎の教科書を最後までやるという話ではなくて、絵であれば球を書き始めるのであれば途中で失敗したとしても書き上げる、スケールも途中で音をはずしても最後のドまでとりあえずやる、ロジックを組むなら正しい処理がわからなくてもとりあえず結果が出るところまでは組む。簡単なアプリケーションを作るならアプリケーションとして成り立つところまで作る。

サッカーで、試合形式での攻撃の練習は必ずシュートで終われみたいな話があって、それは途中でどんなにうまくパスまわしできてもシュートにつながらないなら意味がないしゴール前までボールをあげれてもシュートする人が走りこんでないならただのバクチだし、守備がうまくてパス回しをさせられたボールを蹴らされたというのがあるかもしれない、みたいな話。
これが結局いろいろ通じて、楽器のスケール練習にしても途中までうまくできるんだけど詰まるのならうまくできてないし、うまくできなくても最後まで音をつなげるというのは大事。絵で、途中で失敗したと思っても書きあげたらつじつまがあうということもある。アプリケーションで、実装が簡単なところだけ作って途中で作業が進まなくなるなら、それは完成させない前提だから簡単だっただけということもある。

まあ、なんにせよ基礎はちくちくとやっていくと100日もやればなんなりか力になるし、やっていくといいんじゃなかろうか。

Javaで作るのは他人のためのプログラム、Pythonで作るのは自分のためのプログラム

JavaやCで組むのは他人のためのプログラムで、Pythonで組むのは自分のためのプログラム、という違いがないかなという話。

TIOBEでとうとうPythonが1位になったというニュースが流れてました。
https://internet.watch.impress.co.jp/docs/yajiuma/1357645.html

でも、Pythonが1位になったとはいえ、CやJavaであったような、世の中のプログラム全部Pythonになるみたいな雰囲気はないなと思いました。

で、こんなツイートをしたわけです。

Pythonの入門書で「ざっくりこういうことをするのにこのくらいのコードが必要というのがわかればいい」ということが書いてあって、Javaの入門書ではそうならないよなと思ったことがありました。
それで、そもそもJavaPythonでは勉強のモチベーションが違うということに気づきました。

Javaでプログラミングの勉強を始める人というのは、基本的に転職目的が多いと思います。この場合、プログラムを作る仕事をしたいわけで、そこで作ることになるのは他人のためのプログラムです。
一方でPythonでプログラミングを始める人は、手元の作業を効率化したり、手元のデータを分析したり、純粋にプログラミングの勉強だったり、自分のためのプログラムを作ることを目的としていることが多いと思います。

つまりはJavaPythonで作るプログラムが違うなと。

Javaでは他人のために、プログラマのいないところで動くプログラムを作ります。そうすると、正しく動くことを保証する必要性は高くなり、必要な機能をすべて実装する必要もあります。
一方でPythonでは自分のために、プログラマの目の前で動くプログラムを作ります。そうすると、正しく動かなかったらそのときにやりなおせばいいし、手早く動かせる必要があります。*1

C++を作ったBjarne StroustrupC++の静的型検査についてこういうことを書いてます。

タイプミスマッチの問題をコンパイル時に検出することが、なぜこれほどまでに重要なのか?・・・それは、C++のプログラムの多くが、プログラマのいないところで使われるからだ。
C++の設計と進化

ここではJavaの話ばかりを書きましたが、静的型をはじめ、プログラムが正しく動くことを保証する仕組みというのは、プログラマをはなれて動くプログラムだからこそ重要なのだなと思った話でした。

*1: 傾向の話であって、Javaでも自分のためのプログラム作るとか、Pythonでも他人のためのプログラム作るとか、そいういう話はここではしない

龍馬1865 - おいしいノンアルビール飲み比べ

龍馬1865
以前飲んだときの甘ったるさはなくなって、栗のような香ばしさがある
f:id:nowokay:20211009152201p:plain

日本ビールのノンアルビール です。 原材料は麦芽、ロースト麦芽、ホップと炭酸で、アルコール度数は0.000%
一本あたり112円。以前は一本あたり117円だったからちょっと安くなってる。

カチプラと同じかと思っていたのだけど、レビューみる限りカチプラのほうが少し薄いぽい。

https://nowokay.hatenablog.com/entry/2020/11/02/214730