A. Helpers


(in-package :cl-user)

(require :cl-ppcre)
(require :iterate)
(use-package '(cl-ppcre iterate))

(declaim (optimize (speed 0) (safety 3) (debug 3)))

(defun chomp (string)
  "Similar to Perl's chomp(), although it returns the new value of
STRING rather than the number of characters removed, and doesn't
modify its argument."
  (string-right-trim #(#\Newline #\Return) string))

(defmacro when-let ((var value) &body body)
  "Evaluate VALUE, and if the result is non-nil bind it to VAR
and evaluate BODY."
  `(let ((,var ,value))
     (when ,var ,@body)))

(defmacro perl-grep (sequence &body predicate-body)
  "Like Perl's grep.  Predicate is a body of code that can refer to IT
as the current element of the list."
  `(remove-if-not #'(lambda (it)
                      ,@predicate-body)
                  ,sequence))

;; The following could be made more efficient by using a faster TEST
;; function if the keys appear to be simpler.
(defun mkhash (&rest keys/values)
  "Utility for making new EQUAL hashes easily, similar to Perl's
built-in funcionality."
  (let ((newhash (make-hash-table :test 'equal ; use EQUAL so strings work as keys
                                  :size (truncate (/ (length keys/values)
                                                     2)))))
    (loop
       for key in keys/values by #'cddr
       for value in (cdr keys/values) by #'cddr
       do (setf (gethash key newhash) value))
    newhash))

;; Section 12.1 has an example usage of this, including how
;; *EXPORT-TAGS* should be formatted.
(defun import-tags (package-designator &rest tags)
  "Helps emulate Perl's EXPORT_TAGS functionality, which has no
equivalent in standard CL."
  (let* ((current-package *package*)
         (*package* (find-package package-designator))
         ;; Otherwise we'll find the *export-tags* from the "calling"
         ;; package.
         (export-tags (symbol-value (find-symbol "*EXPORT-TAGS*" *package*))))
    (dolist (tag tags)
      (import (cadr (assoc tag export-tags))
              current-package))))

;; Like Perl's keys function.
(defun hash-keys (hash)
  (loop for k being the hash-keys of hash collect k))

Common Lisp code makes use of the following for
package/loading: 
(require :PACKAGENAME)

SBCL code makes use of the following for package /
library loading:
(asdf:operate 'asdf:load-op :date-calc) ; load the package
(use-package 'date-calc)                ; import the symbols
(load "time.lisp")              ; replace with your location of the pdl library
(use-package 'CyberTiggyr-Time) ; for printing times in various formats

Packages / libraries used include:
http://cybertiggyr.com/gene/pdl/
http://www.cliki.net/asdf
http://www.cliki.net/cl-interpol
http://www.cliki.net/cl-ppcre
http://www.cliki.net/date-calc
http://www.cliki.net/iterate