[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: elisp help: Getting the current word position. (closure?)
From: |
Tassilo Horn |
Subject: |
Re: elisp help: Getting the current word position. (closure?) |
Date: |
Sat, 31 May 2008 18:06:17 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux) |
cinsk <cinsky@gmail.com> writes:
Hi!
> (defun current-word-markers (&optional STRICT REALLY-WORD)
> "Return the position of the current word"
> (let ((old (symbol-function
> 'buffer-substring-no-properties))
> (saved-start (make-marker))
> (saved-end (make-marker)) ret)
>
> (fset 'buffer-substring-no-properties
> (lambda (start end)
> (let (ret)
> (set-marker saved-start start)
> (set-marker saved-end end)
> (setq ret (funcall old start end))
> ret)))
> (setq ret (current-word STRICT REALLY-WORD))
> (fset 'buffer-substring-no-properties old)
> (if ret
> (cons saved-start saved-end)
> nil)))
>
>
> This function works. With my short knowledge of LISP, I think the
> (lambda ...) form in `current-word-markers' is a closure, since it
> refers to the unbound variables (saved-start and saved-end).
Due to emacs' dynamic scoping they're bound when this function is
called. Dynamic scoping basically means that a function can see all
variables its caller defined (recursively). Here's an example:
--8<---------------cut here---------------start------------->8---
(defun foo ()
(let ((foo-val "I'm a local variable of foo!"))
(bar)))
(defun bar ()
foo-val)
(foo) ;; C-x C-e ==> "I'm a local variable of foo!"
--8<---------------cut here---------------end--------------->8---
> Recently, I found that Emacs Lisp does not have "closures" according
> to "GNU Emacs Lisp Reference Manual 2.8".
Yes, that's true.
> Here are a few questions:
>
> 1. Does the (lambda ...) in `current-word-markers' is a closure???
No.
> 3. If not, enlighten me what is a closure.
This real closure won't work in elisp:
--8<---------------cut here---------------start------------->8---
(defun make-adder (n)
(lambda (m)
(+ n m)))
(fset 'adder (make-adder 3))
(adder 3) ;; C-x C-e
==>
Debugger entered--Lisp error: (void-variable n)
(+ n m)
adder(3)
eval((adder 3))
eval-last-sexp-1(nil)
eval-last-sexp(nil)
call-interactively(eval-last-sexp nil nil)
--8<---------------cut here---------------end--------------->8---
Bye,
Tassilo
--
Richard Stallman can coerce meaningful data from /dev/null.