Point of sale (events + OO + logic)
A checkout session as a stream of scan/pay events: the product catalog lives in the object store, and a dairy fact drives the discount rule.
PatLang source
# =============================================================================
# Point-of-sale library (Stage 1 dialect): event-driven checkout combining
# events (scan/pay), OO (product catalog in the object store), and logic
# (dairy facts drive a discount rule). Prices are integer pence.
# =============================================================================
make a function called pos_setup returns done
new("Product", "apple")
send("apple", "set", "price", 30)
new("Product", "banana")
send("banana", "set", "price", 25)
new("Product", "milk")
send("milk", "set", "price", 120)
fact("dairy", "milk", "yes")
fact("dairy", "cheese", "yes")
set_var("total", 0)
set_var("items", 0)
set_var("receipt", "")
goal("serve_customer", "till-1")
return true
end
make a function called pos_scan takes item returns price
let price = get(item, "price")
if not price then
print(" unknown item: " + item)
return 0
end
if query("dairy", item, 0) > 0 then
# dairy discount: 10% off
let price = price * 9 / 10
end
set_var("total", get("__vars", "total") + price)
set_var("items", get("__vars", "items") + 1)
set_var("receipt", get("__vars", "receipt") + " " + item + " " + price + "p\n")
return price
end
make a function called pos_total returns t
return get("__vars", "total")
end
make a function called pos_pay takes tendered returns change
let total = get("__vars", "total")
let change = tendered - total
print("--- RECEIPT ---")
print(get("__vars", "receipt") + " items: " + get("__vars", "items"))
print(" total: " + total + "p, tendered: " + tendered + "p, change: " + change + "p")
return change
end
when scan do
pos_scan(event_data)
end
when pay do
pos_pay(event_data)
end
# Point-of-sale demo driver (concatenate after lib/pos.patlang).
# A checkout session as a stream of events.
pos_setup()
print("scanning...")
emit("scan", "apple")
emit("scan", "apple")
emit("scan", "banana")
emit("scan", "milk")
emit("scan", "unobtainium")
emit("pay", 500)
print("till session complete")
(not run yet)
Native run on the build machine:
scanning... unknown item: unobtainium --- RECEIPT --- apple 30p apple 30p banana 25p milk 108p items: 4 total: 193p, tendered: 500p, change: 307p till session complete