Hatshepsut
Hatshepsut

Reputation: 6642

Why are there two parentheses after `let` in emacs lisp?

I'm doing a tutorial on emacs lisp, and it's talking about the let function.

;; You can bind a value to a local variable with `let':
(let ((local-name "you"))
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello local-name)
  (other-window 1))

I don't understand the role of the double parentheses after let in the first line. What are they doing that a single set wouldn't do? Running that section without them, I get an error: Wrong type argument: listp, "you".

Upvotes: 12

Views: 4045

Answers (4)

Vatine
Vatine

Reputation: 21258

The let special form takes a list of bindings: (let (<binding-form> ...) <body>).

The binding form is one of <symbol> (denoting a variable bound to the value nil) or a list (<symbol> <value>) (where value is computed when the let is entered).

The difference between let and let* is how the "value" bits are executed. For plain let, they're executed before any of the values are bound:

(let ((a 17) 
      (b 42)) 
  (let ((a b)  ; Inner LET
        (b a)) 
    (list a b)))

Whereas let* executes the binding forms one after another. Both have their places, but you can get by with only using let since (let* (<form1> <form2>...) is equivalent to (let (<form1>) (let (<form2>) ...))

Upvotes: 2

Tyler StandishMan
Tyler StandishMan

Reputation: 459

According to gnu.org, it looks like you can construct and initialize multiple variables with one let statement, so the double parenthesis is there to allow the separation between the variables.

If the varlist is composed of two-element lists, as is often the case, the template for the let expression looks like this:

(let ((variable value)
      (variable value)
      …)
  body…)

Upvotes: 3

Drew
Drew

Reputation: 30701

There are not "double parens".

Presumably, you are thinking of (let ((foo...)...)), and you mean the (( that come after let? If so, consider this:

(let (a b c) (setq a 42)...)

IOW, let declares local variables. It may also bind them. In the previous sexp, it declares a, b, and c, but it doesn't bind any of them, leaving it to the let body to give them values.

An example that declares two variables but binds only one of them (a):

(let ((a 42) b) ... (setq b ...) ...)

Upvotes: 8

Svante
Svante

Reputation: 51501

You can introduce multiple variables there. The outer parentheses delimit the list of bindings, the inner the individual binding form.

(let ((foo "one")
      (bar "two"))
  (frobnicate foo bar))

Upvotes: 15

Related Questions