Skip to content

Instantly share code, notes, and snippets.

@lshifr
Last active December 10, 2015 01:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lshifr/4363437 to your computer and use it in GitHub Desktop.
Save lshifr/4363437 to your computer and use it in GitHub Desktop.
The most simple basic core of the OO extension to Mathematica.
{
"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"
}
(* 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