elisp中的lambda函数范围

时间:2016-02-20 11:32:43

标签: lambda scope elisp

我在设计程序时犯了一个错误。 我需要按其值对哈希表中的部分条目进行排序。 我将用演示代码讲述故事。

;; A loacal hash table......
(let ((table (make-hash-table))
      (list-of-interest nil))

  (puthash 0 "Foo" table)
  (puthash 1 "Bar" table)
  ;;..........
  (puthash 9999 "Bra" table)

  ;; And I have a list with key I am interested to sort
  (dotimes (var 50)
    (add-to-list list-of-interest (random 9999)))

  ;; Sorting should depends on comparing the associated string
  ;; For exmple,
  ;; If the list is (0 1 9999)
  ;; I hope to get (1 9999 0) as "Bar" < "Bra" < "Foo"

  ;; However, I forgot that the table is a local variable
  ;; I can't pass the table to the predicate function by any means
  ;; So the predicate function can never resolve the string from the key
  (sort list-of-interest 'predicate)

  ;; When I was thinking to rewrite the code
  ;; I find that a lambda function can 'grab' the local variable
  (sort list-of-interest (lambda (a b)
                           (string-lessp (gethash a table) (gethash b table))))
  ;; return value
  table)

我在脑海里提出了两个问题:

  1. 最重要的问题:lambda函数是否正常?
  2. 我相信lambda是一个像其他人一样没有名字的功能。为什么它能抓住&#39;局部变量?

1 个答案:

答案 0 :(得分:1)

是的,你的lambda函数没问题。

Emacs Lisp有两种类型的绑定:动态绑定和词法绑定。动态绑定是默认设置,您可以通过将此行添加为Emacs Lisp源文件的第一行来基于每个文件激活词法绑定:

;;; -*- lexical-binding: t; -*-

(这会将变量lexical-binding设置为本地缓冲区中的t。)

你的lambda函数在动态和词法绑定方面都能正常工作。

它与动态绑定一起正常工作,因为该函数仅在sort函数运行时被调用,并且在执行期间有一个名为table的let-bound变量,其中包含所需的值。 / p>

它与词法绑定一起正常工作,因为该函数在词法上位于绑定let的{​​{1}}内,因此该函数可以访问该变量的值。

您的代码有一个问题:您应该将table的结果分配回变量:

sort

(setq list-of-interest (sort list-of-interest ...)) 通过重新排列其缺陷单元对列表进行排序,但不能保证将源列表中的第一个缺点单元重用为目标列表中的第一个缺点单元格。如果您不重新分配结果,则在某些情况下可能会“丢失”某些列表元素。