aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile14
-rw-r--r--Makefile28
-rw-r--r--README.md1
-rw-r--r--assets/me.jpegbin0 -> 10890 bytes
-rw-r--r--fizzbuzzz.php86
-rw-r--r--slide.pdfbin0 -> 244957 bytes
-rw-r--r--slide.saty451
8 files changed, 581 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..19780ee
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/slide.satysfi-aux
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..0cbb1ff
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,14 @@
+FROM amutake/satysfi
+
+RUN opam update && \
+ opam install satysfi-base
+
+RUN opam install satysfi-class-slydifi && \
+ opam install satysfi-code-printer && \
+ opam install satysfi-fonts-noto-sans && \
+ opam install satysfi-fonts-noto-sans-cjk-jp
+
+RUN eval $(opam env) && \
+ satyrographos install
+
+WORKDIR /work
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2e45d1a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,28 @@
+.PHONY: all
+all: slide.pdf
+
+slide.pdf: slide.saty
+ docker run \
+ --rm \
+ --name satysfi \
+ --mount type=bind,src=$$(pwd),dst=/work \
+ satysfi \
+ satysfi slide.saty
+
+.PHONY: shell
+shell:
+ docker run \
+ -it \
+ --rm \
+ --name satysfi \
+ --mount type=bind,src=$$(pwd),dst=/work \
+ satysfi \
+ sh
+
+.PHONY: docker
+docker:
+ docker build --tag satysfi .
+
+.PHONY: clean
+clean:
+ rm -f *.pdf *.satysfi-aux
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b378855
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+https://phpstudy.doorkeeper.jp/events/152645
diff --git a/assets/me.jpeg b/assets/me.jpeg
new file mode 100644
index 0000000..4e01020
--- /dev/null
+++ b/assets/me.jpeg
Binary files differ
diff --git a/fizzbuzzz.php b/fizzbuzzz.php
new file mode 100644
index 0000000..7e64904
--- /dev/null
+++ b/fizzbuzzz.php
@@ -0,0 +1,86 @@
+<?
+$a
+=(
+'x
+Om
+'^
+('
+k!
+o'
+))
+(1
+,
+10
+*
+10
+);
+('
+x!
+s!
+k!
+'^
+'k
+Sk
+~}
+Ma
+')
+(
+$a
+,
+fn
+(
+$i
+)
+=>
+('
+x!
+~!
+'^
+'z
+Hd
+G'
+)(
+((
+$i
+%3
+?
+''
+:'
+c!
+'^
+'L
+[p
+')
+.(
+$i
+%5
+?
+''
+:(
+'H
+'^
+('
+')
+).
+('
+b!
+'^
+'i
+S'
+)(
+3*
+3*
+13
+).
+('
+p'
+^
+'p
+')
+)?
+:
+$i
+).
+"
+")
+);
diff --git a/slide.pdf b/slide.pdf
new file mode 100644
index 0000000..0497877
--- /dev/null
+++ b/slide.pdf
Binary files differ
diff --git a/slide.saty b/slide.saty
new file mode 100644
index 0000000..2722ef6
--- /dev/null
+++ b/slide.saty
@@ -0,0 +1,451 @@
+@require: class-slydifi/theme/akasaka
+@require: code-printer/code-design
+@require: code-printer/code-printer
+@require: code-printer/code-syntax
+@require: code-printer/code-theme
+@require: figbox/figbox
+
+let-block +code-block-php source =
+ '<
+ +code-printer?:(
+ CodePrinter.make-config CodeSyntax.php CodeTheme.iceberg-light
+ |> CodePrinter.set-number-fun CodeDesign.number-fun-null
+ )(source);
+ >
+
+let fizzbuzz-normal = `<?php
+
+for ($i = 1; $i <= 100; $i++) {
+ if ($i % 15 === 0) echo 'FizzBuzz', PHP_EOL;
+ else if ($i % 3 === 0) echo 'Fizz', PHP_EOL;
+ else if ($i % 5 === 0) echo 'Buzz', PHP_EOL;
+ else echo $i, PHP_EOL;
+}
+`
+
+let fizzbuzz-0 = `<?php
+for ($i = 1; $i <= 100; $i++) {
+ echo ($i%3?'':'Fizz') . ($i%5?'':'Buzz') ?: $i, "\n";
+}
+`
+
+let fizzbuzz-1 = `<?
+$a = range(1, 100);
+array_walk(
+ $a,
+ fn($i) => printf(
+ (($i%3?'':'Fizz') . ($i%5?'':'Buzz') ?: $i)
+ . "\n"),
+);
+`
+
+let fizzbuzz-2 = `<?
+$r = 'range'; $w = 'array_walk'; $p = 'printf';
+$f = 'Fizz'; $b = 'Buzz';
+$a = $r(1, 10*10);
+$w($a,
+ fn($i) => $p(
+ (($i%3?'':$f) . ($i%5?'':$b) ?: $i) . "
+"));
+`
+
+let string-xor = `<?php
+$a = "12345";
+$b = "world";
+// $a ^ $b は次のコードと同じ
+$result = '';
+for ($i = 0; $i < min(strlen($a), strlen($b)); $i++) {
+ $result .= $a[$i] ^ $b[$i];
+}
+echo $result;
+// => F]AXQ
+
+`#
+
+let string-xor-fizz = `<?php
+$a = "L\n[p";
+$b = "\nc!\n";
+echo $a ^ $b;
+// => Fizz
+
+`#
+
+let string-xor-fizz-2 = `<?php
+echo (
+"L
+[p
+"^
+"
+c!
+"
+);
+// => Fizz
+
+`#
+
+let fizzbuzz-stretched-1 = `<?
+$a
+=(
+'x
+Om
+'^
+('
+k!
+o'
+))
+(1
+,
+10
+`
+
+let fizzbuzz-stretched-2 = `*
+10
+);
+('
+x!
+s!
+k!
+'^
+'k
+Sk
+~}
+Ma
+')
+`
+
+let fizzbuzz-stretched-3 = `(
+$a
+,
+fn
+(
+$i
+)
+=>
+('
+x!
+~!
+'^
+'z
+`
+
+let fizzbuzz-stretched-4 = `Hd
+G'
+)(
+((
+$i
+%3
+?
+''
+:'
+c!
+'^
+'L
+[p
+`
+
+let fizzbuzz-stretched-5 = `')
+.(
+$i
+%5
+?
+''
+:(
+'H
+'^
+('
+')
+).
+('
+`
+
+let fizzbuzz-stretched-6 = `b!
+'^
+'i
+S'
+)(
+3*
+3*
+13
+).
+('
+p'
+^
+'p
+`
+
+let fizzbuzz-stretched-7 = `')
+)?
+:
+$i
+).
+"
+")
+);
+`
+
+open FigBox
+in
+
+document '<
+ +set-config(|
+ SlydifiThemeAkasaka.default-config with
+ color-emph = Color.black;
+ |);
+
+ +make-title(|
+ title = {
+ |明日のあなたの役に立たない
+ |PHPコーディング技法
+ |~細長いFizzBuzzを書く~
+ |};
+ author = {|nsfisis (いまむら)|};
+ date = {|第150回PHP勉強会@東京|};
+ |);
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ +frame{自己紹介}<
+ +fig-center(vconcat [
+ gap 75pt;
+ hconcat [
+ textbox{nsfisis (いまむら)};
+ gap 20pt;
+ include-image 50pt `assets/me.jpeg`;
+ ];
+ gap 20pt;
+ textbox{\@ デジタルサーカス株式会社};
+ ]);
+ >
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ +frame{FizzBuzzとは}<
+ +code-block-php(fizzbuzz-normal);
+ +p{
+ 1から100までの数について、3の倍数ならFizz、5の倍数ならBuzz、15の倍数ならFizzBuzz、それ以外はその数そのものを出力するプログラム
+ }
+ >
+
+ +frame{FizzBuzzとは}<
+ +code-block-php(fizzbuzz-normal);
+ +p{
+ 1行あたりの最大文字数は?
+ }
+ +p{
+ \inline-code(`if`);を並べている行が46文字で最大
+ }
+ >
+
+ +frame{FizzBuzzとは}<
+ +code-block-php(fizzbuzz-normal);
+ +p{
+ 1行あたりの最大文字数は?
+ }
+ +p{
+ \inline-code(`if`);を並べている行が46文字で最大
+ }
+ +p{
+ これを\emph{最小化}したい!
+ }
+ >
+
+ +frame{細長いFizzBuzz}<
+ +fig-center(vconcat [
+ gap 100pt;
+ textbox{1行あたり\emph{2文字}あれば、FizzBuzzが書ける!}
+ ]);
+ >
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ +frame{何が難しいのか?}<
+ +p{
+ 2文字までのトークンしか使えない
+ }
+ +listing{
+ * ほとんどのキーワードが書けない
+ ** \inline-code(`as`);、\inline-code(`do`);、\inline-code(`fn`);、\inline-code(`if`);、\inline-code(`or`);
+ * ほとんどの関数が呼べない
+ ** \inline-code(`_()`); (\inline-code(`gettext()`);の別名)、\inline-code(`pi()`);
+ * 文字列が書けない
+ ** クォート、中身の文字、クォート、で最低3文字必要
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-0);
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-0);
+ +p{
+ ステップ1: 絶対に短縮できない、\emph{キーワード}を排除する
+ }
+ +p{
+ \inline-code(`for`);と\inline-code(`echo`);を消す
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-1);
+ +listing{
+ * \inline-code(`for`);は\inline-code(`array_walk()`);と\inline-code(`range()`);に
+ * \inline-code(`echo`);は\inline-code(`pritnf()`);に
+ * \inline-code(`<?php`);は\inline-code(`<?`);に (要: \inline-code(`short_open_tag`);オプション)
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-1);
+ +p{
+ さっきよりも長くなってない?
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-1);
+ +p{
+ ステップ2: 関数呼び出しをvariable function経由に
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-2);
+ +listing{
+ * 関数名とFizz、Buzzを変数に代入
+ * \inline-code(`100`);を\inline-code(`10*10`);に
+ * \inline-code(`"\n"`);を使わず、直接改行を挿入
+ * 上を無視すれば、2文字以下のトークンだけで構成されている
+ }
+ >
+
+ +frame{FizzBuzzを細長くする}<
+ +code-block-php(fizzbuzz-2);
+ +p{
+ ステップ3: 文字列を幅2文字以下で生成する
+ }
+ >
+
+ +frame{余談: PHP 8 系で動かなくてもいいなら}<
+ +code-block-php(`$f
+=F
+.i
+.z
+.z
+;
+`);
+ +p{
+ 未定義の定数が評価されると、その定数の名前の文字列になる (PHP 7.x 以下)
+ }
+ >
+
+ +frame{余談: PHP 8 系で動かなくてもいいなら}<
+ +code-block-php(`$f
+=@
+F.
+@i
+.
+@z
+.
+@z
+;
+`);
+ +p{
+ 警告を抑制するため、\inline-code(`@`);演算子を使う
+ }
+ >
+
+ +frame{文字列リテラルの短縮}<
+ +code-block-php(string-xor);
+ +p{
+ 文字列の XOR 演算を使う
+ }
+ >
+
+ +frame{文字列リテラルの短縮}<
+ +code-block-php(string-xor-fizz);
+ >
+
+ +frame{文字列リテラルの短縮}<
+ +code-block-php(string-xor-fizz-2);
+ +p{
+ ほとんどの文字列を、1行2文字以下で表せる
+ }
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-1);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-2);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-3);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-4);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-5);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-6);
+ >
+
+ +frame{細長いFizzBuzz完成}<
+ +code-block-php(fizzbuzz-stretched-7);
+ +p{
+ \emph{完成!}
+ }
+ >
+
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+ +frame{そしてその先へ......}<
+ +fig-center(vconcat ?:(align-center) [
+ gap 100pt;
+ textbox{この縛りの下で、どのくらい複雑なプログラムが書けるのか?};
+ ]);
+ >
+
+ +frame{そしてその先へ......}<
+ +fig-center(vconcat ?:(align-center) [
+ gap 100pt;
+ textbox{この縛りの下で、どのくらい複雑なプログラムが書けるのか?};
+ gap 50pt;
+ textbox{任意のプログラムを動かせる!};
+ ]);
+ >
+
+ +frame{そしてその先へ......}<
+ +fig-center(vconcat ?:(align-center) [
+ gap 100pt;
+ textbox{この縛りの下で、どのくらい複雑なプログラムが書けるのか?};
+ gap 50pt;
+ textbox{任意のプログラムを動かせる!};
+ gap 20pt;
+ textbox{\emph{Laravel}を動かせる!};
+ ]);
+ >
+
+ +frame{そしてその先へ......}<
+ +fig-center(vconcat ?:(align-center) [
+ gap 100pt;
+ textbox{任意のプログラムを動かそうとしたときの壁};
+ gap 20pt;
+ textbox{\inline-code(`eval()`);は関数ではない};
+ ]);
+ >
+
+ +frame{おわりに}<
+ +fig-center(vconcat ?:(align-center) [
+ gap 100pt;
+ textbox{続きは\emph{PHPerKaigi 2023}で};
+ ]);
+ >
+>