* bug#13126: 24.3.50; (WISH) Document pcase in Info manual @ 2012-12-09 9:28 Jambunathan K 2012-12-09 17:12 ` Stefan Monnier 0 siblings, 1 reply; 6+ messages in thread From: Jambunathan K @ 2012-12-09 9:28 UTC (permalink / raw) To: 13126 24.3.50; Document pcase in Info manual Having easy to use examples would be nice. ,---- | pcase is an autoloaded Lisp macro in `pcase.el'. | | (pcase EXP &rest CASES) | | Perform ML-style pattern matching on EXP. | CASES is a list of elements of the form (UPATTERN CODE...). `---- In GNU Emacs 24.3.50.12 (i686-pc-linux-gnu, X toolkit, Xaw3d scroll bars) of 2012-12-09 on debian-6.05 Bzr revision: 111153 kjambunathan@gmail.com-20121208130646-kfndebrxbw82i48h Windowing system distributor `The X.Org Foundation', version 11.0.10707000 Important settings: value of $LANG: en_IN locale-coding-system: iso-latin-1-unix default enable-multibyte-characters: t ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13126: 24.3.50; (WISH) Document pcase in Info manual 2012-12-09 9:28 bug#13126: 24.3.50; (WISH) Document pcase in Info manual Jambunathan K @ 2012-12-09 17:12 ` Stefan Monnier 2012-12-11 10:20 ` Jambunathan K 0 siblings, 1 reply; 6+ messages in thread From: Stefan Monnier @ 2012-12-09 17:12 UTC (permalink / raw) To: Jambunathan K; +Cc: 13126 > 24.3.50; Document pcase in Info manual I just installed a doc for it in the `emacs-24' branch. Please take a look at it, Stefan ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13126: 24.3.50; (WISH) Document pcase in Info manual 2012-12-09 17:12 ` Stefan Monnier @ 2012-12-11 10:20 ` Jambunathan K 2012-12-11 13:55 ` Stefan Monnier 0 siblings, 1 reply; 6+ messages in thread From: Jambunathan K @ 2012-12-11 10:20 UTC (permalink / raw) To: Stefan Monnier; +Cc: 13126 >> 24.3.50; Document pcase in Info manual > > I just installed a doc for it in the `emacs-24' branch. Please take > a look at it, Thanks. `pcase' seemed a good replacement for `case'. Quick feedback. 1. pcase-let, pcase-let*, pcase-dolist (maybe) 2. It took some effort to understand that there is a U-PATTERN and a UPATTERN. We don't read out `*-*', do we? ,---- | There are two kinds of patterns involved in `pcase', called | _U-patterns_ and _Q-patterns_. The UPATTERN mentioned above are | U-patterns and can take the following forms: `---- 3. Let's take the example of how ,---- | (defun evaluate (exp env) | (pcase exp | ,---- | | (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) | `---- | (`(call ,fun ,arg) (funcall (evaluate fun) (evaluate arg env))) | (`(fn ,arg ,body) (lambda (val) | (evaluate body (cons (cons arg val) env)))) | ((pred numberp) exp) | ((pred symbolp) (cdr (assq exp env))) | (_ (error "Unknown expression %S" exp)))) `---- `(add ,x ,y) ` QPATTERN ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13126: 24.3.50; (WISH) Document pcase in Info manual 2012-12-11 10:20 ` Jambunathan K @ 2012-12-11 13:55 ` Stefan Monnier 2012-12-13 15:01 ` Jambunathan K 0 siblings, 1 reply; 6+ messages in thread From: Stefan Monnier @ 2012-12-11 13:55 UTC (permalink / raw) To: Jambunathan K; +Cc: 13126 > Thanks. `pcase' seemed a good replacement for `case'. While it's not a plug-in replacement, it provides a superset of the features of case, yes. > 1. pcase-let, pcase-let*, pcase-dolist (maybe) pcase-dolist shouldn't be documented (yet?). Maybe pcase-let and pcase-let* should be there, indeed. > 2. It took some effort to understand that there is a U-PATTERN and a > UPATTERN. We don't read out `*-*', do we? > ,---- > | There are two kinds of patterns involved in `pcase', called > | _U-patterns_ and _Q-patterns_. The UPATTERN mentioned above are > | U-patterns and can take the following forms: > `---- What do you suggest instead? > 3. Let's take the example of how > ,---- > | (defun evaluate (exp env) > | (pcase exp > | ,---- > | | (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) > | `---- > | (`(call ,fun ,arg) (funcall (evaluate fun) (evaluate arg env))) > | (`(fn ,arg ,body) (lambda (val) > | (evaluate body (cons (cons arg val) env)))) > | ((pred numberp) exp) > | ((pred symbolp) (cdr (assq exp env))) > | (_ (error "Unknown expression %S" exp)))) > `---- > `(add ,x ,y) > ` QPATTERN I don't know what you wanted to say here. Stefan ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13126: 24.3.50; (WISH) Document pcase in Info manual 2012-12-11 13:55 ` Stefan Monnier @ 2012-12-13 15:01 ` Jambunathan K 2012-12-13 17:37 ` Stefan Monnier 0 siblings, 1 reply; 6+ messages in thread From: Jambunathan K @ 2012-12-13 15:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: 13126 Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Thanks. `pcase' seemed a good replacement for `case'. > > While it's not a plug-in replacement, it provides a superset of the > features of case, yes. pcase also reminds me of CL's case. Btw, you know in what version of Emacs did pcase made it's appearance. >> 1. pcase-let, pcase-let*, pcase-dolist (maybe) > > pcase-dolist shouldn't be documented (yet?). Maybe pcase-let and > pcase-let* should be there, indeed. > pcase-let reminds me of `destructuring-bind'. Here is a real-life example of pcase-let in action from midnight.el. Good for instructive purposes. (defun midnight-next () "Return the number of seconds till the next midnight." (pcase-let ((`(,sec ,min ,hrs) (decode-time))) (- (* 24 60 60) (* 60 60 hrs) (* 60 min) sec))) >> 2. It took some effort to understand that there is a U-PATTERN and a >> UPATTERN. We don't read out `*-*', do we? >> ,---- >> | There are two kinds of patterns involved in `pcase', called >> | _U-patterns_ and _Q-patterns_. The UPATTERN mentioned above are >> | U-patterns and can take the following forms: >> `---- Provide a BNF and document TERMINALS before NON-TERMINALS. (Currently it seems other way round). Docstring for pcase has more info (pred FUNCTION) apropos the arguments passed to it. Possibly there are other things... > What do you suggest instead? Here is my recommendation. May be replace the example snippets with a /simple/ and /cohesive/ example. I found Snippet 2 "too abstract" and leaves a lot to the imagination of the reader. I just hacked a working REPL based on pcase. See below. We can include these after `repl' will act as a good replacement for Snippet 1. `repl-eval' will act as a good replacement for Snippet 2. M-x repl RET for a reader to toy with. ,---- Snippet 1 | (pcase (get-return-code x) | (`success (message "Done!")) | (`would-block (message "Sorry, can't do it now")) | (`read-only (message "The shmliblick is read-only")) | (`access-denied (message "You do not have the needed rights")) | (code (message "Unknown return code %S" code))) `---- ,---- Snippet 2 | (defun evaluate (exp env) | (pcase exp | (`(add ,x ,y) (+ (evaluate x env) (evaluate y env))) | (`(call ,fun ,arg) (funcall (evaluate fun) (evaluate arg env))) | (`(fn ,arg ,body) (lambda (val) | (evaluate body (cons (cons arg val) env)))) | ((pred numberp) exp) | ((pred symbolp) (cdr (assq exp env))) | (_ (error "Unknown expression %S" exp)))) `---- (let ((repl-dictionary '())) (repl-eval '((x = "happy") (y = "HACKING") (n = 2013) (z = (upcase-initials x + space + (downcase y) + tab + 2013))))) (defvar repl-dictionary '() "Symbol table for `repl'.") (defun repl-eval (exp) (pcase exp ;; In-built constants. (`space " ") (`tab "\t") ;; Add operator. Concatenate. (`(,x + . ,y) (concat (repl-eval x ) (repl-eval y))) ;; Assignment operator. Update dictionary. (`(,x = . ,body) (let* ((value (repl-eval body)) (entry (assoc x repl-dictionary))) (if (not entry) ;; Add variable & value. (push (cons x value) repl-dictionary) ;; Update value. (setcdr entry value)) value)) ;; Function. Assume it takes a string as it's only arg. Call it. (`(,(and (pred functionp) f) . ,x) (funcall f (repl-eval x))) ;; Last of body forms. Return it's value. (`(,x . nil) (repl-eval x)) ;; Body forms. Evaluate in sequence. Return value of last of ;; the forms. (`(,x . ,y) (repl-eval x) (repl-eval y)) ;; String, just return it. ((pred stringp) exp) ;; Number, cast it to string. ((pred numberp) (number-to-string exp)) ;; Symbol, lookup it's value in dictionary. ((pred symbolp) (or (cdr (assoc exp repl-dictionary)) (error "Variable `%s' not bound" exp))) (_ (error "Unknown expression %S" exp)))) (defun repl () "Simple REPL for string operations. Expression syntax: In-built Constants : space : tab Assignment : x = \"hello\" : y = \"world\" Casting : n = 2012 Concatenation : x + space + y + space + n Unary functions : (upcase-initials x) Commands: exit => Quit clear => Unbind all variables examine => Examine currently defined variables." (interactive) (let ((repl-dictionary '()) (prompt "STRING-REPL> ") (result nil)) (while (pcase (read-from-minibuffer prompt) (input (pcase input ("exit" (setq result nil)) ("clear" (setq repl-dictionary '() result "[CLEARED]")) ("examine" (setq result (format "%S" repl-dictionary))) (_ (let ((exp (read (format "(%s)" input)))) (setq result (condition-case err (repl-eval exp) (error (format "%s" err))))))) (when result (minibuffer-message (concat prompt input (propertize "\t" 'display (list 'space :align-to 40)) (propertize result 'face 'highlight)))))) (setq result nil)))) ^ permalink raw reply [flat|nested] 6+ messages in thread
* bug#13126: 24.3.50; (WISH) Document pcase in Info manual 2012-12-13 15:01 ` Jambunathan K @ 2012-12-13 17:37 ` Stefan Monnier 0 siblings, 0 replies; 6+ messages in thread From: Stefan Monnier @ 2012-12-13 17:37 UTC (permalink / raw) To: Jambunathan K; +Cc: 13126 >>> Thanks. `pcase' seemed a good replacement for `case'. >> While it's not a plug-in replacement, it provides a superset of the >> features of case, yes. > pcase also reminds me of CL's case. Btw, you know in what version of > Emacs did pcase made it's appearance. Probably 24.1. You'd have to check the NEWS file. > Provide a BNF and document TERMINALS before NON-TERMINALS. (Currently it > seems other way round). I don't think a BNF spec has its place there. It's fine for the docstring, but the point of this lispref subsection is to give an introduction to `pcase'. > May be replace the example snippets with a /simple/ and /cohesive/ > example. Do you think snippet 1 is not sufficiently simple? > I found Snippet 2 "too abstract" and leaves a lot to the > imagination of the reader. For those readers not familiar enough with functional programming, I could tweak it, maybe replacing `call' and `fn' cases with `(neg ,x) and `(if ,t ,e1 ,e2)? Would that help? The problem I see with your snippets is that they're too long. Stefan ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-12-13 17:37 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-12-09 9:28 bug#13126: 24.3.50; (WISH) Document pcase in Info manual Jambunathan K 2012-12-09 17:12 ` Stefan Monnier 2012-12-11 10:20 ` Jambunathan K 2012-12-11 13:55 ` Stefan Monnier 2012-12-13 15:01 ` Jambunathan K 2012-12-13 17:37 ` Stefan Monnier
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).