* 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).