Mercurial > abomination
changeset 0:1c7ace5054ac
initial commit
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 16 Oct 2011 07:32:21 -0700 |
parents | |
children | a4cb0b71fc78 |
files | .hgignore org/no_parens.org readme.txt |
diffstat | 3 files changed, 107 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Sun Oct 16 07:32:21 2011 -0700 1.3 @@ -0,0 +1,3 @@ 1.4 +syntax: glob 1.5 +src* 1.6 +html* 1.7 \ No newline at end of file
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/org/no_parens.org Sun Oct 16 07:32:21 2011 -0700 2.3 @@ -0,0 +1,102 @@ 2.4 +#+title: Calling it quits without parentheses 2.5 +#+author: Robert McIntyre & Dylan Holmes 2.6 +#+EMAIL: rlm@mit.edu 2.7 +#+MATHJAX: align:"left" mathml:t path:"../MathJax/MathJax.js" 2.8 +#+STYLE: <link rel="stylesheet" type="text/css" href="../css/aurellem.css" /> 2.9 +#+OPTIONS: H:3 num:t toc:t \n:nil @:t ::t |:t ^:t -:t f:t *:t <:t 2.10 +#+SETUPFILE: ../templates/level-0.org 2.11 +#+INCLUDE: ../templates/level-0.org 2.12 + 2.13 +[TABLE-OF-CONTENTS] 2.14 + 2.15 +# * Calling it quits without parentheses 2.16 +Is it possible to make a =quit= command for Clojure such that simply 2.17 +typing the word =quit= at an REPL exits the REPL? An intuitive =quit= 2.18 +command would be especially useful for people new to Lisp syntax or 2.19 +the REPL; the challenge is to make a genuine Clojure command that 2.20 +executes without being called with parentheses. We found three 2.21 +solutions. 2.22 + 2.23 +#+srcname: header 2.24 +#+begin_src clojure :results silent 2.25 +(ns abomination.no-parens 2.26 + (:use clojure.contrib.def)) 2.27 +#+end_src 2.28 + 2.29 +* By modifying =toString= 2.30 +#+srcname: toString 2.31 +#+begin_src clojure 2.32 +(in-ns 'abomination.no-parens) 2.33 +(gen-class :name abomination.no-parens.Quit 2.34 + :prefix quit-) 2.35 + 2.36 +(defn quit-toString 2.37 + [this] 2.38 + (System/exit 0)) 2.39 + 2.40 +(defvar quit (abomination.no-parens.Quit.) 2.41 + "a sneaky way to support a `quit` command") 2.42 +#+end_src 2.43 + 2.44 +When you type any variable at the REPL, the REPL attempts to print it as a nicely-formatted string by calling its =toString= 2.45 +method. Our trick is to define a class with a =toString= method 2.46 +that exits the REPL; this trick ensures that any variable of that class will close 2.47 +the REPL when the REPL attempts to print it. 2.48 + 2.49 +First, we use =gen-class= to make a new class named Quit; in that same line, we use 2.50 +=:prefix= to establish the convention that any function named 2.51 +=quit-[something]= will be adopted as the =[something]= method for the 2.52 +newly-defined Quit class. We use this convention to write our own 2.53 +=toString= method for Quit. 2.54 + 2.55 +Next, we define a suitable =toString= method for the Quit class so that 2.56 +attempting to print an instance of the Quit class has the effect of 2.57 +closing the REPL. We do this by defining a function =quit-toString= 2.58 +which closes the REPL; by the convention established above, the Quit 2.59 +class automatically adopts =quit-toString= as its =toString= method. 2.60 + 2.61 +Finally, we use =defvar= to create an instance of the Quit class; we 2.62 +name this instance =quit=. Now when you type =quit= into the REPL, the 2.63 +REPL executes the =toString= method of the Quit class, exiting the REPL instead of returning a 2.64 +string. 2.65 + 2.66 +#+begin_src clojure :exports both 2.67 +(binding [*compile-path* "/home/r/aurellem/classes"] 2.68 + (compile 'abomination.no-parens)) 2.69 +#+end_src 2.70 + 2.71 +#+results: 2.72 +: abomination.no-parens 2.73 + 2.74 +* By wrapping the command in a lazy sequence 2.75 +#+srcname: lazy-seq 2.76 +#+begin_src clojure :results silent 2.77 +(in-ns 'abomination.no-parens) 2.78 +(defvar quit* (lazy-seq :the-great-bringer-of-death! (System/exit 0)) 2.79 + "the first time it's evaulated it will kill the JVM") 2.80 +#+end_src 2.81 + 2.82 +* By =delay=-ing the command 2.83 +#+srcname: delay 2.84 +#+begin_src clojure :results silent 2.85 +(in-ns 'abomination.no-parens) 2.86 +(defvar quit** (delay (System/exit 0)) 2.87 + "when this is evaulated at the REPL, it will exit the JVM.") 2.88 +#+end_src 2.89 + 2.90 +The same thing, accomplished in a much more elegant and clojureish 2.91 +way. 2.92 + 2.93 +#+begin_src clojure :tangle no_parens.clj :results silent :exports none :noweb yes 2.94 +<<header>> 2.95 +<<toString>> 2.96 +<<lazy-seq>> 2.97 +<<delay>> 2.98 +#+end_src 2.99 + 2.100 +# STUD CRUFT PIZZA 2.101 + 2.102 +#+begin_quote 2.103 +And death i think is no parenthesis 2.104 +\mdash{}E. E. Cummings 2.105 +#+end_quote