Next: , Previous: , Up: For   [Contents][Index]


5 Sequence Constructors

Sequence constructors are the heads of sequence forms. In particular, the sequence constructor :do-in is designed for use in expanders of other sequence constructors and is thus an auxiliary operator.

Auxiliary Operator: :do-in memoize-bindings outer-bindings loop-bindings loop-guards inner-bindings loop-forms

This sequence constructor declares the forms to be appended to subforms in expanded iteration forms. An iteration form essentially expands to the following while loop where bodys are the body expanded so far:

(let memoize-bindings
  (pcase-let* outer-bindings
    (let loop-bindings
      (while (and . loop-guards)
        (pcase-let* inner-bindings
          [body…]
          loop-update))))

As a :do-in form is encountered, the relevant forms are appended to subforms of the same name. Moreover, for each loop-binding in loop-bindings and each loop-form in loop-forms where loop-binding has either the form (loop-identifier [initial-value]) or loop-identifier, the form loop-update updates loop-identifier to the value of loop-form after all loop-forms are evaluated. It is an error for loop-bindings and loop-forms to have unmatched number of subforms. For example, a possible implementation of the expander of a sequence constructor that iterates over lists is as follows15:

(:expander-case
 (`(,identifier (,_ ,list-form))
  (let ((list (gensym "list"))
        (tail (gensym "tail")))
    `(,identifier (:do-in ((,list ,list-form))
                          ()
                          ((,tail ,list))
                          ((not (null ,tail)))
                          ((,identifier (car ,tail)))
                          ((cdr ,tail)))))))

A generic sequence constructor is provided, which is the underlying constructor used for dynamic dispatch.

Function: for-generator datum

This sequence constructor returns an iterator of datum. It is a generic function whose primary methods dispatch on the type of datum and return an iterator. The default :around method returns datum as is when it is a function, otherwise it invokes cl-call-next-method. The default primary method signals for-unhandled-type with the singleton list of datum as data.

Below, all sequence constructors have expanders. Additional properties of them as defined by define-for-sequence are also specified where aliases are auxiliary operators. “This sequence” refers to the expansion of or the iterator returned by the sequence constructor. All sequence constructors when used as generators are guaranteed to delay the computation as much as possible, including that of the initial states.

Function: for-in-array array [start [end [step]]]
Auxiliary Operator: in-array array [start [end [step]]]

This sequence iterates over the elements of the array array. Indexes are iterated as in (for-in-range start end step), except that end defaults to (length array) when it is nil or omitted. arrays are dispatched to it. Moreover, a literal array as a sequence form when used in iteration clauses is treated as if this sequence constructor is used.

Function: for-in-inclusive-range start end [step]
Auxiliary Operator: in-inclusive-range start end [step]

This sequence iterates over the numbers between start and end. The step size step defaults to 1 when it is nil or omitted and is added to the number after each iteration. The iteration terminates when the number is no longer in the closed range of start and end.

Function: for-in-infinite-range start [step]
Auxiliary Operator: in-infinite-range start [step]

This sequence iterates over the numbers from start. The step size step defaults to 1 when it is nil or omitted and is added to the number after each iteration.

Function: for-in-list list
Auxiliary Operator: in-list list

This sequence iterates over the elements of the non-dotted list list. As such, lists are dispatched to it. Moreover, a literal list as a sequence form when used in iteration clauses is treated as if this sequence constructor is used.

Function: for-in-producer producer [continuep [arg…]]
Auxiliary Operator: in-producer producer [continuep [arg…]]

This sequence iterates over the values produced by repeated evaluations of the function form (funcall producer [arg…]). The iteration is infinite when continuep is omitted. Otherwise, the iteration terminates when (funcall continuep value) is false where value is the value of the function form.

Function: for-in-range end
Auxiliary Operator: in-range end
Function: for-in-range start end [step]
Auxiliary Operator: in-range start end [step]

This sequence iterates over the numbers between start and end. start defaults to 0 when omitted. The step size step defaults to 1 when it is nil or omitted, and it is added to the number after each iteration. The iteration terminates when the number is no longer in the range of start and end. The range is right half-open when step is non-negative, otherwise it is left half-open. integers are dispatched to it. Moreover, a literal integer as a sequence form when used in iteration clauses is as if this sequence constructor is used.

Function: for-in-iterator iterator
Auxiliary Operator: in-iterator iterator

This sequence is equivalent to the sequence iterator. When used as a function, this sequence constructor checks iterator to be of type function and returns iterator as is. It is mainly useful for its expander to avoid the dynamic dispatch.

Function: for-in-repeat value…
Auxiliary Operator: in-repeat value…

This sequence repeatedly returns each value from left to right. It is equivalent to the sequence (for-in-list (make-circular value…)) where make-circular is a function that makes a circular list of the arguments.

Function: for-in-value value
Auxiliary Operator: in-value value

This sequence returns value once.

Function: for-on-list list
Auxiliary Operator: on-list list

This sequence iterates over the conses of the non-dotted list list.

Function: for-in-directory directory [full [match [nosort [count]]]]
Auxiliary Operator: in-directory directory [full [match [nosort [count]]]]

This sequence iterates over the files in the directory named by the string directory. It is equivalent to the following sequence (see (elisp)Contents of Directories) where full, nosort, and count default to nil when omitted and match defaults to directory-files-no-dot-files-regexp when it is nil or omitted:

(for-in-list (directory-files directory
                              full match nosort count))
Function: for-in-directory-recursively dir regexp [include-directories [predicate [follow-symlinks]]]
Auxiliary Operator: in-directory-recursively dir regexp [include-directories [predicate [follow-symlinks]]]

This sequence iterates over the files under the directory named by the string dir. It is equivalent to the following sequence where include-directories, predicate, and follow-symlinks default to nil when omitted:

(for-in-list (directory-files-recursively
              dir regexp
              include-directories predicate follow-symlinks))
Function: for-the-buffers [frame]
Auxiliary Operator: the-buffers [frame]

This sequence iterates over the buffers of the frame frame. It is equivalent to the sequence (for-in-list (buffer-list frame)) (see (elisp)Buffer List) where frame defaults to nil when omitted.

Function: for-the-frames
Auxiliary Operator: the-frames

This sequence iterates over the frames. It is not equivalent to the sequence (for-in-list (frame-list)) since the frames are visited from the selected frame in next-frame order (see (elisp)Finding All Frames).

Function: for-the-overlays [buffer]
Auxiliary Operator: the-overlays [buffer]

This sequence iterates over the overlays of the buffer buffer. It is equivalent to the following sequence (see (elisp)Current Buffer, (elisp)Finding Overlays, and (elisp)Point) where buffer defaults to the current buffer when it is nil or omitted:

(for-in-list (with-current-buffer buffer
               (overlays-in (point-min)
                            (point-max))))
Function: for-the-windows [frame [minibuf]]
Auxiliary Operator: the-windows [frame [minibuf]]

This sequence iterates over the windows of the frame frame. It is not equivalent to the sequence (for-in-list (window-list)) (see (elisp)Windows and Frames) since the windows are visited from the selected window of the frame frame in next-window order (see (elisp)Cyclic Window Ordering) where frame defaults to the selected frame when it is not a frame or omitted. minibuf and frame are passed to next-window as the minibuf and all-frames arguments where minibuf and frame default to nil when omitted.


Footnotes

(15)

In this example, it may seem unnecessary to “memoize” the value of list-form at first glance. The actual purpose of doing so in this and many similar cases is to preserve the apparent evaluation order, although sometimes memoization is indeed necessary to guarantee that the subexpressions are evaluated exactly once (see (elisp)Argument Evaluation).


Next: Concept Index, Previous: Iteration Forms, Up: For   [Contents][Index]