#!/usr/bin/5D -p OPLs/Math.5D
let Composition := requireModule "Composition" in 
Composition.withInterface1 filename
import [(rem)] from Composition in 
let dispatch := Composition.dispatch in 
let raiseMissingSymbolError := Composition.raiseMissingSymbolError in 
let wrap := \class \instance 
	rem "Given a class and an instance, results in a #(Composition.dispatch)er for that class and instance."
	\key class key instance 
in 
let wrap! := \class \instance 
	rem "Given a class and an instance, results in an IO action, that, when executed, #(wrap)s that class and instance."
	(requireModule "IO").liftIO! (wrap class instance) 
in 
let class := 
	rem "Identity function in order to make people feel comfortable."
	\x x 
in 
let Object := class
	let id := \self self in 
	Composition.dispatch (#exports[id])
	raiseMissingSymbolError 
in 
rem '(
"Object-oriented programming is done like this:"
let OO := requireModule "OO" in 
import [Object wrap! (class)] from OO in 
let Widget := class
	...
	(requireModule "Composition").dispatch (#exports[])
	Object
in 
let Button := class
	let click! := \self
		...
	in
	let new! := allocatePointer! ;\ptr
		...
		wrap! ptr
	in 
	(requireModule "Composition").dispatch (#exports[click! new!])
	Widget
in
)
(#exports[(Object) wrap wrap! (class)])