スキップしてメイン コンテンツに移動

去る6月に Perl 5.32.0 がリリースされたので差分を把握するために perldelta を読んだ件

要旨

Perl 5 メジャーバージョンアップの季節がやって来たのでまともな Perl プログラマの嗜みとして perldelta を読んだ。

今回は有り体に言えばルーティン的なリリースで、言語コアの拡張は他言語にも見られる構文が実験的に入ったくらいで大きな変化はない。新機能は RegExp の拡充が主である。

比較的重要と思われる変更点を抜粋する。

新機能

isa 演算子

実験的機能。Python とか Java における isinstance とか instanceof

これまでも UNIVERSAL::isa があったが、これはメソッドなのでレシーバにオブジェクトでもクラスでもない値 (i.e., 未定義値 / bless されていないリファレンス) を置くと実行時エラーが起きるのが問題だった:

package Foo {
  use Moo;
}

package Bar {
  use Moo;
  extends 'Foo';
}

package Baz {
  use Moo;
}

use feature qw/say/;

sub do_something_with_foo_or_return_undef {
  my ($foo) = @_;

  # Returns safely if the argument isn't an expected instance, in mind.
  return unless $foo->isa('Foo');
  ...;
}

# OK.
do_something_with_foo(Bar->new);

# |undef| is expected in mind, but actually error will be thrown.
do_something_with_foo(undef);

これを避けるために今までは Scalar::Util::blessed を併用したりしていたわけだが、isa 演算子は左辺が何であっても意味のある値を返すのでよりシンプルになる:

# True
+(bless +{} => 'Foo') isa Foo;

# False
undef isa Foo;

# False
+{} isa Foo;

# False
+(bless +{} => 'Baz') isa Foo;

比較演算子の連結

Python のアレ。このために比較演算子の結合性が「連結 (chained)」に変更された。

my $x = rand(10);
say 0 <= $x < 5 ? '< 5' : '>= 5';
use Math::Round qw/nearest/;

sub PI() { 4 * atan2(1, 1) }

# Rounds to the second decimal place.
sub round($) { nearest(0.01, $_[0]) }

say round sin(0) == round cos(PI / 2) == round sin(PI) != round cos(PI)
  ? 'sin(0) = cos(π / 2) = sin(π) ≠ cos(π)'
  : 'You are in wrong universe.';

連言で繋いだ場合と比べて連結された中間の式の評価回数が一回減ることに注意が必要である; A <= B < C の式 B は一回しか評価されないのに対して、A <= B and B < C の場合は高々二回評価される。

my $x = 40;
say $x if 0 <= ++$x < 42;  # 41

my $y = 40;
say $y if 0 <= ++$y and ++$y < 42;  # Doesn't print.

副作用のある式を混ぜる方がどうかしているといえばそれまでだが。

Unicode Name プロパティ参照

\p{Name=...} で Unicode 文字を名前 (e.g., “LATIN CAPITAL LETTER A”)で参照できるようになった。これまでも \N があったが、主な違いは文字列補間が効くことと、名前に対して副パターンでマッチングできる (e.g., (qr!\p{Name=/LATIN CAPITAL LETTER [A-F]/}!)) ことである。

実験的機能の正式化

Perl 5.28 で実験的機能として導入された正規表現パターンがいくつか標準で警告なしに使えるようになった。

Script Run

ドメイン名スプーフィング (ラテン文字とキリル文字など見た目に区別しづらい字形の文字を混ぜて権威あるサイトに見せかける手法) を検出するのに有用な機能。 (*script_run:...) ないし (*sr:...) で囲んだパターンが同一の Unicode Script にある文字で成り立っていない場合バックトラックする。ただし日常的に複数の Script を使う東アジアのいくつかの言語の文字は少し特別扱いされる。

ラテン文字による別名

既存の拡張正規表現に説明的な別名を付ける試み。コア言語の特殊グローバル変数に対する English.pm のような関係だがこれは新しい構文と一緒に導入されたので特に宣言なく利用可能である。

Symbolic Alias(es)
(?=...) (*pla:...) / (*positive_lookahead:...)
(?!...) (*nla:...) / (*negative_lookahead:...)
(?<=...) (*plb:...) / (*positive_lookbehind:...)
(?<!...) (*nlb:...) / (*negative_lookbehind:...)
(?>...) (*atomic:...)

非互換な変更

字句的定数関数内の変更され得る字句的スコープ変数参照の違法化

Perl は 0 引数で暗黙に値を返す関数を定数としてインライン化するが、実はこの最適化は戻り値として字句的スコープ変数を参照するクロージャにも適用される。 一度インライン化された値は実行時に変更しても反映されないので、定数と認識されたクロージャは一般的なクロージャとは異なる挙動をすることになる:

my $x = 42;
# Constant.
my $K = sub () { $x };
# Closure; Avoiding optiomization by explicit |return|.
my $L = sub () { return $x };

say $K->() + 1;  # 43
say $L->() + 1;  # 43

$x = 0;
say $K->() + 1;  # 43 (!)
say $L->() + 1;  # 1

端的に言って最適化器のバグなのだが、Perl は意図した機能かそうでないかに関らず現実に用例がある挙動は変えないのが伝統であった。公式にこの方針が転換されたのは Perl 5.14 からで、実際に廃止予定 (deprecated) 機能の廃止ロードマップ (perldeprecation) が示されたのは Perl 5.26 からである。

この機能に関しては経過措置として Perl 5.22 から警告が出ていたが予定通り廃止された。今後はこのようなサブルーチンを定義することは単に違法であり、コンパイル時に致命的エラーとなる

なお変更され得ない字句的スコープ変数についてはこれまでどおり参照して良い。ライフサイクルを通して以下のような「変更され得る」操作を受けないのが条件である:

# Error.
$x = 0;

# Error; No matter even if the branch is never reached.
$x = 0 if 0;

# Error; Subroutines can take aliases of arguments so it can be altered.
proc($x);

また字句的スコープでない変数を参照している場合や、クロージャでないサブルーチン定義の場合はそもそもインライン化されないので関係がない:

my $x = 42;
our $y = 42;

# OK; |$y| is not a lexical variable.
my $K = sub () { $y };

# OK; Global subroutines referencing variables are not inlined.
sub L() { $x }

# OK; Ditto, even if lexical subroutines.
use feature qw/lexical_subs/;
my sub M() { $x }

その他

GitHub への移行

https://github.com/Perl/perl5 が Perl 5 のプライマリなリポジトリになった。開発も GitHub の Issues / PRs を使って行われるようになった。 ただし脆弱性の報告は相変わらず非公開のバグトラッカーとメーリングリスト (cf. perldoc perlsec) にて扱われる。

コメント

このブログの人気の投稿

Perl 7 より先に Perl 5.34 が出るぞという話

Perl 5 の次期バージョンとして一部後方互換でない変更 (主に間接オブジェクト記法の削除とベストプラクティスのデフォルトでの有効化) を含んだメジャーバージョンアップである Perl 7 がアナウンスされたのは昨年の 6 月 のことだったが、その前に Perl 5 の次期周期リリースである Perl 5.34 が 5 月にリリース予定 である。 現在開発版は Perl 5.33.8 がリリースされておりユーザから見える変更は凍結、4 月下旬の 5.33.9 で全コードが凍結され 5 月下旬に 5.34.0 としてリリース予定とのこと。 そういうわけで事前に新機能の予習をしておく。 8進数数値リテラルの新構文 見た瞬間「マジかよ」と口に出た。これまで Perl はプレフィクス 0 がついた数値リテラルを8進数と見做してきたが、プレフィクスに 0o (zero, small o) も使えるようになる。 もちろんこれは2進数リテラルの 0b や 16進数リテラルの 0x との一貫性のためである。リテラルと同じ解釈で文字列を数値に変換する組み込み関数 oct も` 新構文を解するようになる。 昨今無数の言語に取り入れられているリテラル記法ではあるが、この記法の問題は o (small o) と 0 (zero) の区別が難しいことで、より悪いことに大文字も合法である: 0O755 Try / Catch 構文 Perl 5 のリリース以来 30 年ほど待たれた実験的「新機能」である。 Perl 5 における例外処理が特別な構文でなかったのは予約語を増やさない配慮だったはずだが、TryCatch とか Try::Tiny のようなモジュールが氾濫して当初の意図が無意味になったというのもあるかも知れない。 use feature qw/ try / ; no warnings qw/ experimental::try / ; try { failable_operation(); } catch ( $e ) { recover_from_error( $e ); } Raku (former Perl 6) だと CATCH (大文字なことに注意) ブロックが自分の宣言されたスコープ内で投げられた例外を捕らえる

BuckleScript が ReScript に改称し独自言語を導入した

Via: BuckleScript Good and Bad News - Psellos OCaml / ReasonML 文法と標準ライブラリを採用した JavaScript トランスパイラである BuckleScript が ReScript に改称した。 公式サイトによると改称の理由は、 Unifying the tools in one coherent platform and core team allows us to build features that wouldn’t be possible in the original BuckleScript + Reason setup. (単一のプラットフォームとコアチームにツールを統合することで従来の BuckleScript + Reason 体制では不可能であった機能開発が可能になる) とのこと。要は Facebook が主導する外部プロジェクトである ReasonML に依存せずに開発を進めていくためにフォークするという話で、Chromium のレンダリングエンジンが Apple の WebKit から Google 主導の Blink に切り替わったのと似た動機である (プログラミング言語の分野でも Object Pascal が Pascal を逸脱して Delphi Language になったとか PLT Scheme (の第一言語) が RnRS とは別路線に舵を切って Racket になったとか、割とよくある話である。) 公式ブログの Q&A によると OCaml / ReasonML 文法のサポートは継続され、既存の BuckleScript プロジェクトは問題なくビルドできるとのこと。ただし現時点で公式ドキュメントは ReScript 文法のみに言及しているなど、サポート水準のティアを分けて ReScript 文法を優遇することで移行を推進していく方針である。 上流である OCaml の更新は取り込み、AST の互換性も維持される。将来 ReScript から言語機能が削除されることは有り得るが、OCaml / ReasonML からは今日の BuckleScript が提供する機能すべてにアクセスできる。 現時点における ReScript の

多分週刊チラシの裏 (Mar 23, 2021 - Mar 27, 2021)

Intel プロセッサのマイクロコードを変更する非公開命令が発見される 今日のプロセッサは複雑な命令を単純な回路で実装したりバグの修正を容易にするため、1 個の命令でも実際にはプロセッサ内部に格納されたマイクロプログラムを実行するようになっていることが多い。 かつて浮動小数点演算器のバグで Pentium をリコールする羽目になった Intel も例外ではないのだが、Intel が電子署名したマイクロコードでなくとも適用できる非公開命令が発見されたという報告。 ただし無条件ではなく、命令自体はユーザモードでもデコードされるがプロセッサが特定の “Unlocked State” にないときは未定義命令として処理されるらしい。 MSKK の週休三日トライアルで生産性が四割向上 2019 年の記事。週休三日制を導入する事業所は中小を中心に増加しているが、Microsoft の日本法人であるマイクロソフト株式会社 (MSKK) が “Work Life Choice Challenge” と称して 2019 年夏に実施した金曜日を休日とする試験的措置において、前年同月比 40 % の生産性向上が見られたとのこと。 同施策は休日の追加に加えて会議時間短縮の奨励、またメッセージングアプリによる会議自体の代替なども含んでいる。 2015 年の電通における過労自殺事件に国際的な耳目が集まって以降、日本は「過労死」に象徴される長時間労働の是正に取り組んでおり、MSKK のこの措置は将に時節を得たものであったと言える。 r/WallStreetBets からゴリラ保護基金へ多額の寄付 「みんなで株価吊り上げて食い付いたヘッジファンド釣ろうぜ」という一種の祭で GameStop の株価が高騰したのは今年の 1 月だが、その震源地であった Reddit の WallStreetBets (WSB) コミュニティからマウンテンゴリラ保護のための基金である The Dian Fossey Gorilla Fund International に 350,000 USD の寄付があったとのこと。 ところで何故ゴリラかというと「猿の惑星」に倣って WSB コミュニティ内で同志を猿 (ape) と称していたからとか。異説に「猿みたいに株を買うのにキーボードを連打しているから」とも。

OCaml で Web フロントエンドを書く

要旨 フロントエンド開発に Elm は堅くて速くてとても良いと思う。昨今の Flux 系アーキテクチャは代数的データ型と相性が良い。ところで工数を減らすためにはバックエンドも同じ言語で書いてあわよくば isomorphic にしてしまいたいところだが、Elm はバックエンドを書くには現状適していない。 OCaml なら js_of_ocaml でエコシステムを丸ごとブラウザに持って来れるのでフロントエンドもバックエンドも無理なく書けるはずである。まず The Elm Architecture を OCaml で実践できるようにするため Caelm というライブラリを書いている。俺の野望はまだまだこれからだ (未完) Elm と TEA について Elm というプログラミング言語がある。いわゆる AltJS の一つである。 ミニマリスティクな ML 系の関数言語で、型推論を持ち、型クラスを持たず、例外機構を持たず、変数の再代入を許さず、正格評価され、代数的データ型を持つ。 言語も小綺麗で良いのだが、何より付属のコアライブラリが体現する The Elm Architecture (TEA) が重要である。 TEA は端的に言えば Flux フロントエンド・アーキテクチャの変種である。同じく Flux の派生である Redux の README に TEA の影響を受けたと書いてあるので知っている人もいるだろう。 ビューなどから非同期に送信される Message (Redux だと Action) を受けて状態 (Model; Redux だと State) を更新すると、それに対応して Virtual DOM が再構築されビューがよしなに再描画され人生を書き換える者もいた——という一方向の流れはいずれにせよ同じである。 差異はオブジェクトではなく関数で構成されていることと、アプリケーション外部との入出力は非同期メッセージである Cmd / Sub を返す規約になっていることくらいだろうか。 後者は面白い特徴で、副作用のある処理はアプリケーションの外で起きて結果だけが Message として非同期に飛んでくるので、内部は純粋に保たれる。つまり Elm アプリケーションが相手にしないといけない入力は今現在のアプリケーションの完全な状態である Model と、時系列イベ

多分週刊チラシの裏 (Feb 28, 2021 - Mar 22, 2021)

JavaScript 開発者が如何にして TypeScript 嫌いから TypeScript ファンになったか 気軽な読み物。型宣言の冗長さとジェネリクスなどの複雑性を嫌って (選択肢にあれば) JavaScript の方を選んできた筆者が TypeScript しか選べない職場に移って数ヶ月後にはすっかりファンになっていたという話。 理由は月並で「『不可能な状態を不可能にする』Union Type と網羅性チェック」「コンパイル時型検査によるエラーの早期検出」「リッチな IDE 支援」の 3 本。理由がそれだけなら個人的には Flow か Elm を進めたいところではある。 NASA の最新火星ローバーが搭載するプロセッサは 1998 年の iMac と同じ NASA が Mars 2020 ミッションのために送り出し、先月火星表面に着陸した最新かつ過去最大のローバーである Perseverance の話。 2021 年に活動を開始したこのハイテク・ガジェットのメインプロセッサは PowerPC 750 であるとのこと。1998 年発売の初代 iMac が搭載していた “G3” プロセッサといえば分かり易いだろう。 もちろん民生品そのものではなく、-55 - 125 ℃ の気温と 200,000 - 1,000,000 Rad の放射線に耐える特別仕様の BAE Systems RAD750 である。ちなみに「火星で自撮り」という快挙を成し遂げたのち現在も活動中の先代 Curiosity も同じものを搭載している。動作周波数 110 - 200 MHz、価格は $200,000 程度とのこと。 Internet Archive Infrastructure 過去の Web サイト、書籍、ビデオに音楽からクラシックソフトウェアまでインターネットに公開されたあらゆるデータを収集・保存する Internet Archive のインフラ紹介ビデオ。 クラウドは一切使っておらず、自前のベアメタルサーバ 750 台に接続されたストレージはシステム全体で 200PB とのこと。保存されるデータは現在のところ年 25 % 以上増大しており、四半期で 5 - 6 PB 規模だという。 Semantic Versioning はお前を救わない 「ある API