;;; Provides a read-only Racket connection to public Liitin objects and a set of functions to utilize them locally. (module liitin-lib racket ;;; Note that while an external connection to Liitin objects provides access to the persistent storage system along with dynamic updates, ;;; it cannot quarantee compatibility between diverse operating systems and application versions under constant changes. ;;; For full benefits, a native Liitin account is needed. ;;; Finndesign Liitin home page: http://liitin.finndesign.fi ;; A set of requires to approximate the Liitin environment. ;; You may additionally want to set the DrRacket language level to 'Pretty Big', uncheck case sensivity, ;; and uncheck 'Disallow redefinition of initial bindings' to further improve compatibility. (require (lib "process.ss") mzlib/string racket/port racket/file racket/gui framework racket/date) (provide (rename-out [my-top #%top]) (except-out (all-from-out racket) #%top) (all-defined-out) (all-from-out mzlib/string) (all-from-out racket/file) (except-out (all-from-out racket/gui) #%top) (all-from-out framework) (all-from-out racket/port)) ;XXX READ-ONLY LIITIN CLIENT XXX (define server-name "liitin.finndesign.fi") (define server-port 9877) (define (eval-in-server server-name server-port expr) (let-values (((server->me me->server) (tcp-connect server-name server-port))) (write expr me->server)- (close-output-port me->server) (let ((response (read server->me))) (close-input-port server->me) response))) (define (quotify var) (eval-string (string-append "''" (symbol->string var)))) (define-syntax-rule (my-top . id) (lookup 'id)) (define (lookup id) (define (symbolize id-candidate) (eval-string (string-append "'" (symbol->string id-candidate)))) (if (l-exists? (symbolize id)) (eval-string (l-get (symbolize id))) (error (string-append "reference to undefined identifier: " (symbol->string id))))) ;XXX UTILS XXX ;; For the future use: requests Liitin server identification (define (l-id server-name server-port) (eval-in-server server-name server-port '(identify-yourself))) ;; Liitin-object-exists?. ;; E.g. (l-exists? 'gaia:fibonacci) or (l-exists? 'gaia:fibonacci:2011-06-30T12:00:00) >> #t/#f ;; Leaving the timestamp out returns #t if any version exists ;; The timestamp can point to the future but pointing too early in history returns #f (define (l-exists? liitin-object) (eval-in-server server-name server-port (list 'public-object-exists? (quotify liitin-object)))) ;; Fetches the specified Liitin object ;; E.g. (l-get 'gaia:fibonacci) or (l-get 'gaia:fibonacci:2011-06-30T12:00:00) >> string ;; Leaving the timestamp out returns the latest version ;; Inexact timestamp returns the latest version at the specified time (define (l-get liitin-object) (eval-in-server server-name server-port (list 'fetch-public-object-contents (quotify liitin-object)))) ;; Lists all existing versions of the specified Liitin object ;; E.g. (l-versions 'gaia:fibonacci) >> list (define (l-versions liitin-object) (eval-in-server server-name server-port (list 'public-object-versions (quotify liitin-object)))) ;; To allow using the same top-level definition format as in Liitin ;; i.e. (named-lambda (name args) ...) = (define (name args) ...) (define-syntax named-lambda (syntax-rules () ((rec (name . variables) . body) (letrec ((name (lambda variables . body))) name)) ((rec name expression) (letrec ((name expression)) name)))) ;;XXX EXAMPLES XXX ; ;;; Use of the provided primitives (see liitin-lib.rkt for more information) ;(l-id server-name server-port) ;(l-exists? 'gaia:fibonacci:2011-01-01T12:00:00) ;(l-get 'gaia:fibonacci:2011-01-01T12:00:00) ;(l-versions 'gaia:fibonacci) ; ;;; Calling Liitin objects ;(gaia:fibonacci 10) ;(mirko:eliza "i can't play piano") ;(map gaia:fibonacci '(1 2 3 4 5 6 7 8 9 10)); combine freely with local primitives (map in this case) ;(jtu100:calculator~); GUI example (functionality not implemented) )