From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Jambunathan K Newsgroups: gmane.emacs.bugs Subject: bug#13126: 24.3.50; (WISH) Document pcase in Info manual Date: Thu, 13 Dec 2012 20:31:57 +0530 Message-ID: <87fw3a2dy2.fsf@gmail.com> References: <87fw3fpoa6.fsf@gmail.com> <87txrslwjp.fsf@gmail.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1355410768 11044 80.91.229.3 (13 Dec 2012 14:59:28 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 13 Dec 2012 14:59:28 +0000 (UTC) Cc: 13126@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Dec 13 15:59:41 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TjAG6-0006NE-1R for geb-bug-gnu-emacs@m.gmane.org; Thu, 13 Dec 2012 15:59:34 +0100 Original-Received: from localhost ([::1]:39957 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAFt-00039f-9y for geb-bug-gnu-emacs@m.gmane.org; Thu, 13 Dec 2012 09:59:21 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:33474) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAFo-00038T-Nl for bug-gnu-emacs@gnu.org; Thu, 13 Dec 2012 09:59:19 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TjAFk-0002O9-1L for bug-gnu-emacs@gnu.org; Thu, 13 Dec 2012 09:59:16 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:59043) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TjAFj-0002O5-TK for bug-gnu-emacs@gnu.org; Thu, 13 Dec 2012 09:59:11 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TjAGZ-0001aL-TF for bug-gnu-emacs@gnu.org; Thu, 13 Dec 2012 10:00:04 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Jambunathan K Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 13 Dec 2012 15:00:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 13126 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 13126-submit@debbugs.gnu.org id=B13126.13554107956045 (code B ref 13126); Thu, 13 Dec 2012 15:00:03 +0000 Original-Received: (at 13126) by debbugs.gnu.org; 13 Dec 2012 14:59:55 +0000 Original-Received: from localhost ([127.0.0.1]:41060 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TjAGQ-0001ZP-TR for submit@debbugs.gnu.org; Thu, 13 Dec 2012 09:59:55 -0500 Original-Received: from mail-pa0-f44.google.com ([209.85.220.44]:34264) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TjAGJ-0001Yz-UA for 13126@debbugs.gnu.org; Thu, 13 Dec 2012 09:59:51 -0500 Original-Received: by mail-pa0-f44.google.com with SMTP id hz11so1596174pad.3 for <13126@debbugs.gnu.org>; Thu, 13 Dec 2012 06:58:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type; bh=m1ZGoVZKEBcdJRlNG92GTdTZCdZThHs4aEydFe4+G0E=; b=0bIDTd0edNMi/7dvQqCIPHFUndCcLLZK+5cQzFeW2shcXhC6ZrlfXHXqkEsFS440w+ JiV58GPMqQXnluyeDR9pIRTLxFrg4S28CcSiWSQzWy/gMmQeRNaPgxTC4uR7L5/4sb9x 8uy10pzBzsMGKuUjx+erH3rzg3jscbPYO8JWxQXmWxOqzqF6z/t5iNni+qySCfGahoC3 Avntb5uARMDKgLlItDJEZ+jzDmHJGqbxdQ7PTkHWtXRDuz6Na+3fqdy3Y3gfya8qlhAX NiDo/YKbxFZAVb4RbOlZER6fQhDN46tH61NjcXYFjN15AUBYg4NdXW76zXwRGC4zUHNi eLRA== Original-Received: by 10.66.82.33 with SMTP id f1mr6789098pay.11.1355410732379; Thu, 13 Dec 2012 06:58:52 -0800 (PST) Original-Received: from debian-6.05 ([115.184.39.134]) by mx.google.com with ESMTPS id rk17sm1161120pbb.3.2012.12.13.06.58.48 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 13 Dec 2012 06:58:51 -0800 (PST) In-Reply-To: (Stefan Monnier's message of "Tue, 11 Dec 2012 08:55:34 -0500") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:68455 Archived-At: Stefan Monnier 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))))