;;; sequences.el --- Sequence manipulation functions -*- lexical-binding: t -*- ;; Copyright (C) 2014 Free Software Foundation, Inc. ;; Author: Nicolas Petton ;; Keywords: sequences ;; Maintainer: address@hidden ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; Sequence manipulation functions ;;; Code: ;;;###autoload (defun first (seq) "Return the first element of the sequence SEQ. If SEQ is nil or empty, return nil." (if (listp seq) (car seq) (when (not (empty-p seq)) (elt seq 0)))) ;;;###autoload (defun rest (seq) "Return all but the first element of the sequence SEQ. If SEQ is nil or empty, return nil." (if (listp seq) (cdr seq) (when (not (empty-p seq)) (drop 1 seq)))) ;;;###autoload (defun drop (n seq) "Return a subsequence, without its first N items, of the sequence SEQ." (let ((length (length seq))) (subseq seq (min n length) length))) ;;;###autoload (defun take (n seq) "Return a sequence of the first N items of SEQ." (subseq seq 0 (min n (length seq)))) ;;;###autoload (defun filter (pred seq) "Return a list filtering with PRED all items of SEQ." (delq nil (mapcar (lambda (elt) (and (funcall pred elt) elt)) seq))) ;;;###autoload (defun reduce (function seq &optional initial-value) "Reduce two-argument FUNCTION across SEQ, starting with INITIAL-VALUE if not nil." (let ((acc (or initial-value (if (empty-p seq) (funcall function) (first seq))))) (mapc (lambda (item) (setq acc (funcall function acc item))) (if initial-value seq (rest seq))) acc)) ;;;###autoload (defun some-p (pred seq) "Return any element for which PRED is true in SEQ, nil otherwise." (car (filter pred seq))) ;;;###autoload (defun every-p (pred seq) "Return t if (PRED item) is non-nil for all items of the sequence SEQ." (catch 'break (mapc (lambda (elt) (or (funcall pred elt) (throw 'break nil))) seq) t)) ;;;###autoload (defun empty-p (seq) "Return t if the sequence SEQ is empty, nil otherwise." (= 0 (length seq))) ;;;###autoload (defun sort-seq (seq pred) "Sort the sequence SEQ comparing elements using PRED." (if (listp seq) (sort (copy-seq seq) pred) (sort-seq (append seq nil) pred))) (defalias 'copy-seq #'copy-sequence) ;;;###autoload (defun subseq (seq start &optional end) "Return the subsequence of SEQ from START to END. If END is omitted, it defaults to the length of the sequence. If START or END is negative, it counts from the end." (cond ((or (stringp seq) (vectorp seq)) (substring seq start end)) ((listp seq) (let (len) (and end (< end 0) (setq end (+ end (setq len (length seq))))) (if (< start 0) (setq start (+ start (or len (setq len (length seq)))))) (if (> start 0) (setq seq (nthcdr start seq))) (if end (let ((res nil)) (while (>= (setq end (1- end)) start) (push (pop seq) res)) (nreverse res)) (copy-sequence seq)))) (t (error "Unsupported sequence: %s" seq)))) ;;;###autoload (defun concatenate (type &rest seqs) "Concatenate, into a sequence of type TYPE, the argument SEQS. \n(fn TYPE SEQUENCE...)" (pcase type (`vector (apply #'vconcat seqs)) (`string (apply #'concat seqs)) (`list (apply #'append (append seqs '(nil)))) (t (error "Not a sequence type name: %s" type)))) (provide 'sequences) ;;; sequences.el ends here