unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* when should a variable to quoted?
@ 2008-09-13  9:11 sunway
  2008-09-13  9:38 ` Pascal J. Bourguignon
  0 siblings, 1 reply; 5+ messages in thread
From: sunway @ 2008-09-13  9:11 UTC (permalink / raw
  To: help-gnu-emacs

(add-to-list 'll "a")
(delete-dups ll)

The variable "ll" needs be quoted in add-to-list, while not quoted in
delete-dups, why? any special reasons?


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

* Re: when should a variable to quoted?
  2008-09-13  9:11 when should a variable to quoted? sunway
@ 2008-09-13  9:38 ` Pascal J. Bourguignon
  2008-09-13 10:21   ` Eli Zaretskii
  2008-09-13 11:06   ` sunway
  0 siblings, 2 replies; 5+ messages in thread
From: Pascal J. Bourguignon @ 2008-09-13  9:38 UTC (permalink / raw
  To: help-gnu-emacs

sunway <sunwayforever@gmail.com> writes:

> (add-to-list 'll "a")
> (delete-dups ll)
>
> The variable "ll" needs be quoted in add-to-list, while not quoted in
> delete-dups, why? any special reasons?

Lisp passes its arguments by-value.

Therefore a function cannot modify the variables from which the values
it gets come.

It still can modify the value, when it is mutable, but not the variable.

Usually, when we want to have a variable (or in general, a place)
modified, we have to use a macro, or a special operator.

(setq ll (list 1 2 3)) ; setq is a special operator.
(require 'cl)
(push 0 ll)            ; push is a macro

Otherwise, you must take care to get the result and store it back into
the variable:

(setq ll (delete ll 2)) ; delete modifies the value of ll, and returns
                        ; the modified value, but when it's the first
                        ; element that is deleted, we need to modify
                        ; the variable too.


For some reason (probably historical), emacs lisp authors prefer to
use a function add-to-list instead of a macro push.  Because there is
no lexical variable in emacs lisp, but only special variables, where
the value of the variable is always stored inside the symbol, in the
symbol-value slot, we can consider any symbol to be a "pointer" to the
variable. Therefore it is possible to pass a symbol to a function that
will modify its symbol-value, thus modifying the variable named by
this symbol.  In lisp with lexical variables such as scheme or Common
Lisp, it wouldn't work.

In the case of delete-dups, it's like in the case of delete, but since
it can never reduce to an empty list if passed an non empty list, it
can modify the value in such a way that the variable always points to
the right value.  Namely, delete-dups modifies the first cons cell of
the list it gets.

Delete doesn't take this special step, so when you delete the first
elements, the result returned and the value of the variable are not
the same cons cell:

(let ((list (list 1 1 2 2 3 3)))
  (print (delete 1 list))
  list)
prints:  (2 2 3 3)
returns: (1 1 2 2 3 3)

We could try to write delete so it modifies the first cons cell:

(defun smart-delete (item list)
   (let* ((first-cell list)
          (head (cons nil list))
          (list head))
     (while (cdr list)
       (if (equal item (cadr list))
          (setf (cdr list) (cddr list))
          (setf list (cdr list))))
     (if (null (cdr head))
         nil
         (progn (setf (car first-cell) (cadr head)
                      (cdr first-cell) (cddr head))
                first-cell))))

(let ((list (list 1 1 2 2 1 3 3)))
  (print (smart-delete 1 list))
  list)
prints:  (2 2 3 3)
returns: (2 2 3 3)

But this wouldn't work when emptying the list:
(let ((list (list 1 1 1)))
  (print (smart-delete 1 list))
  list)
prints:  nil
returns: (1 1 1)

because there is no way of modifying a cons cell to make it the symbol
nil.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

ATTENTION: Despite any other listing of product contents found
herein, the consumer is advised that, in actuality, this product
consists of 99.9999999999% empty space.


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

* Re: when should a variable to quoted?
  2008-09-13  9:38 ` Pascal J. Bourguignon
@ 2008-09-13 10:21   ` Eli Zaretskii
  2008-09-13 11:06   ` sunway
  1 sibling, 0 replies; 5+ messages in thread
From: Eli Zaretskii @ 2008-09-13 10:21 UTC (permalink / raw
  To: help-gnu-emacs

> From: pjb@informatimago.com (Pascal J. Bourguignon)
> Date: Sat, 13 Sep 2008 11:38:18 +0200
> 
> (require 'cl)
> (push 0 ll)            ; push is a macro

push is indeed a macro, but there's no need to require 'cl anymore,
push is now available in Emacs Lisp.




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

* Re: when should a variable to quoted?
  2008-09-13  9:38 ` Pascal J. Bourguignon
  2008-09-13 10:21   ` Eli Zaretskii
@ 2008-09-13 11:06   ` sunway
  2008-09-13 12:29     ` Pascal J. Bourguignon
  1 sibling, 1 reply; 5+ messages in thread
From: sunway @ 2008-09-13 11:06 UTC (permalink / raw
  To: help-gnu-emacs

"elisp lacks of lexical variable", if this happens to the C
programming language:
int a=10;
foo(a);
may be "a" will be changed to 9 ?

if so, I really hate this feature....


On Sep 13, 5:38 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> sunway <sunwayfore...@gmail.com> writes:
> > (add-to-list 'll "a")
> > (delete-dups ll)
>
> > The variable "ll" needs be quoted in add-to-list, while not quoted in
> > delete-dups, why? any special reasons?
>
> Lisp passes its arguments by-value.
>
> Therefore a function cannot modify the variables from which the values
> it gets come.
>
> It still can modify the value, when it is mutable, but not the variable.
>
> Usually, when we want to have a variable (or in general, a place)
> modified, we have to use a macro, or a special operator.
>
> (setq ll (list 1 2 3)) ; setq is a special operator.
> (require 'cl)
> (push 0 ll)            ; push is a macro
>
> Otherwise, you must take care to get the result and store it back into
> the variable:
>
> (setq ll (delete ll 2)) ; delete modifies the value of ll, and returns
>                         ; the modified value, but when it's the first
>                         ; element that is deleted, we need to modify
>                         ; the variable too.
>
> For some reason (probably historical), emacs lisp authors prefer to
> use a function add-to-list instead of a macro push.  Because there is
> no lexical variable in emacs lisp, but only special variables, where
> the value of the variable is always stored inside the symbol, in the
> symbol-value slot, we can consider any symbol to be a "pointer" to the
> variable. Therefore it is possible to pass a symbol to a function that
> will modify its symbol-value, thus modifying the variable named by
> this symbol.  In lisp with lexical variables such as scheme or Common
> Lisp, it wouldn't work.
>
> In the case of delete-dups, it's like in the case of delete, but since
> it can never reduce to an empty list if passed an non empty list, it
> can modify the value in such a way that the variable always points to
> the right value.  Namely, delete-dups modifies the first cons cell of
> the list it gets.
>
> Delete doesn't take this special step, so when you delete the first
> elements, the result returned and the value of the variable are not
> the same cons cell:
>
> (let ((list (list 1 1 2 2 3 3)))
>   (print (delete 1 list))
>   list)
> prints:  (2 2 3 3)
> returns: (1 1 2 2 3 3)
>
> We could try to write delete so it modifies the first cons cell:
>
> (defun smart-delete (item list)
>    (let* ((first-cell list)
>           (head (cons nil list))
>           (list head))
>      (while (cdr list)
>        (if (equal item (cadr list))
>           (setf (cdr list) (cddr list))
>           (setf list (cdr list))))
>      (if (null (cdr head))
>          nil
>          (progn (setf (car first-cell) (cadr head)
>                       (cdr first-cell) (cddr head))
>                 first-cell))))
>
> (let ((list (list 1 1 2 2 1 3 3)))
>   (print (smart-delete 1 list))
>   list)
> prints:  (2 2 3 3)
> returns: (2 2 3 3)
>
> But this wouldn't work when emptying the list:
> (let ((list (list 1 1 1)))
>   (print (smart-delete 1 list))
>   list)
> prints:  nil
> returns: (1 1 1)
>
> because there is no way of modifying a cons cell to make it the symbol
> nil.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
>
> ATTENTION: Despite any other listing of product contents found
> herein, the consumer is advised that, in actuality, this product
> consists of 99.9999999999% empty space.



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

* Re: when should a variable to quoted?
  2008-09-13 11:06   ` sunway
@ 2008-09-13 12:29     ` Pascal J. Bourguignon
  0 siblings, 0 replies; 5+ messages in thread
From: Pascal J. Bourguignon @ 2008-09-13 12:29 UTC (permalink / raw
  To: help-gnu-emacs

sunway <sunwayforever@gmail.com> writes:

> "elisp lacks of lexical variable", if this happens to the C
> programming language:
> int a=10;
> foo(a);
> may be "a" will be changed to 9 ?
>
> if so, I really hate this feature....

1- not in C, but in C++ you can have:
   void foo(int& v){ v=0; }
   void f(){
      int a=10;
      foo(a);
      assert(a==0);
   }

2- even in C, soon enough you have types such as it is possible. eg.
   typedef struct node { int item, struct node* next; } *Node_type;
   void f(void){
       Node_type a=make_node(10);
       foo(a);
       assert(a->item==0);
   }


elisp lack of lexical variables implies only that for all variable,
the symbol naming that variable holds its value and can be used as a
"pointer".  With lexical variables, once compiled there remains no
link between the symbol naming a variable and the variable.  On the
other hand, in these lisp we have real closures, so we can build a
"pointer" also named "locative" with closures.
   
-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.


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

end of thread, other threads:[~2008-09-13 12:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-13  9:11 when should a variable to quoted? sunway
2008-09-13  9:38 ` Pascal J. Bourguignon
2008-09-13 10:21   ` Eli Zaretskii
2008-09-13 11:06   ` sunway
2008-09-13 12:29     ` Pascal J. Bourguignon

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