From b61e2e3e6c9ebf06b86ecae34179caad0de676e4 Mon Sep 17 00:00:00 2001 From: vindarel Date: Mon, 28 Feb 2022 11:39:18 +0100 Subject: [PATCH] hash tables: export alexandria:hash-table-keys/values, ensure-gethash --- docs/alexandria.md | 204 +++++++++++++++++++++++++-------------------- docs/libraries.md | 15 +++- src/ciel.lisp | 22 ++++- 3 files changed, 142 insertions(+), 99 deletions(-) diff --git a/docs/alexandria.md b/docs/alexandria.md index 8168c40..1cc24f7 100644 --- a/docs/alexandria.md +++ b/docs/alexandria.md @@ -1,8 +1,107 @@ -# Symbols imported from ALEXANDRIA for sequences and lists +# Symbols imported from ALEXANDRIA for sequences and hash-tables + + +## LAST-ELT + +ARGLIST: `(sequence)` + +FUNCTION: Returns the last element of SEQUENCE. Signals a type-error if SEQUENCE is +not a proper sequence, or is an empty sequence. + +## LENGTH= + +ARGLIST: `(&rest sequences)` + +FUNCTION: Takes any number of sequences or integers in any order. Returns true iff +the length of all the sequences and the integers are equal. Hint: there's a +compiler macro that expands into more efficient code if the first argument +is a literal integer. + +## RANDOM-ELT + +ARGLIST: `(sequence &key (start 0) end)` + +FUNCTION: Returns a random element from SEQUENCE bounded by START and END. Signals an +error if the SEQUENCE is not a proper non-empty sequence, or if END and START +are not proper bounding index designators for SEQUENCE. + +## SHUFFLE + +ARGLIST: `(sequence &key (start 0) end)` + +FUNCTION: Returns a random permutation of SEQUENCE bounded by START and END. +Original sequence may be destructively modified. +Signals an error if SEQUENCE is not a proper sequence. + +## SETP + +ARGLIST: `(object &key (test #'eql) (key #'identity))` + +FUNCTION: Returns true if OBJECT is a list that denotes a set, NIL otherwise. A list +denotes a set if each element of the list is unique under KEY and TEST. + +## FLATTEN + +ARGLIST: `(tree)` + +FUNCTION: Traverses the tree in order, collecting non-null leaves into a list. + +## ENSURE-LIST + +ARGLIST: `(list)` + +FUNCTION: If LIST is a list, it is returned. Otherwise returns the list designated by LIST. + +## ENSURE-CONS + +ARGLIST: `(cons)` + +FUNCTION: If CONS is a cons, it is returned. Otherwise returns a fresh cons with CONS + in the car, and NIL in the cdr. + +## DOPLIST + +ARGLIST: `((key val plist &optional values) &body body)` + +FUNCTION: Iterates over elements of PLIST. BODY can be preceded by +declarations, and is like a TAGBODY. RETURN may be used to terminate +the iteration early. If RETURN is not used, returns VALUES. + +## CIRCULAR-LIST-P + +ARGLIST: `(object)` + +FUNCTION: Returns true if OBJECT is a circular list, NIL otherwise. + +## CIRCULAR-LIST + +ARGLIST: `(&rest elements)` + +FUNCTION: Creates a circular list of ELEMENTS. + +TYPE: Type designator for circular lists. Implemented as a SATISFIES type, so not +recommended for performance intensive use. Main usefullness as the +expected-type designator of a TYPE-ERROR. + +## PROPER-SEQUENCE + +TYPE: Type designator for proper sequences, that is proper lists and sequences +that are not lists. + +## PROPER-LIST-P + +ARGLIST: `(object)` + +FUNCTION: Returns true if OBJECT is a proper list. + +## PROPER-LIST + +TYPE: Type designator for proper lists. Implemented as a SATISFIES type, hence +not recommended for performance intensive use. Main usefullness as a type +designator of the expected type in a TYPE-ERROR. ## IOTA - ARGLIST: `(n &key (start 0) (step 1))` FUNCTION: Return a list of n numbers, starting from START (with numeric contagion @@ -14,102 +113,23 @@ Examples: (iota 4) => (0 1 2 3) (iota 3 :start 1 :step 1.0) => (1.0 2.0 3.0) (iota 3 :start -1 :step -1/2) => (-1 -3/2 -2) -## PROPER-LIST +## HASH-TABLE-KEYS -TYPE: Type designator for proper lists. Implemented as a SATISFIES type, hence -not recommended for performance intensive use. Main usefullness as a type -designator of the expected type in a TYPE-ERROR. -## PROPER-LIST-P +ARGLIST: `(table)` +FUNCTION: Returns a list containing the keys of hash table TABLE. -ARGLIST: `(object)` +## HASH-TABLE-VALUES -FUNCTION: Returns true if OBJECT is a proper list. -## PROPER-SEQUENCE +ARGLIST: `(table)` +FUNCTION: Returns a list containing the values of hash table TABLE. -TYPE: Type designator for proper sequences, that is proper lists and sequences -that are not lists. -## CIRCULAR-LIST +## ENSURE-GETHASH +ARGLIST: `(key hash-table &optional default)` -ARGLIST: `(&rest elements)` - -FUNCTION: Creates a circular list of ELEMENTS. - -TYPE: Type designator for circular lists. Implemented as a SATISFIES type, so not -recommended for performance intensive use. Main usefullness as the -expected-type designator of a TYPE-ERROR. -## CIRCULAR-LIST-P - - -ARGLIST: `(object)` - -FUNCTION: Returns true if OBJECT is a circular list, NIL otherwise. -## DOPLIST - - -ARGLIST: `((key val plist &optional values) &body body)` - -FUNCTION: Iterates over elements of PLIST. BODY can be preceded by -declarations, and is like a TAGBODY. RETURN may be used to terminate -the iteration early. If RETURN is not used, returns VALUES. -## ENSURE-CONS - - -ARGLIST: `(cons)` - -FUNCTION: If CONS is a cons, it is returned. Otherwise returns a fresh cons with CONS - in the car, and NIL in the cdr. -## ENSURE-LIST - - -ARGLIST: `(list)` - -FUNCTION: If LIST is a list, it is returned. Otherwise returns the list designated by LIST. -## FLATTEN - - -ARGLIST: `(tree)` - -FUNCTION: Traverses the tree in order, collecting non-null leaves into a list. -## SETP - - -ARGLIST: `(object &key (test #'eql) (key #'identity))` - -FUNCTION: Returns true if OBJECT is a list that denotes a set, NIL otherwise. A list -denotes a set if each element of the list is unique under KEY and TEST. -## SHUFFLE - - -ARGLIST: `(sequence &key (start 0) end)` - -FUNCTION: Returns a random permutation of SEQUENCE bounded by START and END. -Original sequence may be destructively modified. -Signals an error if SEQUENCE is not a proper sequence. -## RANDOM-ELT - - -ARGLIST: `(sequence &key (start 0) end)` - -FUNCTION: Returns a random element from SEQUENCE bounded by START and END. Signals an -error if the SEQUENCE is not a proper non-empty sequence, or if END and START -are not proper bounding index designators for SEQUENCE. -## LENGTH= - - -ARGLIST: `(&rest sequences)` - -FUNCTION: Takes any number of sequences or integers in any order. Returns true iff -the length of all the sequences and the integers are equal. Hint: there's a -compiler macro that expands into more efficient code if the first argument -is a literal integer. -## LAST-ELT - - -ARGLIST: `(sequence)` - -FUNCTION: Returns the last element of SEQUENCE. Signals a type-error if SEQUENCE is -not a proper sequence, or is an empty sequence. +FUNCTION: Like GETHASH, but if KEY is not found in the HASH-TABLE saves the DEFAULT +under key before returning it. Secondary return value is true if key was +already in the table. diff --git a/docs/libraries.md b/docs/libraries.md index d775d6f..c1b9857 100644 --- a/docs/libraries.md +++ b/docs/libraries.md @@ -16,12 +16,21 @@ It's always for an alist, a hash-table, a struct, an object… Use `accesses` for nested access (specially useful with JSON). -### Hash-table utilities (Serapeum) +### Hash-table utilities (Alexandria and Serapeum) -We import functions from Serapeum. +We import functions from [Alexandria](https://alexandria.common-lisp.dev/draft/alexandria.html#Hash-Tables) and [Serapeum](https://github.com/ruricolist/serapeum/blob/master/REFERENCE.md#hash-tables). + +To see their full list with their documentation, see [alexandria](alexandria.md) [serapeum](serapeum.md). + +```txt +;; alexandria +hash-table-keys +hash-table-values +ensure-gethash +``` -To see their full list with their documentation, see [serapeum](serapeum.md). ``` txt +;; serapeum :dict :do-hash-table ;; see also trivial-do :dict* diff --git a/src/ciel.lisp b/src/ciel.lisp index 6e466dc..5f6d14d 100644 --- a/src/ciel.lisp +++ b/src/ciel.lisp @@ -131,6 +131,15 @@ We currently only try this with serapeum. See *deps/serapeum/sequences-hashtable :include *deps/alexandria-2/sequences*) +;; alexandria/hash-tables +(defparameter *deps/alexandria/hash-tables* + '(:hash-table-keys + :hash-table-values + :ensure-gethash)) +(cl-reexport:reexport-from :alexandria + :include + *deps/alexandria/hash-tables*) + ;; alexandria/numbers (cl-reexport:reexport-from :alexandria :include @@ -139,8 +148,10 @@ We currently only try this with serapeum. See *deps/serapeum/sequences-hashtable (push (list "docs/alexandria.md" :alexandria - *deps/alexandria/sequences-lists* - "Symbols imported from ALEXANDRIA for sequences and lists") + (union + *deps/alexandria/sequences-lists* + *deps/alexandria/hash-tables*) + "Symbols imported from ALEXANDRIA for sequences and hash-tables") *doc-pages*) ;; serapeum: sequences/hash tables @@ -303,8 +314,11 @@ We currently only try this with serapeum. See *deps/serapeum/sequences-hashtable (error (c) (format *error-output* "Error during documentation lookup: ~a~&" c)))) (defun generate-dependencies-page-reference () - (loop for doc-spec in *doc-pages* + (loop for doc-spec in (reverse *doc-pages*) + ;; reverse used during development. If we push the same data onto *doc-pages*, the previous one is still processed after the one, so we won't see changes in a doc/….md file. + ;; We could erase the first occurence. do + (format t "~&Formating ~a doc to ~a: ~a~&" (second doc-spec) (first doc-spec) (third doc-spec)) (with-open-file (f (first doc-spec) :direction :output :if-does-not-exist :create @@ -315,7 +329,7 @@ We currently only try this with serapeum. See *deps/serapeum/sequences-hashtable (loop for elt in (third doc-spec) for sym = (uiop:find-symbol* elt (second doc-spec)) do - (format f "## ~a ~%~%~a~&" + (format f "~%## ~a ~%~a~&" elt (with-output-to-string (s) (symbol-documentation sym :stream s)))))))