The most simple basic core of the OO extension to Mathematica.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"author"-> | |
{ | |
"name" -> "Leonid Shifrin", | |
"email" -> "lshifr@gmail.com", | |
"url" -> "http://www.mathprogramming-intro.org" | |
}, | |
"name" -> "SimpleOO", | |
"mathematica_version" -> "8.0+", | |
"description" -> "The most simple basic core of the OO extension to Mathematica.", | |
"url" -> "https://gist.github.com/4363437" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* Mathematica Package *) | |
BeginPackage["SimpleOO`"] | |
(* Exported symbols added here with SymbolName::usage *) | |
Object; | |
TypeQ; | |
TypeOf; | |
SuperType; | |
DeclareType; | |
Extends; | |
$self; | |
$content; | |
$super; | |
Begin["`Private`"] (* Begin Private Context *) | |
ClearAll[vtable]; | |
vtable[Object]:=object; | |
ClearAll[instanceValue]; | |
SetAttributes[instanceValue,HoldAll]; | |
instanceValue[_]:= | |
Throw[$Failed, {instanceValue,"invalid_instance"}]; | |
ClearAll[addMethods]; | |
SetAttributes[addMethods, HoldAll]; | |
addMethods[SetDelayed[lhs_, rhs_], rest___][s_] := | |
With[{ff = vtable[s]}, | |
ff[sym_, lhs] := | |
Block[{ | |
$self = sym, | |
$content = instanceValue[sym], | |
$super | |
} | |
, | |
SetAttributes[$super,HoldAll]; | |
$content /: Set[$content, expr_] := Set[sym, expr]; | |
$super[call_]:= vtable[SuperType[s]][sym,call]; | |
rhs | |
]; | |
addMethods[rest][s] | |
]; | |
addMethods[][s_] := | |
vtable[s][sym_, lhs_] := | |
vtable[SuperType[s]][sym,lhs]; | |
ClearAll[defineMethods]; | |
SetAttributes[defineMethods, HoldRest]; | |
defineMethods[s_] := s; | |
defineMethods[s_, args___] := | |
Module[{ff}, | |
SetAttributes[{ff}, HoldAll]; | |
vtable[s] = ff; | |
self : (s[content_]) := | |
Module[{sym}, | |
SetAttributes[sym, HoldAll]; | |
sym /: instanceValue[sym] = content; | |
sym /: Normal[sym] := | |
With[{cont = instanceValue[sym]}, | |
HoldForm[s[cont]] | |
]; | |
(* Note: this forces the arguments to be evaluated *) | |
sym[f_[argums___]] := | |
Hold[f][argums]/.Hold[h_][x___]:> | |
ff[sym,f[x]]; | |
sym /: Set[sym, newcontent_] := | |
sym /: instanceValue[sym] = newcontent; | |
sym/: TypeOf[sym] = s; | |
sym | |
]; | |
addMethods[args][s]; | |
]; | |
ClearAll[SuperType]; | |
SuperType[Object] = Null; | |
SuperType[_] = Object; | |
ClearAll[Object, object]; | |
Object::nomethod = "Unknown method for type Object. The method call was `1`"; | |
SetAttributes[{Object, object}, HoldAll]; | |
Object[__] := object; | |
object[args___,methodCall_] := | |
( | |
Message[Object::nomethod,ToString@HoldForm[methodCall]]; | |
$Failed | |
); | |
ClearAll[TypeQ]; | |
TypeQ[type_Symbol][instance_Symbol]/;TypeOf[instance] === type := True; | |
TypeQ[type_Symbol][instance_Symbol] := | |
TypeQ[SuperType[type], instance]; | |
TypeQ[_][_] := False; | |
ClearAll[DeclareType]; | |
DeclareType[Object] = Null; | |
DeclareType[type_Symbol] := DeclareType[type~ Extends ~ Object]; | |
DeclareType[Object ~ Extends ~ _] = Null; | |
DeclareType[type_Symbol ~ Extends ~ superType_Symbol] := | |
Function[ | |
Null | |
, | |
ClearAll[type]; | |
If[ValueQ[vtable[type]], vtable[type] =.]; | |
SetAttributes[type, HoldAll]; | |
defineMethods[type, ##]; | |
SuperType[type] = superType; | |
type | |
, | |
HoldAll | |
]; | |
End[] (* End Private Context *) | |
EndPackage[] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment