Skip to main content
OP requested version without SetAttributes
Source Link
user21
user21

Here is an idea:

SetAttributes[account, HoldAll ]

makeAccount[ initBalance_ ] :=
 Module[ { balance = initBalance },
  account[ balance ]
  ]

account /: balance[ account[ bal_ ] ] := bal

account /: deposit[ account[ bal_ ], newBal_ ] := ( bal += newBal )

account /: withdraw[ account[ bal_ ], amount_ ] := ( bal -= amount ) /; 
  amount <= bal
account /: withdraw[ account[ bal_ ], amount_ ] := 
 Print[ "Save some cash first" ] /; amount > bal

Format[ acc_account  /; ValueQ[ balance[ acc ] ] ] := "-account-"

Then use this as:

a1 = makeAccount[100]
a2 = makeAccount[150]

balance[a1]

100

deposit[a1, 100]

200

balance[a1]

200

balance[a2]

150

This works because of the unique symbol:

FullForm[a1]

Edit:

Here is a version without SetAttributes

makeAccount1[ initBalance_ ] :=
 
 Module[ { balance = initBalance , withdraw, deposit, amount, 
   dispatch},
  
  withdraw[ amount_ ] :=
   Module[ {},
    If[ balance >= amount,
     balance -= amount; balance,
     Print[ "Insufficient funds" ] 
     ]
    ];
  
  deposit[ amount_ ] :=
   Module[ {},
    balance += amount; 
    balance
    ];
  
  amount[ amount_ ] :=
   Module[ {},
    balance
    ];
  
  dispatch[m_] :=
   Which[
    StringMatchQ[ m, "withdraw" ], withdraw,
    StringMatchQ[ m, "deposit" ], deposit,
    StringMatchQ[ m, "amount" ], amount,
    (* else *)
    True, Print["Unknown request -- MAKE_ACCOUNT ", m]
    ];
  
  Return[ dispatch ];
  ]

Use as follows:

acc = makeAccount1[ 100 ] 
acc2 = makeAccount1[ 200 ] 

dispatch$99 dispatch$100

acc[  "withdraw" ][ 10 ]

90

acc2[ "withdraw" ][ 60 ]

140

acc2["amount"][]

140

Here is an idea:

SetAttributes[account, HoldAll ]

makeAccount[ initBalance_ ] :=
 Module[ { balance = initBalance },
  account[ balance ]
  ]

account /: balance[ account[ bal_ ] ] := bal

account /: deposit[ account[ bal_ ], newBal_ ] := ( bal += newBal )

account /: withdraw[ account[ bal_ ], amount_ ] := ( bal -= amount ) /; 
  amount <= bal
account /: withdraw[ account[ bal_ ], amount_ ] := 
 Print[ "Save some cash first" ] /; amount > bal

Format[ acc_account  /; ValueQ[ balance[ acc ] ] ] := "-account-"

Then use this as:

a1 = makeAccount[100]
a2 = makeAccount[150]

balance[a1]

100

deposit[a1, 100]

200

balance[a1]

200

balance[a2]

150

This works because of the unique symbol:

FullForm[a1]

Here is an idea:

SetAttributes[account, HoldAll ]

makeAccount[ initBalance_ ] :=
 Module[ { balance = initBalance },
  account[ balance ]
  ]

account /: balance[ account[ bal_ ] ] := bal

account /: deposit[ account[ bal_ ], newBal_ ] := ( bal += newBal )

account /: withdraw[ account[ bal_ ], amount_ ] := ( bal -= amount ) /; 
  amount <= bal
account /: withdraw[ account[ bal_ ], amount_ ] := 
 Print[ "Save some cash first" ] /; amount > bal

Format[ acc_account  /; ValueQ[ balance[ acc ] ] ] := "-account-"

Then use this as:

a1 = makeAccount[100]
a2 = makeAccount[150]

balance[a1]

100

deposit[a1, 100]

200

balance[a1]

200

balance[a2]

150

This works because of the unique symbol:

FullForm[a1]

Edit:

Here is a version without SetAttributes

makeAccount1[ initBalance_ ] :=
 
 Module[ { balance = initBalance , withdraw, deposit, amount, 
   dispatch},
  
  withdraw[ amount_ ] :=
   Module[ {},
    If[ balance >= amount,
     balance -= amount; balance,
     Print[ "Insufficient funds" ] 
     ]
    ];
  
  deposit[ amount_ ] :=
   Module[ {},
    balance += amount; 
    balance
    ];
  
  amount[ amount_ ] :=
   Module[ {},
    balance
    ];
  
  dispatch[m_] :=
   Which[
    StringMatchQ[ m, "withdraw" ], withdraw,
    StringMatchQ[ m, "deposit" ], deposit,
    StringMatchQ[ m, "amount" ], amount,
    (* else *)
    True, Print["Unknown request -- MAKE_ACCOUNT ", m]
    ];
  
  Return[ dispatch ];
  ]

Use as follows:

acc = makeAccount1[ 100 ] 
acc2 = makeAccount1[ 200 ] 

dispatch$99 dispatch$100

acc[  "withdraw" ][ 10 ]

90

acc2[ "withdraw" ][ 60 ]

140

acc2["amount"][]

140

Source Link
user21
user21

Here is an idea:

SetAttributes[account, HoldAll ]

makeAccount[ initBalance_ ] :=
 Module[ { balance = initBalance },
  account[ balance ]
  ]

account /: balance[ account[ bal_ ] ] := bal

account /: deposit[ account[ bal_ ], newBal_ ] := ( bal += newBal )

account /: withdraw[ account[ bal_ ], amount_ ] := ( bal -= amount ) /; 
  amount <= bal
account /: withdraw[ account[ bal_ ], amount_ ] := 
 Print[ "Save some cash first" ] /; amount > bal

Format[ acc_account  /; ValueQ[ balance[ acc ] ] ] := "-account-"

Then use this as:

a1 = makeAccount[100]
a2 = makeAccount[150]

balance[a1]

100

deposit[a1, 100]

200

balance[a1]

200

balance[a2]

150

This works because of the unique symbol:

FullForm[a1]