; ; information-hiding.scm ; A simple technique to accomplish information hiding in R5RS Scheme. ; ; SPDX-FileCopyrightText: In 2023, Chris Pressey, the original author of this work, placed it into the public domain. ; SPDX-License-Identifier: Unlicense ; For more information, please refer to https://unlicense.org/ ;
(define stack-module (lambda () (let* ((secret-token (list 1)) (seal (lambda (data) (lambda (token) (if (eq? token secret-token) data 'an-error-occurred)))) (open (lambda (opaque-object) (opaque-object secret-token)))
(new-stack (lambda ()
(seal '())))
(is-empty? (lambda (stack)
(equal? (open stack) '())))
(push (lambda (stack item)
(let* ((data (open stack))
(new-data (cons item data))
(new-stack (seal new-data)))
new-stack)))
(top (lambda (stack)
(car (open stack))))
(popped (lambda (stack)
(let* ((data (open stack))
(new-data (cdr data))
(new-stack (seal new-data)))
new-stack))))
(list new-stack is-empty? push top popped))))
(define skm (stack-module)) (define new-stack (car skm)) (define is-empty? (cadr skm)) (define push (caddr skm)) (define top (cadddr skm)) (define popped (car (cddddr skm)))
; ; A transcript of some sample usage that shows that it implements a stack: ; ; #;1> (define s (new-stack)) ; #;2> (define t (push s 4)) ; #;3> (define u (push t 5)) ; #;4> (top u) ; 5 ; #;5> (top (popped u)) ; 4 ; #;6> (is-empty? s) ; #t ; #;7> (is-empty? (popped t)) ; #t ; #;8> (popped s) ; ; Error: (cdr) bad argument type: () ;
;
; And a transcript that shows that it hides the representation:
;
; #;8> s
; #