Skip to content

Instantly share code, notes, and snippets.

@AdamHeck
Forked from diiq/1-make-account.scm
Created July 31, 2011 03:09
Show Gist options
  • Save AdamHeck/1116333 to your computer and use it in GitHub Desktop.
Save AdamHeck/1116333 to your computer and use it in GitHub Desktop.
SICP make-account in Tainted Oyster
;; This is some code from chapter 3 of SICP. I chose it by going to
;; http://mitpress.mit.edu/sicp/code/index.html , clicking at random
;; and picking the first good, meaty function that caught my eye. It
;; is a demonstration of object orientation by way of functional
;; closures.
(define (make-account balance)
(define (withdraw amount)
(if (>= balance amount)
(begin (set! balance (- balance amount))
balance)
"Insufficient funds"))
(define (deposit amount)
(set! balance (+ balance amount))
balance)
(define (dispatch m)
(cond ((eq? m 'withdraw) withdraw)
((eq? m 'deposit) deposit)
(else (error "Unknown request -- MAKE-ACCOUNT"
m))))
dispatch)
(define acc (make-account 100))
((acc 'withdraw) 50)
((acc 'deposit) 50)
## Scheme is not a specifically object oriented language, so here is the same
## function as it would be defined in Python. Note that Python does not
## close functions over integers, so in addition to being idiomatic, a class
## is also easiest.
class Account():
def __init__(balance):
self.balance = balance
def withdraw(self, amount):
if selfbalance >= amount:
self.balance -= amount
return self.balance
else:
return "Insufficient funds"
def deposit(self, amount):
self.balance += amount
return self.balance
acc = Account(100)
acc.withdraw(50);
acc.deposit(50);
# Here is a direct transliteration of the scheme into Tainted Oyster:
make-account <- \balance:
withdraw <- \amount:
if (balance >= amount):
balance <- balance - amount
else:
"Insufficient funds"
deposit <- \amount:
balance <- balance + amount
dispatch <- \m:
cond:
(m == 'withdraw): withdraw
(m == 'deposit): withdraw
t: signal: list "Unknown request -- MAKE-ACCOUNT" m
dispatch
acc <- make-account 100
(acc 'withdraw) 50
(acc 'deposit) 50
# Here is a more idiomatically Oyster-ish solution:
make-account <- \balance:
account <- 'account
account.type <- 'account
account.withdraw <- \amount:
if (balance >= amount):
balance <- balance - amount
else:
"Insufficient funds"
account.deposit <- \amount:
balance <- balance + amount
account
acc <- make-account 100
acc.withdraw 50
acc.deposit 50
# But Tainted Oyster is designed for metaprogramming, so here is what it might
# look like if someone wrote an object orientation framework:
class Account (balance):
withdrawl amount:
if (balance >= amount):
balance <- balance - amount
else:
"Insufficient funds"
deposit amount:
balance <- balance + amount
acc <- Account 100
acc.withdraw 50
acc.deposit 50
# But "object orientation framework"? That sound like a lot of work,
# bulky an gross and hard to wri--- oh wait, here it is:
class <- \('name 'args ... 'members):
leak: really name
really name <- \(really args):
return <- name
return.type <- name
while(members):
member <- first members
members <- rest members
return.(really: first member) <- \(really: second member):
*(rest: rest member)
return
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment