unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
@ 2011-01-02 21:45 Thien-Thi Nguyen
  2011-01-02 21:57 ` Fren Zeee
                   ` (4 more replies)
  0 siblings, 5 replies; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-02 21:45 UTC (permalink / raw)
  To: emacs-devel

In Scheme, the expression:

  (cond (EXPR => (lambda (X) ...)))

provides the lambda expression parameter X with the non-false
value computed from evaluating EXPR.  However, if EXPR evaluates
to false, control falls through to the next ‘cond’ clause, as
usual.  The syntax requires the symbol ‘=>’ between EXPR and the
lambda expression, without which the non-false value is discarded
(i.e., the status quo).

What do people think of adding this to Emacs Lisp?  (I would be
grateful for pointers to any previous discussion on the matter.)



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
@ 2011-01-02 21:57 ` Fren Zeee
  2011-01-02 22:52 ` Harald Hanche-Olsen
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 25+ messages in thread
From: Fren Zeee @ 2011-01-02 21:57 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

On Sun, Jan 2, 2011 at 1:45 PM, Thien-Thi Nguyen <ttn@gnuvola.org> wrote:
> In Scheme, the expression:
>
>  (cond (EXPR => (lambda (X) ...)))
>
> provides the lambda expression parameter X with the non-false
> value computed from evaluating EXPR.  However, if EXPR evaluates
> to false, control falls through to the next ‘cond’ clause, as
> usual.  The syntax requires the symbol ‘=>’ between EXPR and the
> lambda expression, without which the non-false value is discarded
> (i.e., the status quo).

To tell you the truth the implies looks not very pretty. I would
rather that emacs is made into lexically scoped lisp like CL than
these teeni changes. Just write the whole thingy like CL. This will
increase the number of people who can help newbies in lisp as there is
only one lisp, the CL. This kind of drastic transition would be easier
than any other.

> What do people think of adding this to Emacs Lisp?  (I would be
> grateful for pointers to any previous discussion on the matter.)

Thien, I would be grateful if you can finish and not STALL the
previous thread where you put an inkomplet reply. I have given my
opinion and hope it helps.

Franz Xe



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
  2011-01-02 21:57 ` Fren Zeee
@ 2011-01-02 22:52 ` Harald Hanche-Olsen
  2011-01-04 16:41   ` Thien-Thi Nguyen
  2011-01-03  2:19 ` Stefan Monnier
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 25+ messages in thread
From: Harald Hanche-Olsen @ 2011-01-02 22:52 UTC (permalink / raw)
  To: emacs-devel

[Thien-Thi Nguyen <ttn@gnuvola.org> (2011-01-02 21:45:56 UTC)]

> In Scheme, the expression:
> 
>   (cond (EXPR => (lambda (X) ...)))
> 
> provides the lambda expression parameter X with the non-false
> value computed from evaluating EXPR.  [...]
> 
> What do people think of adding this to Emacs Lisp?

If you think you need this, I suspect the need can just as easily be
covered using a macro:

(defmacro acond (&rest clauses)
  "Anaphoric `cond': Like `cond', except the value of the condition is bound
to the variable `it' during the execution of the corresponding body."
  ;; Bug: This macro does no error checking.
  `(let (it)
     (cond ,@(mapcar (lambda (clause) (cons (list 'setq 'it (car clause))
					    (cdr clause)))
		     clauses))))

Example usage:

(acond
 ((foo) (do-something-with it))
 ((bar) (do-something-else-with it)))

I learned about anaphoric macros from Paul Graham's "On Lisp".
They can be very handy.

- Harald



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
  2011-01-02 21:57 ` Fren Zeee
  2011-01-02 22:52 ` Harald Hanche-Olsen
@ 2011-01-03  2:19 ` Stefan Monnier
  2011-01-04 17:00   ` Thien-Thi Nguyen
  2011-01-03 16:15 ` Richard Stallman
  2011-01-05  5:17 ` Miles Bader
  4 siblings, 1 reply; 25+ messages in thread
From: Stefan Monnier @ 2011-01-03  2:19 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

> In Scheme, the expression:
>   (cond (EXPR => (lambda (X) ...)))

> provides the lambda expression parameter X with the non-false
> value computed from evaluating EXPR.  However, if EXPR evaluates
> to false, control falls through to the next ‘cond’ clause, as
> usual.  The syntax requires the symbol ‘=>’ between EXPR and the
> lambda expression, without which the non-false value is discarded
> (i.e., the status quo).

> What do people think of adding this to Emacs Lisp?  (I would be
> grateful for pointers to any previous discussion on the matter.)

Doesn't sound bad: it's a conservative extension which doesn't seem to
introduce any significant incompatibility.  The only problem I can see
with it is that it relies on a function call, which is a slow operation
in the current Elisp implementation.


        Stefan



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
@ 2011-01-03  5:37 MON KEY
  2011-01-04 17:20 ` Thien-Thi Nguyen
  0 siblings, 1 reply; 25+ messages in thread
From: MON KEY @ 2011-01-03  5:37 UTC (permalink / raw)
  To: emacs-devel

> What do people think of adding this to Emacs Lisp?

Is the proposed symbol for this syntax extension `=>'?

If so, I find the proposed symbol ugly.

`=>' is already a semantically loaded indicator.

Likewise, the individual tokens of `=>' are too visually similiar to
`=' and `>'.

I would prefer either `#=>' or `#->' which might help to convey the
implicit function call involved.

--
/s_P\



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
                   ` (2 preceding siblings ...)
  2011-01-03  2:19 ` Stefan Monnier
@ 2011-01-03 16:15 ` Richard Stallman
  2011-01-04 18:12   ` Thien-Thi Nguyen
  2011-01-05  5:17 ` Miles Bader
  4 siblings, 1 reply; 25+ messages in thread
From: Richard Stallman @ 2011-01-03 16:15 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

It is un-lispy for a special symbol in the middle of a list
to change the way that list is used.

Here's another syntax that makes it all much simpler.

    (cond VAR COND-CLAUSES...)

would bind VAR, and set it to each clause condition after that is
computed.  For example,

    (cond temp
      ((cdr list) (car temp)))

is equivalent to

    (cond
      ((cdr list) (car (cdr list))))

The same variable gets used for each clause, but if you want to change
to a different one, just write another top-level symbol:

    (cond
      tail
      ((cdr list) (car tail))
      first
      ((car list) (car first)))

Only the last cond variable gets set, and not if it's nil.
So you can also write this:

    (cond temp first nil
      ((setq temp (cdr list)) (car temp))
      ((setq first (car list)) (car first)))

That is more explicit.  It is not quite as brief,
but it s still better than this:

    (cond 
      ((cdr list) -> (lambda (temp) (car temp)))
      ((car list) -> (lambda (first) (car first))))

Currently you can write this,

    (let (temp first)
      (cond
        ((setq temp (cdr list)) (car temp))
        ((setq first (car list)) (car first))))

so the alternatives proposed above are not a tremendous improvement,
just a small improvement.  But even the small improvement might be
good, since it improves readability.


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 22:52 ` Harald Hanche-Olsen
@ 2011-01-04 16:41   ` Thien-Thi Nguyen
  2011-01-04 17:56     ` Harald Hanche-Olsen
  0 siblings, 1 reply; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-04 16:41 UTC (permalink / raw)
  To: emacs-devel

() Harald Hanche-Olsen <hanche@math.ntnu.no>
() Sun, 02 Jan 2011 23:52:34 +0100 (CET)

   If you think you need this, I suspect the need can
   just as easily be covered using a macro:

   (defmacro acond (&rest clauses) ...)

   They can be very handy.

True.  For my own code, i would not hesitate to use it.
However, this macro masks ‘it’ from an outer scope, so is
not a good general (for installation into Emacs) solution.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-03  2:19 ` Stefan Monnier
@ 2011-01-04 17:00   ` Thien-Thi Nguyen
  0 siblings, 0 replies; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-04 17:00 UTC (permalink / raw)
  To: emacs-devel

() Stefan Monnier <monnier@iro.umontreal.ca>
() Sun, 02 Jan 2011 21:19:44 -0500

   The only problem I can see with it is that it relies on a
   function call, which is a slow operation in the current Elisp
   implementation.

Perhaps the compiler can optimize

  (EXPR => (lambda (VAR) BODY))

to be

  (let ((VAR EXPR))
    (when VAR
      ;; book-keeping to mark ‘cond’ success,
      ;; to preclude next clause, here.
      BODY))

?



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-03  5:37 MON KEY
@ 2011-01-04 17:20 ` Thien-Thi Nguyen
  0 siblings, 0 replies; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-04 17:20 UTC (permalink / raw)
  To: emacs-devel

() MON KEY <monkey@sandpframing.com>
() Mon, 3 Jan 2011 00:37:48 -0500

   Is the proposed symbol for this syntax extension `=>'?

Yes.

   If so, I find the proposed symbol ugly.

   `=>' is already a semantically loaded indicator.

I'm sorry, i don't understand what you mean.  Outside of
documentation and the mini-language Calc accepts, i don't
see that symbol in use.

   Likewise, the individual tokens of `=>' are too visually
   similiar to `=' and `>'.

   I would prefer either `#=>' or `#->' which might help to
   convey the implicit function call involved.

The hash is problematic, but really, any short symbol is
fine with me.  (I chose ‘=>’ out of familiarity w/ Scheme.)
Another idea is ‘:=>’ or even ‘::’, both of which font lock
nicely out of the box, for some extra visual distinction.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-04 16:41   ` Thien-Thi Nguyen
@ 2011-01-04 17:56     ` Harald Hanche-Olsen
  2011-01-04 18:39       ` Thien-Thi Nguyen
  0 siblings, 1 reply; 25+ messages in thread
From: Harald Hanche-Olsen @ 2011-01-04 17:56 UTC (permalink / raw)
  To: emacs-devel

[Thien-Thi Nguyen <ttn@gnuvola.org> (2011-01-04 16:41:06 UTC)]

> () Harald Hanche-Olsen <hanche@math.ntnu.no>
> () Sun, 02 Jan 2011 23:52:34 +0100 (CET)
> 
>    If you think you need this, I suspect the need can
>    just as easily be covered using a macro:
> 
>    (defmacro acond (&rest clauses) ...)
> 
>    They can be very handy.
> 
> True.  For my own code, i would not hesitate to use it.
> However, this macro masks ‘it’ from an outer scope, so is
> not a good general (for installation into Emacs) solution.

I offered the solution firstly to argue that the new syntax may not be
needed, since it is easily emulated. But if you want something to add
to emacs for general use, it is easy enough to tweak my macro so it
names the bound variable explicitly:

(defmacro acond (var &rest clauses)
  "Binds variable VAR and processes CLAUSES just like `cond', except that VAR
is set to the condition of the successful clause when the corresponding body
is executed."
  `(let (,var)
     (cond ,@(mapcar (lambda (clause) `((setq ,var ,(car clause))
					,@(cdr clause)))
		     clauses))))

- Harald



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-03 16:15 ` Richard Stallman
@ 2011-01-04 18:12   ` Thien-Thi Nguyen
  2011-01-05  1:55     ` Stephen J. Turnbull
                       ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-04 18:12 UTC (permalink / raw)
  To: emacs-devel

() Richard Stallman <rms@gnu.org>
() Mon, 03 Jan 2011 11:15:11 -0500

   It is un-lispy for a special symbol in the middle of
   a list to change the way that list is used.

Hmm.  I guess that this is the same grounds for your
unease with keyword arguments.  Close?  My take on the
lispiness of this change is:

- We are already dealing with a construct where the
  treatment of the list is non-uniform (EXPR vs BODY),
  so playing in the "neck" area has precedence: special
  handling of docstring, ‘interactive’ form, indentation
  hints (for ‘defmacro’), etc.

- Functional style is not unlispy.  It's true that a
  large body of Emacs Lisp is written with assignments
  (and will continue to be done that way), but that is
  hardly elegant.  It would be nice to bolster this
  argument with "and hardly needed", supplying stats
  gathered from lisp/* on how often a local variable is
  declared only to be used in communication between a
  cond's EXPR and BODY forms, but i haven't done that,
  yet.  (Anyone want to beat me to it?)

Having said that, i readily admit my relative inexperience
with Lisp (Emacs Lisp or otherwise).  It could be that what i
hold dear as lispy is actually more schemey than anything...
Now for some thoughts on:

   Here's another syntax that makes it all much simpler.

       (cond VAR COND-CLAUSES...)

   [...]

   The same variable gets used for each clause, but if
   you want to change to a different one, just write
   another top-level symbol:

       (cond
         tail
         ((cdr list) (car tail))
         first
         ((car list) (car first)))

Really, what i want to do is elide variable names entirely,
for what i regard as essentially an internal (to each clause)
affair.  Any communication outside of that scope is a lose
(or rather, is the status quo, which is less than winning).

   Only the last cond variable gets set, and not if it's nil.
   So you can also write this:

       (cond temp first nil
         ((setq temp (cdr list)) (car temp))
         ((setq first (car list)) (car first)))

   That is more explicit.  It is not quite as brief,
   but it s still better than this:

       (cond 
         ((cdr list) -> (lambda (temp) (car temp)))
         ((car list) -> (lambda (first) (car first))))

   Currently you can write this,

       (let (temp first)
         (cond
           ((setq temp (cdr list)) (car temp))
           ((setq first (car list)) (car first))))

   so the alternatives proposed above are not a tremendous
   improvement, just a small improvement.  But even the small
   improvement might be good, since it improves readability.

I should clarify.  The original proposal should read:

  (cond (EXPR => 1-ARY-FUNC) ...)

In other words, the (lambda (VAR) ...) does the job,
but is not required.  So, the example expression you
gave above can actually be made even more succinct:

  (cond 
    ((cdr list) => #'car)
    ((car list) => #'car)

No variables at all!



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-04 17:56     ` Harald Hanche-Olsen
@ 2011-01-04 18:39       ` Thien-Thi Nguyen
  0 siblings, 0 replies; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-04 18:39 UTC (permalink / raw)
  To: emacs-devel

() Harald Hanche-Olsen <hanche@math.ntnu.no>
() Tue, 04 Jan 2011 18:56:13 +0100 (CET)

   if you want something to add to emacs for general use, it is
   easy enough to tweak my macro so it names the bound variable
   explicitly:

   (defmacro acond (var &rest clauses) ...)

True again!

Now, the trick is to get rid of VAR.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-04 18:12   ` Thien-Thi Nguyen
@ 2011-01-05  1:55     ` Stephen J. Turnbull
  2011-01-05  3:21       ` Thien-Thi Nguyen
  2011-01-05 21:29     ` Stefan Monnier
  2011-01-05 23:36     ` Richard Stallman
  2 siblings, 1 reply; 25+ messages in thread
From: Stephen J. Turnbull @ 2011-01-05  1:55 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

Thien-Thi Nguyen writes:

 > - We are already dealing with a construct where the
 >   treatment of the list is non-uniform (EXPR vs BODY),
 >   so playing in the "neck" area has precedence: special
 >   handling of docstring, ‘interactive’ form, indentation
 >   hints (for ‘defmacro’), etc.

All these occur in a top-level form, though.

 > - Functional style is not unlispy.

True, but in the examples so far you could define a macro like

(defmacro applificating-cond (&rest clauses)
  "Documentation is all too often left to the reader.
This docstring just follows that custom."
  (let ((var (gensym)))
    `(let (,var)
       (cond ,@(mapcar (lambda (clause) `((setq ,var ,(car clause))
					  (funcall ,(cdr clause) ,var)))
		       clauses)))))

and write

   (applificating-cond 
     ((cdr list) #'car)
     ((car list) #'car)

instead of

 >   (cond 
 >     ((cdr list) => #'car)
 >     ((car list) => #'car)

No?

 > No variables at all!

I do like that.  So, do you ever want to write

   (cond 
     ((cdr list) => #'car)
     ((car list) (random-expr-not-needing-value-of-car-list free-var))

or the like?  (That makes me feel a little ill, but YMMV.)



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05  1:55     ` Stephen J. Turnbull
@ 2011-01-05  3:21       ` Thien-Thi Nguyen
  2011-01-05  4:16         ` Stephen J. Turnbull
  0 siblings, 1 reply; 25+ messages in thread
From: Thien-Thi Nguyen @ 2011-01-05  3:21 UTC (permalink / raw)
  To: emacs-devel

() "Stephen J. Turnbull" <stephen@xemacs.org>
() Wed, 05 Jan 2011 10:55:28 +0900

   All these occur in a top-level form, though.

Usually, yes.

    > - Functional style is not unlispy.

   True, but in the examples so far you could define a macro like

   (defmacro applificating-cond (&rest clauses) ...)

   and write

      (applificating-cond 
        ((cdr list) #'car)
        ((car list) #'car)

   No?

Yes, but now traditional ‘cond’ clauses cannot be used within
‘applificating-cond’.  The ‘=>’ serves to distinguish between
those clauses requiring the EXPR value and those that don't.
Which brings us to:

   So, do you ever want to write

      (cond 
        ((cdr list) => #'car)
        ((car list) (random-expr-not-needing-value-of-car-list free-var))

   or the like?  (That makes me feel a little ill, but YMMV.)

Sure, why not?  Good fences make good neighbors, and the price
of this flexible neighborliness (or neighborly flexibility) is
syntax.

(cond
  ((integerp x) => #'-)             ; takes value
  ((not (listp x)) 42)              ; traditional
  ((cdr x) => #'car)                ; takes value
  ((car x)                          ; takes value, unnecessarily
   => (lambda (head)
        (code that ignores ; head
         oh well
         life goes on))))

There are other ways to distinguish between these two clause
variants, of course.  Doodling out loud:

- Move special symbol to head of clause.
  (=> EXPR 1-ARY-FUNC)

- Use vectors.
  [EXPR 1-ARY-FUNC]

- Use top-level special symbol.
  => (EXPR 1-ARY-FUNC)

- Use top-level symbol more special in some ways, less in others.
  t (EXPR 1-ARY-FUNC)

- Use a number to encode arity.
  N (EXPR N-ARY-FUNC)

I think the last one is too strange, personally, but there it is.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05  3:21       ` Thien-Thi Nguyen
@ 2011-01-05  4:16         ` Stephen J. Turnbull
  2011-01-05  5:15           ` Miles Bader
  0 siblings, 1 reply; 25+ messages in thread
From: Stephen J. Turnbull @ 2011-01-05  4:16 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

Thien-Thi Nguyen writes:

 > Sure, why not?  Good fences make good neighbors, and the price
 > of this flexible neighborliness (or neighborly flexibility) is
 > syntax.
 > 
 > (cond
 >   ((integerp x) => #'-)             ; takes value
 >   ((not (listp x)) 42)              ; traditional
 >   ((cdr x) => #'car)                ; takes value
 >   ((car x)                          ; takes value, unnecessarily
 >    => (lambda (head)
 >         (code that ignores ; head
 >          oh well
 >          life goes on))))

Well, it makes me want to gag, that's all. ;-)  I would not mix the
two, though (if the change is approved) you are welcome to do so.
After all, if you want the very occasional constant,

    (applicating-cond
      ((integerp x)  #'-)               ; takes value
      ((not (listp x)) (lambda (y) 42)) ; constant function of 1 arg
      ((cdr x)  #'car)                  ; takes value
      ((car x)                          ; takes value, 'cause that's how
       (lambda (head)                   ; applicating-cond works, OK?
         (code that ignores ; head
          oh well
          life goes on))))

Or (this is pretty disgusting, too) applicating-cond could check for
(functionp (cadr clause)), and call the function on the result of (car
clause) if that is non-nil, otherwise, return the value.  I suppose
'#'car would make it possible to return #'car in that case.

 > - Use a number to encode arity.
 >   N (EXPR N-ARY-FUNC)
 > 
 > I think the last one is too strange, personally, but there it is.

The expansion could also use apply instead of funcall, so that the
function can be any-ary.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05  4:16         ` Stephen J. Turnbull
@ 2011-01-05  5:15           ` Miles Bader
  0 siblings, 0 replies; 25+ messages in thread
From: Miles Bader @ 2011-01-05  5:15 UTC (permalink / raw)
  To: Stephen J. Turnbull; +Cc: Thien-Thi Nguyen, emacs-devel

"Stephen J. Turnbull" <stephen@xemacs.org> writes:
> Well, it makes me want to gag, that's all. ;-) 

Yeah it is kinda gagworthy, isn't it...?

[How do people come up with this kind of crap?]

-miles

-- 
Everywhere is walking distance if you have the time.  -- Steven Wright



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
                   ` (3 preceding siblings ...)
  2011-01-03 16:15 ` Richard Stallman
@ 2011-01-05  5:17 ` Miles Bader
  4 siblings, 0 replies; 25+ messages in thread
From: Miles Bader @ 2011-01-05  5:17 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

Thien-Thi Nguyen <ttn@gnuvola.org> writes:
> In Scheme, the expression:
>   (cond (EXPR => (lambda (X) ...)))

Syntax is horrible.

-miles

-- 
Friendless, adj. Having no favors to bestow. Destitute of fortune. Addicted to
utterance of truth and common sense.



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-04 18:12   ` Thien-Thi Nguyen
  2011-01-05  1:55     ` Stephen J. Turnbull
@ 2011-01-05 21:29     ` Stefan Monnier
  2011-01-05 22:40       ` Harald Hanche-Olsen
  2011-01-05 23:36     ` Richard Stallman
  2 siblings, 1 reply; 25+ messages in thread
From: Stefan Monnier @ 2011-01-05 21:29 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

> - Functional style is not unlispy.  It's true that a

Agreed, and as a functional programmer (and implementer of functional
programming languages) the fact that the proposed cond => thingy is
naturally pure is an important aspect.  Richard's proposal fails pretty
poorly there.  Yet, Richard's proposal solves another problem as well:
often the value is needed not just for the body of a cond branch, but
also for subsequent branches (because the value is used in several of
the conditions, but not all (and more importantly not the first), so you
can't (or don't want to for efficiency reasons) lift it to before the
cond, yet you do want to share it between branches).

An alternative would be to add a way for a cond test to add a variable
so it's available to the cond's body and to subsequent branches, i.e.
a let in the middle of the cond.


  (cond
   (foo bar)
   ((special-let ((var exp1)) exp2) bla... exp1 ...bla)
   (bli... exp1 ...bli) ...)

Such a thing could still be pure, while providing more flexibility than
Richard's (since the var doesn't have to take the value returned as the
condition, but can take the value of any sub-expression needed to
compute that condition).


        Stefan



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05 21:29     ` Stefan Monnier
@ 2011-01-05 22:40       ` Harald Hanche-Olsen
  2011-01-06  0:10         ` Stefan Monnier
  2011-01-06 18:43         ` Richard Stallman
  0 siblings, 2 replies; 25+ messages in thread
From: Harald Hanche-Olsen @ 2011-01-05 22:40 UTC (permalink / raw)
  To: emacs-devel

[Stefan Monnier <monnier@IRO.UMontreal.CA> (2011-01-05 21:29:30 UTC)]

> Yet, Richard's proposal solves another problem as well:
> often the value is needed not just for the body of a cond branch, but
> also for subsequent branches

When I read this, I thought for a moment that you had lost your
marbles: For you only get into subsequent branches if the previous
conditions were all nil, which is a rather boring value to retain for
later use. But then I realized that you are now talking about a way to
bind subexpressions of a condition to make it available further in,
and that makes sense. Sort of.

However, it seems to me that we are now coming up with rather
convoluted schemes in which scoping become far from obvious,
especially to someone unfamiliar with this particular lisp. Also, I
wonder what is so special about cond, anyhow? Surely, you may wish to
make subexpressions of the condition in an if, when or unless form
available to other parts of the form as well? But we already have that:
Any lisp programmer will surely understand the role of blah in

(let (blah)
  (if (foo (setq blah (quux)))
      (bar blah)
    (baz blah)))

and it seems to me that dressing this construct up in a bunch of extra
syntax is just going to muddy the waters and confuse the users.

And by the way, the bike shed should be blue for certain.

- Harald



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-04 18:12   ` Thien-Thi Nguyen
  2011-01-05  1:55     ` Stephen J. Turnbull
  2011-01-05 21:29     ` Stefan Monnier
@ 2011-01-05 23:36     ` Richard Stallman
  2011-01-11 17:20       ` Andy Wingo
  2 siblings, 1 reply; 25+ messages in thread
From: Richard Stallman @ 2011-01-05 23:36 UTC (permalink / raw)
  To: Thien-Thi Nguyen; +Cc: emacs-devel

    I should clarify.  The original proposal should read:

      (cond (EXPR => 1-ARY-FUNC) ...)

It would rarely be useful, so it is not worth adding to Emacs Lisp.

      (cond 
	((cdr list) => #'car)
	((car list) => #'car)

That would be possible when the computation to be done
happens to match an existing function.  That was true in my
(artificial) example, but it is rarely true in real life.

-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05 22:40       ` Harald Hanche-Olsen
@ 2011-01-06  0:10         ` Stefan Monnier
  2011-01-06  8:24           ` Helmut Eller
  2011-01-06 18:43         ` Richard Stallman
  1 sibling, 1 reply; 25+ messages in thread
From: Stefan Monnier @ 2011-01-06  0:10 UTC (permalink / raw)
  To: Harald Hanche-Olsen; +Cc: emacs-devel

> However, it seems to me that we are now coming up with rather
> convoluted schemes in which scoping become far from obvious,
> especially to someone unfamiliar with this particular lisp.

Agreed.  A slightly more sane syntax could be

  (cond
   (foo bar)
   (:let var exp1)
   (exp2 bla... var ...bla)
   (bli... var ...bli) ...)

but it's still not very convincing.

> Also, I wonder what is so special about cond, anyhow?

It's often useful to use cond to syntactically list
various alternatives.  But if some of conds need the same sub-expression
and that sub-expression is not always computed, you get into a funny
situation where you need to use

  (let (var)
    ...
    (setq var ...)
    ...)

I.e. separate the declaration of a variable from its initialization,
which is ugly and introduces side-effects even for a variable which
often could/should really be immutable.

Lazy languages solve this by letting the user do

   (let ((var exp1))
     ...
     ...var...
     ...)

and have exp1 only evaluated the first time var is used.  But we don't
want to add laziness, do we?


        Stefan



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-06  0:10         ` Stefan Monnier
@ 2011-01-06  8:24           ` Helmut Eller
  2011-01-07  3:49             ` Stefan Monnier
  0 siblings, 1 reply; 25+ messages in thread
From: Helmut Eller @ 2011-01-06  8:24 UTC (permalink / raw)
  To: emacs-devel

* Stefan Monnier [2011-01-06 00:10] writes:

> and have exp1 only evaluated the first time var is used.  But we don't
> want to add laziness, do we?

Can't you add those exotic cases to pcase?  Or perhaps add a pcond and a
plet.  Please keep cond as it is.

Helmut




^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05 22:40       ` Harald Hanche-Olsen
  2011-01-06  0:10         ` Stefan Monnier
@ 2011-01-06 18:43         ` Richard Stallman
  1 sibling, 0 replies; 25+ messages in thread
From: Richard Stallman @ 2011-01-06 18:43 UTC (permalink / raw)
  To: Harald Hanche-Olsen; +Cc: emacs-devel

    However, it seems to me that we are now coming up with rather
    convoluted schemes in which scoping become far from obvious,

The scoping in my proposal is quite natural.  A variable is bound
where it appears, and the scope ends at the end of the cond-form.

I agree that this is not an important feature.
I am not arguing in favor of it.
However, if such a feature is to be considered,
it should be a clean and simple one.


-- 
Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org, www.gnu.org



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-06  8:24           ` Helmut Eller
@ 2011-01-07  3:49             ` Stefan Monnier
  0 siblings, 0 replies; 25+ messages in thread
From: Stefan Monnier @ 2011-01-07  3:49 UTC (permalink / raw)
  To: Helmut Eller; +Cc: emacs-devel

>> and have exp1 only evaluated the first time var is used.  But we don't
>> want to add laziness, do we?
> Can't you add those exotic cases to pcase?  Or perhaps add a pcond and a
> plet.  Please keep cond as it is.

Right now, there's no plan whatsoever.
Any addition to the basic special forms will need to be very well
argumented (and come with a patch that handles all the relevant cases,
including byte-compiler).
Addition of a new macro OTOH is very straightforward, so I'd expect any
such change to take the form of a new macro.


        Stefan



^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...)))
  2011-01-05 23:36     ` Richard Stallman
@ 2011-01-11 17:20       ` Andy Wingo
  0 siblings, 0 replies; 25+ messages in thread
From: Andy Wingo @ 2011-01-11 17:20 UTC (permalink / raw)
  To: rms; +Cc: Thien-Thi Nguyen, emacs-devel

On Wed 05 Jan 2011 15:36, Richard Stallman <rms@gnu.org> writes:

>     I should clarify.  The original proposal should read:
>
>       (cond (EXPR => 1-ARY-FUNC) ...)
>
> It would rarely be useful, so it is not worth adding to Emacs Lisp.

It exists in Scheme FWIW, and is widely used there.  (Probably doesn't
have much bearing on this argument, though.)

Andy
-- 
http://wingolog.org/



^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2011-01-11 17:20 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-02 21:45 emacs lisp syntax rfc: (cond (EXPR => (lambda (X) ...))) Thien-Thi Nguyen
2011-01-02 21:57 ` Fren Zeee
2011-01-02 22:52 ` Harald Hanche-Olsen
2011-01-04 16:41   ` Thien-Thi Nguyen
2011-01-04 17:56     ` Harald Hanche-Olsen
2011-01-04 18:39       ` Thien-Thi Nguyen
2011-01-03  2:19 ` Stefan Monnier
2011-01-04 17:00   ` Thien-Thi Nguyen
2011-01-03 16:15 ` Richard Stallman
2011-01-04 18:12   ` Thien-Thi Nguyen
2011-01-05  1:55     ` Stephen J. Turnbull
2011-01-05  3:21       ` Thien-Thi Nguyen
2011-01-05  4:16         ` Stephen J. Turnbull
2011-01-05  5:15           ` Miles Bader
2011-01-05 21:29     ` Stefan Monnier
2011-01-05 22:40       ` Harald Hanche-Olsen
2011-01-06  0:10         ` Stefan Monnier
2011-01-06  8:24           ` Helmut Eller
2011-01-07  3:49             ` Stefan Monnier
2011-01-06 18:43         ` Richard Stallman
2011-01-05 23:36     ` Richard Stallman
2011-01-11 17:20       ` Andy Wingo
2011-01-05  5:17 ` Miles Bader
  -- strict thread matches above, loose matches on Subject: below --
2011-01-03  5:37 MON KEY
2011-01-04 17:20 ` Thien-Thi Nguyen

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