Document Sample
Packages Powered By Docstoc
• Package = a name-space for symbols, where each package has its own
  symbol table.
• Means of modularizing code

Pac-5                                   Pac-10

(defclass player-info ()                (defclass player-info ()
 ((id ....)                              ((id ....)
  (betting-history...)))                  (betting-history...)))

(defmethod can-bluff?                   (defmethod can-bluff?
        ((pi player-history))                   ((pi player-history))
 ....)                                   ....)

(defun calc-bet ()                      (defun calc-bet ()....)
... (can-bluff? player) ...)            ... (can-bluff? player) ...)
                        Imports & Exports
• Packages can export symbols for use by other packages that import
  those symbols.
• These can be variable names, function names, class names, slot names,
  symbolic constants, macro names, etc.

General-Pac                                 Pac-5
                                            (use-package general-pac)
(defvar *hand-rankings*
 ‘(royal-flush straight-flush               (defclass player-info ()
fours...))                                   ((id ....)
(defun eval-cards (cards)...)
                                            (defmethod can-bluff?
(export                                        ((pi player-history)).. )
 (list ‘*hand-rankings*                     (defun calc-bet ()
       ‘eval-cards))                        ...(eval-cards cards)...
                                            ... (can-bluff? player) ...)
                      Dealer Package
;; Note:: This is NOT the dealer package delivered for
   the poker contest, but merely a simple example!!

(in-package dealer)    ;; Package where this code will be

(defvar *dealer* nil) ;; global var for dealer object
(defvar *ordered-card-suits* '(S H C D))
(defvar *poker-hand-order* '(royal-flush straight-flush
   fours full-house flush straight threes two-pairs pair
(defvar *password* ‘sundance)

(defclass dealer ()
  ((player-ids :accessor player-ids) ;; player-ids &
   player-cards are private
   (player-cards :accessor player-cards)
   (blind :accessor blind :initform 10) ;; blind & max-
   bet are public
   (max-bet :accessor max-bet :initform 500)))
                   Dealer Package (2)
(defun make-card (type suit) (cons type suit))
(defun card-value (card) (car card))
(defun card-suit (card) (cdr card))

(defun copy-cards (cards)
  (cond ((null cards) nil)
        (t (cons (cons (car (car cards)) (cdr (car cards)))
                 (copy-cards (cdr cards))))))

(export (list '*ordered-card-suits* '*poker-hand-order*
              'make-card 'card-value 'card-suit 'blind
              'max-bet 's 'h 'c 'd))

;; Note: export of global vars, methods, functions and
   constant symbols.
                Listing, Creating & Loading
> *package* ;; gives current package
            #<The COMMON-LISP-USER package>
> (list-all-packages)
(#<The ACL-SOCKET package> #<The ACLWIN package> #<The C-TYPES
    package> #<The CLOS package> #<The CLTL1 package> #<The
    package> #<The COMMON-LISP package> #<The COMMON-LISP-USER
    package> #<The GARBAGE package> #<The GRAPHER package> ...)

 > (make-package 'dealer) ;; Create the package
          #<The DEALER package>
;; Now load the source code into this package.
;; You can also compile and load binary files if desired
> (load "D:\\allegro\\kdlisp\\games\\dumpack.lsp")
; Loading D:\allegro\kdlisp\games\dumpack.lsp
                     Symbol Access (Variables)
> *ordered-card-suits*
Error: Attempt to take the value of the unbound variable `*ordered-card-suits*'.
;; In the common-lisp-user package, so this var isn’t directly accessible.
> dealer:*ordered-card-suits* ;; Use package prefix with “:” for exported symbols
(dealer:s dealer:h dealer:c dealer:d) ;; Note dealer prefix on all 4 constant symbols
> dealer:*password*
Error: The symbol "*PASSWORD*" is not external in the DEALER package.
> dealer::*password*
dealer::sundance ;; Woops!! The CIA doesn’t use packages..or Lisp!!
;; “::” allows access to all symbols, exported or not.
> (import 'dealer:*ordered-card-suits*) ;; Import an exported global var
> *ordered-card-suits* ;; Now we can refer to it without the “dealer:” prefix
(dealer:s dealer:h dealer:c dealer:d)
            Symbol Access (Function Names)
> (make-card 5 's) ;; This is not defined in common-lisp-user
Error: attempt to call `make-card' which is an undefined function.
> (dealer:make-card 5 's) => (5 . s) ;; It’s exported, so use the package prefix
> (import 'dealer:make-card) => t
> (make-card 5 'd) => (5 . d) ;; Now it works without the package prefix
;; It’s easy to hop back and forth between packages using in-package
> (in-package dealer) => #<The DEALER package>
> *password* => sundance
> (setf *dealer* (make-instance 'dealer)) => #<dealer @ #x20c72e92>
> (setf (player-ids *dealer*) '(1 7 19 32 91)
         (blind *dealer*) 5 (max-bet *dealer*) 250)
> (describe *dealer*)
#<dealer @ #x20c72e92> is an instance of #<standard-class dealer>:
 The following slots have :instance allocation:
 player-ids (1 7 19 32 91)
 player-cards <unbound>
                Symbol Access (Slot Names)
 blind        5
 max-bet        250
> (export '*dealer*) => t ;; Can do this at toploop or in the source code
> (in-package cl-user) ;; cl-user is nickname for common-lisp-user
#<The COMMON-LISP-USER package>
> (describe 'dealer:*dealer*)
          dealer:*dealer* is a symbol.
           Its value is #<dealer::dealer @ #x20c72e92>
           It is globally declared to be a special variable.
          It is external in the DEALER package.
    ;; Note: even though *dealer* is exported, we can’t get all the detailed info
    about it from inside another package.
> (dealer:max-bet dealer:*dealer*) ;; use the exported slot name
> (dealer:player-ids dealer:*dealer*)
Error: The symbol "PLAYER-IDS" is not external in the DEALER package.
> (use-package 'dealer) => t
> *dealer* => #<dealer::dealer @ #x20c72e92>
> *password* ;; Never exported, so error message
Error: Attempt to take the value of the unbound variable `*password*'.
> (blind *dealer*) => 5 ;; exported
> *poker-hand-order* ;; This was exported, but the symbols in the list were not
(dealer::royal-flush dealer::straight-flush dealer::fours dealer::full-house ...)
> *ordered-card-suits*
(s h c d) ;; Note: These are no longer prefixed by dealer package, since all 4
    were also exported and are now implicitly imported via use-package.
> (setf c (make-card 9 'd)) => (9 . d)
> (card-suit c) => d
> (symbol-package 'c) => #<The DEALER package>

MUCH simpler than importing individual symbols. If the used package exports
  many symbols, then the using package can reference all of them without
  prefixes => package usage becomes transparent to the user.
            Defpackage Macro (Beware!!)
> (describe *package*)
#<The COMMON-LISP-USER package> is the package named COMMON-
It has nicknames: USER, CL-USER.
It uses packages: DEALER, COMMON-LISP, EXCL.
(defpackage "Keith" (:nicknames "KD" "K-Pack")
          (:use "DEALER" "COMMON-LISP-USER”)
         (:export "*message*" "*warning*")) => #<The Keith package>
> (in-package KD) => #<The Keith package>
> (setf *message* "Study packages for your project"
      *warning* "But do not try to get too may regret it")
Error: attempt to call `setf' which is an undefined function.
> (in-package cl-user)
Error: attempt to call `in-package' which is an undefined function.
;; Help!!!!!!!!
> (cl-user:describe *package*)
Error: The symbol "DESCRIBE" is not external in COMMON-LISP-USER

Shared By: