help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: when should a variable to quoted?


From: sunway
Subject: Re: when should a variable to quoted?
Date: Sat, 13 Sep 2008 04:06:31 -0700 (PDT)
User-agent: G2/1.0

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]