From 40eca908574a20caaaa61de6ea63db294dc85ab3 Mon Sep 17 00:00:00 2001 From: William Carroll Date: Thu, 24 Nov 2022 22:26:57 -0800 Subject: feat(wpcarro/emacs): Package vector.el Paying-off more packaging debt... Change-Id: Ide641229d6c8efe70c0fd6c625d07aa1a3be98a0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7395 Tested-by: BuildkiteCI Reviewed-by: wpcarro --- users/wpcarro/emacs/.emacs.d/wpc/vector.el | 84 ----------------------------- users/wpcarro/emacs/pkgs/vector/default.nix | 21 ++++++++ users/wpcarro/emacs/pkgs/vector/tests.el | 20 +++++++ users/wpcarro/emacs/pkgs/vector/vector.el | 58 ++++++++++++++++++++ 4 files changed, 99 insertions(+), 84 deletions(-) delete mode 100644 users/wpcarro/emacs/.emacs.d/wpc/vector.el create mode 100644 users/wpcarro/emacs/pkgs/vector/default.nix create mode 100644 users/wpcarro/emacs/pkgs/vector/tests.el create mode 100644 users/wpcarro/emacs/pkgs/vector/vector.el (limited to 'users') diff --git a/users/wpcarro/emacs/.emacs.d/wpc/vector.el b/users/wpcarro/emacs/.emacs.d/wpc/vector.el deleted file mode 100644 index 6b89708cefcc..000000000000 --- a/users/wpcarro/emacs/.emacs.d/wpc/vector.el +++ /dev/null @@ -1,84 +0,0 @@ -;;; vector.el --- Working with Elisp's Vector data type -*- lexical-binding: t -*- - -;; Author: William Carroll -;; Version: 0.0.1 -;; Package-Requires: ((emacs "25.1")) - -;;; Commentary: -;; It might be best to think of Elisp vectors as tuples in languages like -;; Haskell or Erlang. -;; -;; Not surprisingly, this API is modelled after Elixir's Tuple API. -;; -;; Some Elisp trivia: -;; - "Array": Usually means vector or string. -;; - "Sequence": Usually means list or "array" (see above). -;; -;; It might be a good idea to think of Array and Sequence as typeclasses in -;; Elisp. This is perhaps more similar to Elixir's notion of the Enum protocol. -;; -;; Intentionally not supporting a to-list function, because tuples can contain -;; heterogenous types whereas lists should contain homogenous types. - -;;; Code: - -;; TODO: Consider supporting an alias named tuple for vector. - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; Library -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(defconst vector-enable-tests? t - "When t, run the tests defined herein.") - -;; TODO: Consider labelling variadic functions like `vector-concat*' -;; vs. `vector-concat'. -(defun vector-concat (&rest args) - "Return a new vector composed of all vectors in `ARGS'." - (apply #'vconcat args)) - -;; TODO: Here's a sketch of a protocol macro being consumed. -;; (definstance monoid vector -;; :empty (lambda () [])) - -(defun vector-prepend (x xs) - "Add `X' to the beginning of `XS'." - (vector-concat `[,x] xs)) - -(defun vector-append (x xs) - "Add `X' to the end of `XS'." - (vector-concat xs `[,x])) - -(defun vector-get (i xs) - "Return the value in `XS' at index, `I'." - (aref xs i)) - -(defun vector-set (i v xs) - "Set index `I' to value `V' in `XS'. -Returns a copy of `XS' with the updates." - (let ((copy (vconcat [] xs))) - (aset copy i v) - copy)) - -(defun vector-set! (i v xs) - "Set index `I' to value `V' in `XS'. -This function mutates XS." - (aset xs i v)) - -(when vector-enable-tests? - (let ((xs [1 2 3]) - (ys [1 2 3])) - (prelude-assert (= 1 (vector-get 0 ys))) - (vector-set 0 4 ys) - (prelude-assert (= 1 (vector-get 0 ys))) - (prelude-assert (= 1 (vector-get 0 xs))) - (vector-set! 0 4 xs) - (prelude-assert (= 4 (vector-get 0 xs))))) - -;; TODO: Decide between "remove" and "delete" as the appropriate verbs. -;; TODO: Implement this. -;; (defun vector/delete (i xs) -;; "Remove the element at `I' in `XS'.") - -(provide 'vector) -;;; vector.el ends here diff --git a/users/wpcarro/emacs/pkgs/vector/default.nix b/users/wpcarro/emacs/pkgs/vector/default.nix new file mode 100644 index 000000000000..c0a475aaaa82 --- /dev/null +++ b/users/wpcarro/emacs/pkgs/vector/default.nix @@ -0,0 +1,21 @@ +{ pkgs, depot, ... }: + +let + vector = pkgs.callPackage + ({ emacsPackages }: + emacsPackages.trivialBuild { + pname = "vector"; + version = "1.0.0"; + src = ./vector.el; + }) + { }; + + emacs = (pkgs.emacsPackagesFor pkgs.emacs28).emacsWithPackages (epkgs: [ vector ]); +in +vector.overrideAttrs (_old: { + doCheck = true; + checkPhase = '' + ${emacs}/bin/emacs -batch \ + -l ert -l ${./tests.el} -f ert-run-tests-batch-and-exit + ''; +}) diff --git a/users/wpcarro/emacs/pkgs/vector/tests.el b/users/wpcarro/emacs/pkgs/vector/tests.el new file mode 100644 index 000000000000..ffa983188229 --- /dev/null +++ b/users/wpcarro/emacs/pkgs/vector/tests.el @@ -0,0 +1,20 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Dependencies +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(require 'ert) +(require 'vector) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Tests +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(ert-deftest vector-misc-tests () + (let ((xs [1 2 3]) + (ys [1 2 3])) + (should (= 1 (vector-get 0 ys))) + (vector-set 0 4 ys) + (should (= 1 (vector-get 0 ys))) + (should (= 1 (vector-get 0 xs))) + (vector-set! 0 4 xs) + (should (= 4 (vector-get 0 xs))))) diff --git a/users/wpcarro/emacs/pkgs/vector/vector.el b/users/wpcarro/emacs/pkgs/vector/vector.el new file mode 100644 index 000000000000..87f38d7d93e2 --- /dev/null +++ b/users/wpcarro/emacs/pkgs/vector/vector.el @@ -0,0 +1,58 @@ +;;; vector.el --- Working with Elisp's Vector data type -*- lexical-binding: t -*- + +;; Author: William Carroll +;; Version: 0.0.1 +;; Package-Requires: ((emacs "25.1")) + +;;; Commentary: +;; It might be best to think of Elisp vectors as tuples in languages like +;; Haskell or Erlang. +;; +;; Not surprisingly, this API is modelled after Elixir's Tuple API. +;; +;; Some Elisp trivia: +;; - "Array": Usually means vector or string. +;; - "Sequence": Usually means list or "array" (see above). +;; +;; It might be a good idea to think of Array and Sequence as typeclasses in +;; Elisp. This is perhaps more similar to Elixir's notion of the Enum protocol. +;; +;; Intentionally not supporting a to-list function, because tuples can contain +;; heterogenous types whereas lists should contain homogenous types. + +;;; Code: + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Library +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun vector-concat (&rest args) + "Return a new vector composed of all vectors in `ARGS'." + (apply #'vconcat args)) + +(defun vector-prepend (x xs) + "Add `X' to the beginning of `XS'." + (vector-concat `[,x] xs)) + +(defun vector-append (x xs) + "Add `X' to the end of `XS'." + (vector-concat xs `[,x])) + +(defun vector-get (i xs) + "Return the value in `XS' at index, `I'." + (aref xs i)) + +(defun vector-set (i v xs) + "Set index `I' to value `V' in `XS'. +Returns a copy of `XS' with the updates." + (let ((copy (vconcat [] xs))) + (aset copy i v) + copy)) + +(defun vector-set! (i v xs) + "Set index `I' to value `V' in `XS'. +This function mutates XS." + (aset xs i v)) + +(provide 'vector) +;;; vector.el ends here -- cgit 1.4.1