GNU bug report logs - #13126
24.3.50; (WISH) Document pcase in Info manual

Previous Next

Package: emacs;

Reported by: Jambunathan K <kjambunathan <at> gmail.com>

Date: Sun, 9 Dec 2012 09:27:01 UTC

Severity: minor

Merged with 12752

Found in version 24.3.50

Fixed in version 24.3

Done: Glenn Morris <rgm <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 13126 in the body.
You can then email your comments to 13126 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Sun, 09 Dec 2012 09:27:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Jambunathan K <kjambunathan <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Sun, 09 Dec 2012 09:27:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Jambunathan K <kjambunathan <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.3.50; (WISH) Document pcase in Info manual
Date: Sun, 09 Dec 2012 14:58:49 +0530
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 <at> 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





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Sun, 09 Dec 2012 17:14:02 GMT) Full text and rfc822 format available.

Message #8 received at 13126 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Jambunathan K <kjambunathan <at> gmail.com>
Cc: 13126 <at> debbugs.gnu.org
Subject: Re: bug#13126: 24.3.50; (WISH) Document pcase in Info manual
Date: Sun, 09 Dec 2012 12:12:55 -0500
> 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




Forcibly Merged 12752 13126. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Sun, 09 Dec 2012 20:42:02 GMT) Full text and rfc822 format available.

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Tue, 11 Dec 2012 10:19:02 GMT) Full text and rfc822 format available.

Message #13 received at 13126 <at> debbugs.gnu.org (full text, mbox):

From: Jambunathan K <kjambunathan <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 13126 <at> debbugs.gnu.org
Subject: Re: bug#13126: 24.3.50; (WISH) Document pcase in Info manual
Date: Tue, 11 Dec 2012 15:50:42 +0530
>> 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
                




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Tue, 11 Dec 2012 13:57:02 GMT) Full text and rfc822 format available.

Message #16 received at 13126 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Jambunathan K <kjambunathan <at> gmail.com>
Cc: 13126 <at> debbugs.gnu.org
Subject: Re: bug#13126: 24.3.50; (WISH) Document pcase in Info manual
Date: Tue, 11 Dec 2012 08:55:34 -0500
> 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




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Thu, 13 Dec 2012 15:00:03 GMT) Full text and rfc822 format available.

Message #19 received at 13126 <at> debbugs.gnu.org (full text, mbox):

From: Jambunathan K <kjambunathan <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: 13126 <at> debbugs.gnu.org
Subject: Re: bug#13126: 24.3.50; (WISH) Document pcase in Info manual
Date: Thu, 13 Dec 2012 20:31:57 +0530
Stefan Monnier <monnier <at> 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))))
     




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#13126; Package emacs. (Thu, 13 Dec 2012 19:44:01 GMT) Full text and rfc822 format available.

Message #22 received at 13126 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> IRO.UMontreal.CA>
To: Jambunathan K <kjambunathan <at> gmail.com>
Cc: 13126 <at> debbugs.gnu.org
Subject: Re: bug#13126: 24.3.50; (WISH) Document pcase in Info manual
Date: Thu, 13 Dec 2012 12:37:28 -0500
>>> 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




Disconnected #12752 from all other report(s). Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Sat, 05 Jan 2013 19:48:02 GMT) Full text and rfc822 format available.

Forcibly Merged 12752 13126. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Mon, 04 Feb 2013 08:11:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 04 Mar 2013 12:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 12 years and 112 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.