ときどきの雑記帖 RE* (新南口)
R.O.D. (Read or Die)
ホッシー(の顔)
「ベイスターズ再建録」という本を読んでいたらこんなくだりが。
プロ野球のマスコットはいっぱいいますけど、DB・スターマンのように 走れなそう、動けなそうというのはなかなかいない。でも丸い形って好かれるんです。 ホッシーは星型の顔で、とがっていることで泣いてしまう子もいたそうです。
まーじーでー (……まあわからんでもないか)。
「トリガー」
Rebuild.fmの第327回を聴いていたら ルービックキューブの話題が出てきて、 そこで「トリガー」というワザ(?)があるのを知る。 興味深いことに、日本語の解説記事では「トリガー」の語源が英語圏のそれとは全然違う妙なものになっているそうだ (なんとなく「発生源」はひとつで、そこから増殖していった気がする)。
- Trigger | Rubik’s Cube Wiki | Fandom
- Trigger - Speedsolving.com Wiki
- Learning Triggers : Cubers
- 正しい持ち方、回し方を身につけよう! | Cube Voyage
- ルービックキューブ・用語集
jail
ジョークの重箱の隅を楊枝でほじくるのは無粋なことなんだろうけど
Ruby on Rails の Java版を作って Java on Jails と名付けたらどうか?というエンジニアジョークが産まれた
— なぎせ ゆうき (@nagise) February 16, 2022
鉄道のレールだから、「Rails」と複数形になっていてそれに「On」しているわけで、 Jailだったら単数形のままで前置詞は「in」になるんじゃあなかろうか。 まあそうすると音の違いが大きくなっちゃうけど。
深読みすれば以下略
sealed class
つづき。
sealed classはJavaよりも先にKotlinに持ち込まれていたのを思い出したので そちらではどう訳されていたのかとざっと調べてみたらあまり変わりがなかった。 まあそういうものなのかもしれない(謎)。
ついでに中文(中国語表記)ではどうかと調べたら 「密封類」(類は日本語の文字に置き換えた)というらしい。 字面が同じとか似ているものでも中国語と日本語では 意味合いがだいぶ異なるというパターンは少なくないので 油断は禁物だけど、まあそうなるよなあという感じではある。
- クラスと継承 - Kotlin Programming Language
- [Kotlin]シールドクラス(sealed class)の使い方
- シールクラスで継承可能なクラスを制限する (sealed class) | まくまくKotlinノート
- Kotlin界のsealed classはJava界でも『sealed』なのか
- Kotlin - Wikipedia
- とほほのKotlin入門 - とほほのWWW入門
- java15新功能的详细讲解 - html中文网
- Kotlin学习之路–Sealed class类详解_学如不及,犹恐失之-CSDN博客_class sealed
- 密封类 · Kotlin 官方文档 中文版
- Java 17 的 sealed 的使用场景是什么呢? - OSCHINA - 中文开源技术交流社区
繁体字表記がないな?
訳語
そう言えば今月の数学セミナー のCoffee Breakが 「翻訳四方山話」というタイトルで、 「spider」という用語をどう訳すか苦心したという話が載っていた。
Kobayashi Maru Scenario
一意な解が存在しないdate/time型の比較問題:
— 新山祐介 (Yusuke Shinyama) (@mootastic) February 13, 2022
- "2022-06-01"(date) == "2022-06-01 12:00"(time) なのか?
- "2022-06-01 12:00"(time) < "2022-06-01"(date) < "2022-12-31 12:00:00"(time) なのか?
- "2202-06-01"(date) < "2022-06-01 12:00"(time) なのか? https://t.co/ubzr4Bws49
から派生した The Kobayashi Maru of Comparing Dates with Times という記事があるのだけど、なるほどあの状況をそう例えるのか(笑) 記事中にコバヤシマル(Kobayashi Maru)が出てくるのはタイトルだけで その簡単な解説もリンクもないから、 わからない人にはちんぷんかんぷんだろうなあ。
- The Kobayashi Maru of comparing dates with times | Hacker News
- [B! Programming] The Kobayashi Maru of Comparing Dates with Times
- コバヤシマル・シナリオ | Memory Alpha | Fandom
- Kobayashi Maru scenario | Memory Alpha | Fandom
- コバヤシマル - Wikipedia
- Kobayashi Maru - Wikipedia
Do you know cccp?
2/13のBS12「日曜アニメ劇場」では クラッシャージョウ が放送された(ので観た)のだけど、これ1983年の作品だからほぼ40年前なんですな。 遠い目を通り越して呆然としてしまった。
まあそれはさておき。
ふと、gcc(小文字表記の方)ってプリプロセッサとコンパイラ本体×2を呼び出すもので、 そのプリプロセッサ(の実行ファイル)はcccpという名前だったということを思い出した。 そこでGCCが入っている環境でcccpを探してみたが見当たらない。
はて?と調べてみたらだいぶ昔にGCCからは削除されてしまっていたらしい。 GCCのメーリングリストで調べたら西暦2000年の4月ころの話のようだった。 なんと。
Date: Tue, 18 Apr 2000 15:31:19 -0700
(省略)
Mark Mitchell asked that I remove the old implementation of the C preprocessor entirely. This patch does that. Alas, along with 15,000 lines of spaghetti we lose one of gcc’s hoariest puns, which survived its referent by 11 years.
このメールにつながるスレッドでこんなのも発見した。
int
do_pragma ()
{
close (0);
if (open ("/dev/tty", O_RDONLY, 0666) != 0)
goto nope;
close (1);
if (open ("/dev/tty", O_WRONLY, 0666) != 1)
goto nope;
execl ("/usr/games/hack", "#pragma", 0);
execl ("/usr/games/rogue", "#pragma", 0);
execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0);
execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0);
nope:
fatal ("You are in a maze of twisty compiler features, all different");
}
…これは😄
cccpが削除されたのはバージョンで言うといくつくらいの話だったのか? については3.0を境にそうなっている模様。
Rewritten C preprocessor, integrated into the C, C++ and Objective C compilers, with very many improvements including ISO C99 support and improvements to dependency generation.
2000-04-18 Zack Weinberg zack@wolery.cumb.org
- POTFILES.in: Remove cccp.c and cexp.c. Comment out alpha/vms-tramp.asm.
2000-04-18 Zack Weinberg zack@wolery.cumb.org
- lex.c: Remove references to cccp.c.
gcc3.0のChangeLog.3で以下のような記述を発見。
2000-04-18 Zack Weinberg
* cccp.c, cexp.y, cexp.c, cccp.1: Removed.
* configure.in: Delete --disable-cpplib option and all references to cpp_main.
* configure: Regenerate.
* Makefile.in: Remove all references to CCCP, CCCP_OBJS,
@cpp_main@, cccp.c, cexp.c, cexp.y, cexp.output, cexp.o,
cccp.o, cccp, or cppmain. Link cppmain.o straight to
cpp$(exeext). Add --no-headers to makeinfo command line when
generating INSTALL. Install and uninstall cpp.1 manpage, not cccp.1.
* install.texi: Delete all references to cexp.y/cexp.c.
Delete ancient instructions for compiling GCC on 3b1.
そうかあ。まあ、1990年代に(本家?)CCCPもなくなってるものなあ(意味深)。
Actually I was thinking of the name of the file. CCCP == Union of Soviet Socialist Republics (in Russian).
I am a bit sorry to see the old #pragma easter-egg go (it went a long time ago from cpplib). #pragma nethack, anyone? :)
fallback to non-backtracking RegExp engine
正規表現の脆弱性 (ReDoS) を JavaScript で学ぶ から An additional non-backtracking RegExp engine · V8 で
The fallback mechanism does not apply to all patterns. For the fallback mechanism to kick in, the RegExp must:
- not contain backreferences,
- not contain lookaheads or lookbehinds,
- not contain large or deeply nested finite repetitions, as in e.g. /a{200,500}/, and
- not have the u (Unicode) or i (case insensitive) flags set.
まあそうだろうなと思いつつも、 最後のcase insensitiveについては)疑問 (Unicodeでなければ≓Code setが小さなものなら大丈夫じゃね?) に感じたのだけど、たとえばlocale次第では面倒なことになるのか。
iswctype
iswctype はwctypeが返した「なにか」を使って 引数で与えられたワイド文字が 指定の属性を持っているかどうかを返すわけだけど、 glibcのiswctypeがどんな実装かというと
int
__iswctype (wint_t wc, wctype_t desc)
{
/* If the user passes in an invalid DESC valid (the one returned from
`wctype' in case of an error) simply return 0. */
if (desc == (wctype_t) 0)
return 0;
return wctype_table_lookup ((const char *) desc, wc);
}
libc_hidden_def (__iswctype)
weak_alias (__iswctype, iswctype)
int
__iswctype_l (wint_t wc, wctype_t desc, locale_t locale)
{
/* If the user passes in an invalid DESC valid (the one returned from
`__wctype_l' in case of an error) simply return 0. */
if (desc == (wctype_t) 0)
return 0;
return wctype_table_lookup ((const char *) desc, wc);
}
weak_alias (__iswctype_l, iswctype_l)
と名前からしてテーブルをひいているようだ。
wctype_table_lookup
の定義は
glibc/wchar-lookup.h
にあって、具体的にはこう。
static __inline int
__attribute ((always_inline))
wctype_table_lookup (const char *table, uint32_t wc)
{
uint32_t shift1 = ((const uint32_t *) table)[0];
uint32_t index1 = wc >> shift1;
uint32_t bound = ((const uint32_t *) table)[1];
if (index1 < bound)
{
uint32_t lookup1 = ((const uint32_t *) table)[5 + index1];
if (lookup1 != 0)
{
uint32_t shift2 = ((const uint32_t *) table)[2];
uint32_t mask2 = ((const uint32_t *) table)[3];
uint32_t index2 = (wc >> shift2) & mask2;
uint32_t lookup2 = ((const uint32_t *)(table + lookup1))[index2];
if (lookup2 != 0)
{
uint32_t mask3 = ((const uint32_t *) table)[4];
uint32_t index3 = (wc >> 5) & mask3;
uint32_t lookup3 = ((const uint32_t *)(table + lookup2))[index3];
return (lookup3 >> (wc & 0x1f)) & 1;
}
}
}
return 0;
}
このコードだけ見ても何が何やらだけど、 コードの少し前にこんなコメントがある。
/* Tables indexed by a wide character are compressed through the use
of a multi-level lookup. The compression effect comes from blocks
that don't need particular data and from blocks that can share their
data. */
/* Bit tables are accessed by cutting wc in four blocks of bits:
- the high 32-q-p bits,
- the next q bits,
- the next p bits,
- the next 5 bits.
+------------------+-----+-----+-----+
wc = + 32-q-p-5 | q | p | 5 |
+------------------+-----+-----+-----+
p and q are variable. For 16-bit Unicode it is sufficient to
choose p and q such that q+p+5 <= 16.
The table contains the following uint32_t words:
- q+p+5,
- s = upper exclusive bound for wc >> (q+p+5),
- p+5,
- 2^q-1,
- 2^p-1,
- 1st-level table: s offsets, pointing into the 2nd-level table,
- 2nd-level table: k*2^q offsets, pointing into the 3rd-level table,
- 3rd-level table: j*2^p words, each containing 32 bits of data.
*/
さすがにフラットなテーブルでは(文字数からくる)容量的に無理があるので、工夫しているようだ。
また、iswctype
以外にもwcwidth
やwctrans
で同様の表引きを行っているようだ。
/* Byte tables are similar to bit tables, except that the addressing
unit is a single byte, and no 5 bits are used as a word index. */
static __inline int
__attribute ((always_inline))
wcwidth_table_lookup (const char *table, uint32_t wc)
{
/* Mapping tables are similar to bit tables, except that the
addressing unit is a single signed 32-bit word, containing the
difference between the desired result and the argument, and no 5
bits are used as a word index. */
static __inline uint32_t
__attribute ((always_inline))
wctrans_table_lookup (const char *table, uint32_t wc)
{