Packages
Packages are namespaces for symbols, not modules of code. A symbol belongs to one home package; :export makes it external; :use makes another package's external symbols accessible unqualified.
Use uninterned symbols (#:name) or keywords in defpackage to avoid interning symbols in the current package. UIOP's define-package adds conveniences (:mix, :reexport, :recycle).
;;;; package.lisp
(defpackage #:inventory
(:use #:cl) ; inherit COMMON-LISP's external symbols
(:import-from #:alexandria #:when-let #:hash-table-keys)
(:local-nicknames (#:a #:alexandria)) ; package-local nicknames (widely supported)
(:shadow #:remove) ; define our own REMOVE instead of CL:REMOVE
(:export #:make-item #:item-name #:add-item #:remove #:total-value))
;;;; inventory.lisp
(in-package #:inventory)
(defstruct item name (price 0) (qty 0))
(defvar *items* (make-hash-table :test 'equal))
(defun add-item (item) (setf (gethash (item-name item) *items*) item))
(defun remove (name) (remhash name *items*))
(defun total-value ()
(loop for item being the hash-values of *items*
sum (* (item-price item) (item-qty item))))
(defun %internal-helper () :not-exported) ; internal symbol;; Using it
(inventory:add-item (inventory:make-item :name "pen" :price 2 :qty 10))
(inventory:total-value) ; 20
(inventory::%internal-helper) ; :: accesses internal symbols (avoid in real code)
(in-package #:cl-user)
(do-external-symbols (s :inventory) (print s))
(find-package :inventory)
(package-name *package*) ; current package