Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
scheme-small-linter.pdf
Search
Niyarin
April 30, 2020
Programming
570
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
scheme-small-linter.pdf
Niyarin
April 30, 2020
More Decks by Niyarin
See All by Niyarin
Scheme用nREPLの開発(エラー出力の改善)
niyarin
0
180
bel lispの紹介
niyarin
0
790
nanopass-compiler-frameworkを使ってみました
niyarin
0
490
Gorgos-parser-combinator-written-in-scheme
niyarin
0
420
outputting-beautiful-s-expression
niyarin
0
420
Serialisp
niyarin
1
730
Mongo DBとS式検索
niyarin
0
360
goodbye-python-repl
niyarin
0
390
SchemeのEphemeronとWeak Pairの説明
niyarin
0
1.1k
Other Decks in Programming
See All in Programming
気圧・高度・GPSを記録&可視化するアプリ「Koudo」を作った話
hjmkth
1
340
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
640
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
2.8k
ADKを使って簡単にAIエージェントを作ってみよう
k1mu21
0
290
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.8k
キャリア迷子上等 ─ "ない道"は自分で作ればいい
16bitidol
3
2.8k
Even G2とAWSで推しのエージェントを召喚しよう!
har1101
1
140
コンテキストの使い捨てをやめる — ビジネスルール駆動開発と miko —
ioki
0
270
技術記事、 専門家としてのプログラマ、 言語化
mizchi
14
7.3k
これからAgentCoreを触る方へトレンドはGatewayです
har1101
6
470
Strategic Design in the Frontend: Moduliths & Micro Frontends @DDDEurope
manfredsteyer
PRO
0
140
どこまでゆるくて許されるのか
tk3fftk
0
300
Featured
See All Featured
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
460
The #1 spot is gone: here's how to win anyway
tamaranovitovic
3
1.1k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
A Soul's Torment
seathinner
6
3k
Context Engineering - Making Every Token Count
addyosmani
9
1k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Building the Perfect Custom Keyboard
takai
2
810
Mobile First: as difficult as doing things right
swwweet
225
10k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.2k
Become a Pro
speakerdeck
PRO
31
6k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Transcript
Scheme Linterを作る Niyarin
Linter for Scheme ・作法に反するコードを教えてくれるやつ (if (not (some-pred? a)) (write ‘hello))
Linter 「 に変更しよう」 (unless (some-pred? a) (write ‘hello)) → 例 ・(捕捉)Schemeコーディングスタイル派閥 関数定義(define (foo arg) ...) VS (define foo (lambda (arg) …) あとはifを使わずcond+else勢とか ・Schemeは決まったコーディングスタイルは特にないが、 明らかに冗長なものは潰せる 1
Linter実装方針 kibit/kibit/src/kibit/rules/control_structures.clj ・パターンベースのやつ → ユーザがルールを追加しやすい S式言語はこういうの楽で良いね ・ClojureのKibitもそういう方針 core.logicベース 2
作ったもの ・プロトタイプとしてRed-parenという小さいLinterを作った → syntax-rulesライクなルール記述ができる 行数取得とかできるreaderがないので入出力が未完全 ・没案としてmini-kanrenとかの利用も検討していた → Kibitがcore.logic使っているようだったので ・syntax-rulesライクなパターンマッチング(のようなことをする)ライブラリ
・rules (最初に作ったやつ) ・rules+ (記述力が弱かったので↑を拡張した) niyarin/red-paren niyarin/rules 2
最初に作ったライブラリ、Rules ・rulesの例 実質syntax-rulesの関数版のようなもの inputが第一引数にマッチしたなら第二引数に展開される ・schemeでschemeを書く時にsyntax-rulesの実装にも役立つ er-macro/ir-macro(ハイジニックな評価を使うマクロ)があればすぐ実装できる ・あまり強力ではなかった ・型の判定等は苦手 定数(0,#t,#fなど)の判定はできるが、
数値かどうかの判定などはできない ・繰り返し記号の1listに1回だけという制約 (match-expand (when (not pred) body ...) (unless pred body ...) input) 3
rulesの繰り返し記号の制約 ・1つのリストに繰り返し記号2回使うルールが書けない 0を含む+演算 (syntax-rulesでは再帰的にマクロルールを書くことで対処している) ・メリットとしては計算は少なくてすむ ・バックトラックしなくて良い 繰り返し回数が(入力リストの長さ - 非繰り返し記号)で定まる (+
num1 … 0 num2 ...) (a b c … d e)に(1 2 3 4 5 6)を入力した場合、 入力長6からa,b,d,eの4つを引く 4
rulesの実装は必要だったのか ・syntax-rulesのような操作を関数実行時に行う一番楽な方法 ・ほとんど使われないのに必要な時に忘れられるeval ・10行足らずで書けてしまったよ (define (match-expand rule template input) (eval
`(let-syntax ((expand (syntax-rules () ((_ ,rule) (quote ,template)) ((_ _ …) #f)))) (expand ,input)) (environment '(scheme base)))) 5
rules+ (1) 繰り返し数の制限を無くした ・ … 記号は最長マッチの繰り返しとして扱うように変更した ・継続でバックトラックするだけなのでそれほど労力はかからなかった。 6 (or (call/cc
(lambda (break) 繰り返しにもう一回マッチする)) 繰り返しおわり、次に進む) (break #f) マッチ失敗した場合
rules+ (2) 述語埋め込み 述語を埋め込めるようにした 挙動 ・述語に入力を適用して#tならば述語:入力の連想リストで登録される ・複数回使う場合はラップして別ポインタに配置される必要がある 手続きのポインタ配置は仕様の外なので コンパイラの最適化にひっかからないようにする `((assv
(quote ,symbol?) als) (assq (quote ,symbol?) als)) (let ((symbol1? (lambda (x) (and (symbol? x) 1))) (symbol2? (lambda (x) (and (symbol? x) 2)))) `((some-rule ,symbol1? ,symbol2?) (some-template ,symbol1? ,symbol2?))) 7
Red-parenの実行例 ---------- (if (not (and (> x 0) (= (modulo
(+ x y) 2) 0))) (display (car (car y)))) => (unless (and (> x 0) (= (modulo (+ x y) 2) 0)) (display (car (car y)))) ---------- (> x 0) => (positive? x) ---------- (= (modulo (+ x y) 2) 0) => (even? (+ x y)) ---------- (car (car y)) => (caar y) (if (not (and (> x 0) (= (modulo (+ x y) 2) 0))) (display (car (car y)))) > gosh rparen.scm badcode1.scm 結果 入力 8
Red-parenのチェック項目例 ・SRFI/R7RS large用のリストとか append-map、concatenate、remove `((apply append (map f ls ...))
(append-map f ls ...)) ((apply append list-of-list) (concatenate list-of-list)) ((filter (lambda (x) (not (pred x)) body) ls) (remove pred ls))) 9
おわり/あとでやること 今後実装する手続き(ライブラリ) ・行数とか頭の空白情報を保持するreader ・いいかんじに成形するwriter 出力のフィルタリング やってみたいこと ・初心者が書いたSchemeコードを入力してみたい AtcoderとかQiitaに転がってそう 典型的な冗長なコードからチェックパターンを増やせると思う
10