Make a Lisp 㧠Lisp å¦çç³»ãå¦ãã§ã¤ãã (with Crystal)
ã¤ã³ã¿ããªã¿å¼ã®è¨èªå¦çç³»ãæ¸ãããã¨ãç¡ãã£ãã®ã§ä¸åº¦å®è£ ãã¦ã¿ããã¨æã£ã¦ï¼ãã®æã®ã¯ Lisp ãå®çªã ã¨ãããã¨ã§ï¼åã ããæ°ã«ãªã£ã¦ãã Make a Lisp (mal) ã«ææ¦ãã¦ã¿ã¾ããï¼
Make a Lisp (mal) ã¨ã¯
Make a Lisp ã¯è²ã ãªè¨èªã§ mal ã¨ãã Lisp æ¹è¨ãå®è£ ãã¦ã¿ããã¨ããããã¸ã§ã¯ãã§ãï¼
- 30以ä¸ã®è¨èªã§ã® mal å¦çç³»å®è£
- 11段éã®ã¹ãããã«åããããå®è£ ã¬ã¤ãï¼å ¨ä½ã®æ§æå³ä»ãï¼
- åå®è£ ã¹ããããã¨ã®ãã¹ãã±ã¼ã¹
ã¨ãã£ãã»ããæ å ±ãæã£ã¦ããï¼è¨èªå¦çç³»åå¿è ã§ã Lisp å®è£ ã«ã¤ãã¦ç°¡åã«å¦ã¹ãç°å¢ãæ´ã£ã¦ãã¾ãï¼ 11段éã®åã¹ãããã¯ä»¥ä¸ã®æ§ãªæãã§ãï¼
- The REPL : å®è£
ãå§ããæºåï¼èªåã®è¨èªã Makefile ã«ç»é²ãã¦
make
ä¸çºã§ãã¹ããèµ°ãããããããã«ããï¼é¢æ°ã®ã¹ã±ã«ãã³ã®ä½æï¼ - Read and Print : REPL (read-eval-print loop) ã® read ããã³ print é¨åã®åºæ¬çãªå®è£ ï¼Lisp ã®å¤ãæ ¼ç´ãããã¼ã¿æ§é ãã¤ãã
- Eval : è©ä¾¡å¨ï¼ã·ã³ãã«ã»ãªã¹ãã»ãã¯ã¿ã»ãããã®åºæ¬çãªãã¼ã¿æ§é ãçæããé¢æ°ããã³ååæ¼ç®ãè¡ãé¢æ°ãã¤ãã
- Environments : "ç°å¢"ãå®è£ ããï¼Lisp ã®å¤ã«ååãä»ããã¨ç°å¢ã¨å¼ã°ãããã¼ãã«ã«ååã¨å¤ã®çµã§ä¿åãããï¼ä¾ãã°å¤æ°å®ç¾©ãªã©ï¼
- If Fn Do : å¶å¾¡æ§é é¢é£ã®é¢æ°
if
,fn
,do
ãå®è£ ããï¼ããããæ¡ä»¶åå²ï¼é¢æ°å®ç¾©ï¼é次å®è¡ãè¡ããããã«ãªã - Tail call optimization : ããããæ«å°¾å帰å¼ã³åºãæé©åãå®è£ ããï¼ãªãæ«å°¾ã«ããå帰å¼ã³åºããã«ã¼ãã«å¤æã§ããã®ãåãã
- Files and Evil : ãã¡ã¤ã«èªã¿åºãç¨ã®é¢æ°ã¨ eval() é¢æ°ãå®è£ ããï¼ä¸»ã«å¾ã§åºã¦ããã»ã«ããã¹ãã®ããï¼
- Quoting : Lisp ã®ã¯ã©ã¼ããå®è£ ããï¼ããã«ããï¼èªèº«ã®æ½è±¡æ§ææ¨ããã¼ã¿æ§é ã¨ãã¦ç´æ¥æ±ããã¨ãã§ããããã«ãªãï¼
- Macros : Lisp ã®ãã¯ããå®è£
ããï¼å®ç¾©ããããã¯ã㯠eval ã«ããè©ä¾¡å®è¡åã«å±éãããã®ã§ï¼ããã§èªèº«ã®æ§æãæ¡å¼µãããã¨ãã§ããï¼è©¦ãã«
if
ãå ã«unless
ãã¤ãã£ã¦ã¿ããããï¼ - Try : ä¾å¤å¦çæ©æ§ãã¤ããï¼ãããã
try-catch
ã§ï¼ã·ã³ã¿ãã¯ã¹ã¨ã©ã¼ãªã©ãããã§æ¾ããããã«ããï¼ - Mutation, Self-hosting and Interop : å¤ã«ã¡ã¿æ å ±ãæããããã¨ãã§ããããã«ããï¼ã¾ãï¼å¤æ´å¯è½(mutable)ãªå¤ã¨ã㦠atom ã¨ãããã¼ã¿å㨠atom ãæä½ããæ¨æºé¢æ°ãããã¤ãå®è£ ããï¼ãã§ã«ãã mal ã«ãã mal å®è£ ã使ã£ã¦ï¼èªåã§ä½ã£ãå¦çç³»ããã¼ãã¹ãã©ããã¨ã㦠mal ãã»ã«ããã¹ãããï¼ï¼èªåã§ã¤ãã£ã mal å¦çç³»ã§å®è¡ãã mal å¦çç³»ã step0 ã stepA ã®ãã¹ã¦ã®ãã¹ããéãï¼
ã¡ããã© Crystal ã¨ããè¨èªã以åããæ°ã«ãªã£ã¦ããã®ã§ï¼ãã£ãããªã®ã§ Crystal ã§å®è£ ãããã¨ã«ãã¾ããï¼
Crystal
Crystal 㯠Ruby ã®ææ³ããã¼ã¹ã«ããéçåä»ãè¨èªã§ãï¼ãªã®ã§ååãå®ç³ããåã£ã¦ãã¾ãï¼ï¼è¦ããã¯ããªã Ruby ã«è¿ãã§ããï¼ã³ã³ãã¤ã©ãåãã§ãã¯ãè¡ãåãåããªãå ´åã¯ã³ã³ãã¤ã«ã¨ã©ã¼ã«è½ã¨ãã¦ããã¾ããï¼ãã¤ããªã®å®è¡ãããªãéãã§ãï¼å ã åçåä»ãè¨èªã® Ruby ãéçåä»ãè¨èªã«æã£ã¦ããããã«è²ã ãªå·¥å¤«ããã¦ãã¾ãï¼
arr = [1, 2, 3, "foo"]
ä¾ãã°ä¸ã®ãã㪠Array
ã®è¦ç´ ã®å㯠Crystal ã§ã¯ Int32 | String
ã¨ãã Union type ã«ãªãã¾ãï¼
Union type ã¯å®éã«ã©ã®åãå
¥ã£ã¦ãããã確èªããå¾ã§ãªãã¨ä½¿ãã¾ããï¼
elem = arr.sample # ã©ã³ãã ã«1ã¤åãåºã elem + 10 # ã¨ã©ã¼ï¼ String + Int32 ã¯å®ç¾©ããã¦ããªã puts elem.to_s # elem ã Int32 ã§ã String ã§ã to_s ã¡ã½ããã¯ä½¿ããã®ã§ OK case elem when Int32 elem + 10 # Int32 ã¨ãã¦æ±ãã when String elem + "!" # String ã¨ãã¦æ±ãã end
ãã®ä»ã®æ§ã ãªç®æã§ãã³ã³ãã¤ã©ãåæ å ±ãããéãã¦ãã¦ï¼åãå¾ãåããã¹ã¦åããã Union type ã¨ãã¦æ¨è«ãã¾ãï¼ãã£ã¦ï¼Crystal ã§ã¯ããä¸é¨ã®ä¾å¤ãé¤ãã¦ã»ã¨ãã©åãæ¸ãå¿ è¦ãããã¾ããï¼åãæ¸ããªãã®ãè¯ããã©ããã¯å¥ã®åé¡ã§ããï¼ï¼
ãã ï¼ç°ãªãç¹ãããªãããã®ã§ï¼Ruby ã ã¨æã£ã¦æ¸ãã¨ãã¾ããããªããã¨ãããã¾ãï¼
- ããã©ã«ãã nilable ã§ãªãï¼å
T
ã®å¤æ°ã«nil
ãå ¥ããããã°T | Nil
åã使ãï¼ String
ãå¤æ´ä¸å¯è½- eval ãç¡ã
eval ãç¡ãã¨ããã®ã¯ï¼Ruby ã«æ¯ã¹ã¦ï¼ããªãèªç±åº¦ãä½ããªãããã«è¦ãã¾ããï¼Crystal ã«ã¯ãã¯ããããããã³ã³ãã¤ã«æã«ã¡ã½ãããå®ç¾©ããã Ruby ã® method_missing
ã¿ãããªå¦çãã³ã³ãã¤ã«æã§ããã°å¯è½ã§ãï¼ã¾ãï¼ãããã°ã«ä¾¿å©ãª p
ã¡ã½ãããªã©ããã¯ãã§å®è£
ããã¦ãã¾ãï¼
ãã ï¼ã¾ã pre-alpha ã¹ãã¼ã¸ã§ç¾å¨é²è¡å½¢ã§éçºä¸ã®ããï¼ã³ã³ãã¤ã©ã®ãã°ããã£ããï¼ä»æ§å¤æ´ããã£ãããã¾ãï¼ã©ããããéçºä¸ãã¨ããã¨ï¼Crystal 㧠mal ãå®è£ ãã¦ããã¨ã¡ã¤ã³éçºè ã® Ary ãããã«ã¸ã¥ã¢ã«ã« commit ã³ã¡ã³ãã§ãCrystal ã®ä½¿ç¨æã©ãï¼ãã¨èãã¦ãããããã§ãï¼ãªãï¼ãã§ã«ã»ã«ããã¹ãæ¸ã¿ã§ï¼Crystal ã®ã³ã³ãã¤ã©ã¯ Crystal ã§æ¸ããã¦ãã¾ãï¼
Crystal ã«ãã Lisp (mal) å®è£
Crystal ã¯ä»¥åããã¡ãã£ã¨æ°ã«ãªã£ã¦ããã®ã§ï¼Make a Lisp 㯠Crystal ã§å®è£ ãã¾ããï¼
Lisp ã®å¤ã®ãã¼ã¿æ§é 㯠Union type ã使ã£ã¦ç°¡æ½ã«æ¸ããã¨ãã§ãï¼ä»ã®ç®æãï¼Ruby ã§ãã Proc
ã¯è¥å¹²æ²è
ã§ãããï¼ããã£ã¨æ¸ããã¨ãã§ãã¾ããï¼ï¼ãã¡ããæãç®æããããããã£ããï¼ã³ã³ãã¤ã©ã®ãã°ãåé¿ããããã«ã¯ã¼ã¯ã¢ã©ã¦ã³ãããç®æãããã¾ããâ¦ï¼
ã¬ã¤ã ã¯è¥å¹²æ å ±ã足ãã¦ããªãï¼çµã¿è¾¼ã¿é¢æ°ã®ä»æ§ã¨ãï¼ãã¨ããã£ããè¥å¹²å 容ãé£ãããã¨ãããã¾ããï¼ããããã¨ãã¯ä»ã®è¨èªã§ã®å®è£ ã失æãããã¹ãã±ã¼ã¹ã確èªãããã¨ã§ç解ãããã¨ãã§ãã¾ãï¼èªç¶è¨èªã§èª¬æããããããå®éã®ã³ã¼ãã§è¦ãã»ããåããããããã¨ãå¤ãã§ãï¼ã¾ãï¼ä»ã®ç¥ããªãè¨èªã§ã®å®è£ ãè¦ãªããå®è£ ãé²ããã®ã楽ããã§ãï¼
åã®å ´å㯠Nim ã§ã®å®è£ ãèªã¿ãªããåèã«ãããï¼ã©ããã¦ãåãããªãç®æã¯ããç¥ã£ã¦ãã Ruby ã§ã®å®è£ ãèªãã§ç解ããããã¾ããï¼
æå¾ã®ã¹ãããã¾ã§å®è£ ããã£ãæã®å®è£ éã¯å ¨ä½ã§ 2500 è¡ãããã§ï¼åã¹ãããã§ãã¡ã¤ã«ãåã£ã¦ããã®ã§ï¼å®éã®å®è£ 㯠1000 è¡ç¨åº¦ã§ãï¼é£æ度çã«ã¯æå¾ã®ã»ã«ããã¹ãæã«ã»ã«ããã¹ãããå´ã§ãã°ãè¦ã¤ããã¨ç¹å®ãå°ã大å¤ã§ããï¼ãã以å¤ã¯ã»ã¼è¦æ¦ãã¾ããã§ããï¼ãªãï¼ã³ããããã°ãè¦ã¦ããã¨ï¼éã人ã ã¨3æ¥ã»ã©ã§å®è£ ãã¦ããããã§ãï¼e.g. Nimï¼ï¼1æ¥1æé1ã¹ããããã¤å®è£ ãã¦ããã¨ããã®ãè¯ãããã§ãï¼
Crystal ã§å®è£ ããä¸ã§è¦ã¤ããã³ã³ãã¤ã©ã®ãã°ã¯ Crystal ã®ãªãã¸ããªã® issue ã«å ±åãããï¼æ°ã¥ããç®æãä¿®æ£ã㦠pull request ãããã§ããããè²¢ç®ãããã¨ãã§ãã¾ããï¼ã¾ãï¼Crystal ã§ã® mal å®è£ ã¯ã¾ã ãªãï¼ãã£ãããªã®ã§ mal ã« pull request ãåºãã¦åãè¾¼ãã§ãããã¾ããï¼
@Linda_pp has implemented mal in Crystal: https://t.co/2aEobB0itY Implementation count now stands at 35! #lisp #clojure
— Joel Martin (@bus_kanaka) June 4, 2015
ã¾ãï¼ãã£ãããªã®ã§ä»å¾ãã¡ããã¡ããããã£ã¦ããããã¨æãåç¬ã®ãªãã¸ããªåãã¾ããï¼
https://github.com/rhysd/Crisp
ã¾ã¨ã
åºæ¬çãªã¤ã³ã¿ããªã¿åã®åçåä»ãã®è¨èªå¦çç³»ã®ä¸èº«ãã©ããªã£ã¦ããã®ãåå¼·ã«ãªãã¾ãããï¼Lisp ã®å¼·åãã¤åçãªæ©è½ã§è²ã éã¶ãã¨ãã§ãã¾ããï¼ Lisp ã¯ããããã©ãããè¨èªããããç¥ããªãã£ãã®ã§ããï¼ãã¹ãã±ã¼ã¹ãå å®ãã¦ãããä»ã®è¨èªã§ã®å®è£ ããã£ãã®ã§ãªãã»ã©ãªãã¨ããæãã§é²ãããã¾ããï¼
ã¾ã mal ã®ãªãã¸ããªã«ç¡ãè¨èªã§å®è£ ããã¨èªåã®å®è£ ãåãå ¥ãã¦ãããã¦ã©ãã¨ãªããå¾æãããã¾ãï¼ä¾ãã°Dè¨èªã¨ãï¼æè¿è©±é¡(?)ã® Elixir ã¨ã Vim script ã¨ãï¼ã¾ã mal å®è£ ãç¡ãããã§ãï¼
ãã ï¼Lisp ï¼ã®ãã¡æ¹è¨ï¼ã®å¦çç³»ãå®è£ ãã¦ã¿ã¾ãããã®ã®ï¼ç¸å¤ãããä½æ ã Lisp èªä½ã¯æ¸ããæ°ããã¾ããâ¦