yasos

  1. yasos
    1. Description
    2. Author
    3. Version
    4. Usage
    5. Download
    6. Documentation
    7. Examples
    8. Changelog
    9. License

Description

"Yet another Scheme Object System"

A very simple OOP system with multiple inheritance, that allows mixing of styles and separates interface from implementation. There are no classes, no meta-anything, simply closures.

Author

Kenneth Dickey

ported to CHICKEN by Juergen Lorenz

Version

1.0

Usage

(require-extension syntax-case yasos)

Download

yasos.egg

Documentation

(define-operation (opname self arg ...) default-body)
(define-predicate opname)
(object ((name self arg ...) body) ...)
(object-with-ancestors ((ancestor1 init1) ...) operation ...)
(operate-as component operation self arg ...) 

Examples

 ;;;===============
 ;;;file yasos-examples.scm
 ;;;===============
 
 (declare (unit yasos-examples))
 (require-extension syntax-case yasos format)
 
 ;;----------------------------
 ;; general operations
 ;;----------------------------
 
 (define-operation (print-obj obj port)
   (format port
     ;; if an instance does not have a print-obj operation..
     (if (instance? obj) "#<INSTANCE>~%" "#<NOT-AN-INSTANCE: ~s>~%") obj))
 
 (define-operation (size-obj obj)
   ;; default behavior
   (cond
     ((vector? obj) (vector-length obj))
     ((list? obj) (length obj))
     ((pair? obj) 2)
     ((string? obj) (string-length obj))
     ((char? obj) 1)
     (else
       (error "Operation not supported: size-obj" obj))))
 
 ;;----------------------
 ;; point interface
 ;;----------------------
 
 (define-predicate point?) ;; answers #f  by default
 (define-operation (x obj))
 (define-operation (y obj))
 (define-operation (set-x! obj new-x))
 (define-operation (set-y! obj new-y))
 
 ;;--------------------------------
 ;; point implementation
 ;;--------------------------------
 
 (define (make-point the-x the-y)
   (object
     ((point? self) #t) ;; yes, this is a point object
     ((x self) the-x)
     ((y self) the-y)
     ((set-x! self val)
       (set! the-x val)
       the-x)
     ((set-y! self val)
       (set! the-y val)
       the-y)
     ((size-obj self) 2)
     ((print-obj self port)
       (format port "#<point: ~a ~a>~%" (x self) (y self)))))
 
 ;;-----------------------------------------
 ;; 3D point interface additions
 ;;-----------------------------------------
 
 (define-predicate point-3d?) ;; #f by defualt
 (define-operation (z obj))
 (define-operation (set-z! obj new-z))
 
 ;;------------------------------------
 ;; 3D point implementation
 ;;------------------------------------
 
 (define (make-point-3d the-x the-y the-z)
   (object-with-ancestors ( (a-point (make-point the-x the-y)) )
     ((point-3d? self) #t)
     ((z self) the-z)
     ((set-z! self val) (set! the-z val) the-z)
     ;; override inherited size-obj and print-obj operations
     ((size-obj self) 3)
     ((print-obj self port)
       (format port "#<3d-point: ~a ~a ~a>~%" (x self) (y self) (z self)))))
 
 ;;;-----------------------
 ;; person interface
 ;;------------------------
 
 (define-predicate person?)
 (define-operation (name obj))
 (define-operation (age obj))
 (define-operation (set-age! obj new-age))
 (define-operation (ssn obj password)) ;; Social Security # is protected
 (define-operation (new-password obj old-passwd new-passwd))
 (define-operation (bad-password obj bogus-passwd)
   ;; assume internal (design) error
   (error (format #f "Bad Password: ~s given to ~a~%"
           bogus-passwd
           (print-obj obj #f))))
 
 ;;----------------------------------
 ;; person implementation
 ;;----------------------------------
 
 (define (make-person a-name an-age a-ssn the-password)
   (object
     ((person? self) #t)
     ((name self) a-name)
     ((age self) an-age)
     ((set-age! self val) (set! an-age val) an-age)
     ((ssn self password)
       (if (equal? password the-password)
         a-ssn
         (bad-password self password)))
     ((new-password self old-passwd new-passwd)
       (cond
         ((equal? old-passwd the-password) (set! the-password new-passwd) self)
         (else (bad-password self old-passwd))))
     ((bad-password self bogus-passwd)
       (format #t "Bad password: ~s~%" bogus-passwd)) ;; let user recover
     ((print-obj self port)
       (format port "#<Person: ~a age: ~a>~%" (name self) (age self)))))
 
 ;;;---------------------------------------------------------------
 ;; account-history and bank-account interfaces
 ;;----------------------------------------------------------------
  
 (define-predicate bank-account?)
 (define-operation (current-balance obj pin))
 (define-operation (add obj amount))
 (define-operation (withdraw obj amount pin))
 (define-operation (get-pin obj master-password))
 (define-operation (get-account-history obj master-password))
 
 ;;----------------------------------------------
 ;; account-history implementation
 ;;----------------------------------------------
 
 ;; put access to bank database and report generation here
 (define (make-account-history initial-balance a-pin master-password)
   ;; history is a simple list of balances -- no transaction times
   (letrec 
     ((history (list initial-balance))
      (balance (lambda () (car history))) ; balance is a function
      (remember
        (lambda (datum) (set! history (cons datum history)))))
     (object
       ((bank-account? self) #t)
       ((add self amount) ;; bank will accept money without a password
         (remember (+ amount (balance)))
         ;; print new balance
         (format #t "New balance: $~a~%" (balance)))
       ((withdraw self amount pin)
         (cond
           ((not (equal? pin a-pin)) (bad-password self pin))
           ((< (- (balance) amount) 0)
             (format 
               #t
               "No overdraft~% Can't withdraw more than you have: $~a~%"
               (balance)))
           (else
             (remember (- (balance) amount))
             (format #t "New balance: $~a~%" (balance)))))
       ((current-balance self password)
         (if (or (eq? password master-password) (equal? password a-pin))
           (format #t "Your Balance is $~a~%" (balance))
           (bad-password self password)))
       ;; only bank has access to account history
       ((get-account-history self password)
         (if (eq? password master-password)
           history
           (bad-password self password))))))
 
 ;;;------------------------------------------
 ;; bank-account implementation
 ;;-------------------------------------------
 
 (define (make-account a-name an-age a-ssn a-pin initial-balance master-password)
   (object-with-ancestors
     ((customer (make-person a-name an-age a-ssn a-pin))
      (account (make-account-history initial-balance a-pin master-password)))
     ((get-pin self password)
       (if (eq? password master-password)
         a-pin
         (bad-password self password)))
     ((get-account-history self password)
       (operate-as account get-account-history self password))
     ;; our bank is very conservative...
     ((bad-password self bogus-passwd)
       (format #t "~%CALL THE POLICE!!~%"))
     ;; protect the customer as well
     ((ssn self password)
       (operate-as customer ssn self password))
     ((print-obj self port)
       (format port "#<Bank-Customer ~a>~%" (name self)))))
 
 ;;; eof yasos-examples.scm
 
 ;;;============
 ;;; file: yasos-test.scm
 ;;;============
 
 (declare (uses yasos-examples))
 (define main
   (lambda ()
     (let
       ((p2 (make-point 1 2))
        (p3 (make-point-3d 4 5 6))
        (fred  (make-person  "Fred"  19 "573-19-4279" 'FadeCafe))
        (sally (make-account "Sally" 26 "629-26-9742" 'FeedBabe 263 'bank-password)))
       (printf "(size-obj p2) => ~a (size-obj p3) => ~a~%" (size-obj p2) (size-obj p3))
       (print-obj 'mist #t)
       (print-obj p2 #t)
       (printf "(point? p2) => ~A (point-3d? p2) => ~A~%" (point? p2) (point-3d? p2))
       (print-obj p3 #t)
       (printf "(point? p3) => ~A (point-3d? p3) => ~A~%" (point? p3) (point-3d? p3))
       (print-obj fred #t)
       (printf "Fred's ssn: ~a~%" (ssn fred 'FadeCafe))
       (printf "Fred: person? ~a bank-account? ~a~%" (person? fred) (bank-account? fred))
       (print-obj sally #t)
       (printf "Sally's  ssn: ~a~%" (ssn sally 'FeedBabe))
       (printf "Sally: person? ~a bank-account? ~a~%" (person? sally) (bank-account? sally))
       (current-balance sally 'FeedBabe)
       (add sally 200)
       (add sally 300)
       (withdraw sally 400 'FeedBabe)
       (printf "Account history of Sally: ~a~%" (get-account-history sally 'bank-password))
       (withdraw sally 150 (get-pin sally 'bank-password))
       (printf "Account history of Sally: ~a~%" (get-account-history sally 'bank-password))
       (printf "Bad password for Fred:~%")
       (ssn fred 'bogus)
       (printf "Bad password for Sally:")
       (ssn sally 'bogus)
       (void) 
 ) ) )   
 (main)
 
 ;;; eof yasos-test.scm

Changelog

License

 COPYRIGHT (c) 1992,2008 by Kenneth A Dickey, All rights reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
 "Software"), to deal in the Software without restriction, including
 without limitation the rights to use, copy, modify, merge, publish,
 distribute, sublicense, and/or sell copies of the Software, and to
 permit persons to whom the Software is furnished to do so, subject to
 the following conditions:
 
 The above copyright notice and this permission notice shall be
 included in all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,WHETHER IN AN ACTION
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.