Function: let*
let* is a special form defined in eval.c.
Signature
(let* VARLIST BODY...)
Documentation
Bind variables according to VARLIST then eval BODY.
The value of the last form in BODY is returned. Each element of VARLIST is a symbol (which is bound to nil) or a list (SYMBOL VALUEFORM) (which binds SYMBOL to the value of VALUEFORM). Each VALUEFORM can refer to the symbols already bound by this VARLIST.
Probably introduced at or before Emacs version 27.1.
Source Code
// Defined in /usr/src/emacs/src/eval.c
{
Lisp_Object var, val, elt, lexenv;
specpdl_ref count = SPECPDL_INDEX ();
lexenv = Vinternal_interpreter_environment;
Lisp_Object varlist = XCAR (args);
FOR_EACH_TAIL (varlist)
{
elt = XCAR (varlist);
if (SYMBOLP (elt))
{
var = elt;
val = Qnil;
}
else
{
var = Fcar (elt);
if (! NILP (Fcdr (XCDR (elt))))
signal_error ("`let' bindings can have only one value-form", elt);
val = eval_sub (Fcar (XCDR (elt)));
}
var = maybe_remove_pos_from_symbol (var);
CHECK_TYPE (BARE_SYMBOL_P (var), Qsymbolp, var);
if (!NILP (lexenv) && !XBARE_SYMBOL (var)->u.s.declared_special
&& NILP (Fmemq (var, Vinternal_interpreter_environment)))
/* Lexically bind VAR by adding it to the interpreter's binding
alist. */
{
Lisp_Object newenv
= Fcons (Fcons (var, val), Vinternal_interpreter_environment);
if (BASE_EQ (Vinternal_interpreter_environment, lexenv))
/* Save the old lexical environment on the specpdl stack,
but only for the first lexical binding, since we'll never
need to revert to one of the intermediate ones. */
specbind (Qinternal_interpreter_environment, newenv);
else
Vinternal_interpreter_environment = newenv;
}
else
specbind (var, val);
}
CHECK_LIST_END (varlist, XCAR (args));
val = Fprogn (XCDR (args));
return unbind_to (count, val);
}