11

I was wondering how to do it in general, what are the best strategies etc. I have seen some solutions and some of them look really hard/tedious to use. The one I worked on used pure functions to implement object functions and heads like OBJECT[]. It was very hard to use on the class coding side. I got dizzy when defining functions and constructors (especially the inheritance part was tough).

So the emaphsis of my quesiton is on the elegenace of the coding part of a class. Ideally, I am looking for something that would work as follows. First, we define a class, e.g. car as follows:

beginClass["vehicle"];
   public startTheEngine;
   private fuel;
   vehicle[args_]:=Block[{},...];
   startTheEngine[thrust_]:=Block[{}...];
endClass

beginClass["car", "vehicle"];
public TurnTheRadioOn;
private frequency;
car[args_] := Block[{...},];
TurnTheRadioOn[]:=
   Block[{},
      use private variable frequency
   ]
endClass;

Please note that it is very important that private/public functions are defined almost as in a "normal" mathematica code. This would the main requirement so to say.

The class would be used as

car1 = newObject["car", args];
car1.StartTheEngine[];
car1.TurnOnTheRadio[];

I am curious what is that one has to think about? To consturct something like the above probably involves many aspects of Mathematica, e.g. how would one fix the "." syntax etc. If you suggest an existing package I would be grateful if you could comment on how it works in principle.

My naive expectation is that the encapsulation part could be fixed by BeginPackage constructs. All objects could be stored in namespaces specifically designed for each class. I presume that objects would look like

car1 = OBJECT["car"][fuel$1,frequency$1,....];
car2 = OBJECT["car"][fuel$2,frequency$2,....];

I presume one would have to construct something like a compiler that would convert the class definition code above into the class .m file. Also, to some extent, the second main issue is how to construct such a compiler.

Regards Zoran

p.s. The reason why I am asking this is that I really had a need for something like this many times.

zorank
  • 281
  • 2
  • 7
  • 1
    Note that if one is only looking for `Struct`-like abilities (i.e., the ability to access data using names such as `dataAboutBob[["weight"]`), then the [`Association`](http://reference.wolfram.com/language/ref/Association.html) structure added in Mathematica 10 can be used. [More here](http://stackoverflow.com/a/33465106/330202). – Jess Riedel Nov 01 '15 at 17:53

2 Answers2

15

The Mathematica language is optimized for the symbolic programming paradigm, and provides the most leverage and convenience when one stays within that paradigm. Object-oriented programming is a significant departure from the symbolic paradigm, and one ends up having to write most of the supporting infrastructure from scratch. There is nothing inherently wrong with that, of course, but it would be much less effort to exploit the J/Link facility and write OOP code in Java. The Wolfram Workbench makes it easy to mix Mathematica and Java code.

It would be fruitful to think about what requirements are driving one towards an OOP solution. The question suggests that the interest is in how to simulate structure types, but perhaps there are other concerns like encapsulation and polymorphism. It seems there is scope for some more specific follow-up questions along the lines of "What is the Mathematica equivalent of the object-oriented idiom X?".

OOP Considered Harmful?

Within the context of Mathematica, object-oriented programming might even be considered harmful. OO emphasizes the creation of "black box" objects whose internals are inaccessible to outside callers. While this has obvious benefits for complexity control through information hiding, it does fly directly in the face of the power of symbolic programming. Mathematica emphasizes synergy between seemingly unrelated components by allowing the symbolic representation of one to be transformed into the symbolic representation of the other. A "black box" does not play well in this ecosystem. As a concrete example, contrast the difference between Graphics "objects" and the new V8 Graph objects. The latter take a somewhat OO approach -- generating some negative feedback in the community.

None of this is to say that OO is intrinsically harmful. The point of this discussion is that OO is foreign to the Mathematica ecosystem and that by taking that design choice, one might rule out some desirable synergies in the future. Take that decision consciously.

Community
  • 1
  • 1
WReach
  • 18,098
  • 3
  • 49
  • 93
  • +1 - Very good points. I actually would not mind having a natively supported OO in mma, but I never felt in a desperate need of things like inheritance or polymorphism given other means available in mma, such as closures, higher order functions, rules and patterns, and evaluation control. At the same time, I used them quite a bit in Java. May be it is just because the problems I was solving in mma and Java were substantially different, but I suspect it is more the case for the Sapir-Whorf hypothesis at work. – Leonid Shifrin Sep 11 '11 at 15:19
  • 1
    @Leonid. I too find spend quite a bit of time in Java and sometimes an OO solution leaps to mind for particular problems in Mathematica -- a solution that is hard to realize in that context. On the other hand, consider the newly added section to my response: _OOP considered harmful?_ – WReach Sep 11 '11 at 18:23
  • 1
    Another excellent point! I have similar feelings, but wouldn't be able to articulate this so well. Would vote again if I could. But also, my feeling is that certain problems *may* benefit from OO, if they have the "right degrees of freedom" for that. If one manages to decouple those from the rest (where symbolic nature of mma is more important), then applying OO to such "islands" in the code may work well. With the graphs, I just feel that OO style (paradigm) was applied to the "wrong degrees of freedom". – Leonid Shifrin Sep 11 '11 at 18:46
  • 1
    continuing... I would rather apply OO to some less algorithmic and more ad hoc stuff, characteristic of commercial (special - purpose) systems and their frequently changing requirements, which often have more to do with business than technology. Having OO natively supported in mma would allow to build such systems much easier without leaving mma, which may make mma more attractive for developers. – Leonid Shifrin Sep 11 '11 at 18:48
  • @Leonid. Totally agree with the correct addition of OO paradigm to Mathematica. Let's not forget that one, relatively new, very fast growing technical computing software offers OO, and some point it as a strong benefit when compared with Mathematica. It just needs to be very well thought, to mix it up with all the other paradigms. – P. Fonseca Sep 11 '11 at 19:36
  • @P.Fonseca I also think so. But, as WReach argued in this excellent answer, doing it right is a highly non-trivial task for Mathematica, more so than for most other systems. – Leonid Shifrin Sep 11 '11 at 20:45
  • @WReach: I did stumble accross a need to use OO paradigm now and then. The problem is real... – zorank Sep 11 '11 at 21:40
8

I refer you to this post of mine where I discuss one way to implement something similar to what you ask for. This will not give you an object system, inheritance or polymorphism characteristic of OO, but from your formulation it looks like you are looking more for the means to construct ADTs (Abstract Data Types), than the full-fledged OO extension. For a non-trivial example of use of mutable data structures constructed in that way, you may look here.

As far as OO in Mathematica is concerned, you may also look at some relevant past discussions, both on SO and on MathGroup. I am aware of this one, where I contributed a reply and expressed some of my thoughts on the matter. You may also find this very recent SO question and the link it provides to past discussion on structs in Mathematica interesting.

Community
  • 1
  • 1
Leonid Shifrin
  • 22,449
  • 4
  • 68
  • 100
  • Thanks. will check. Please see the edit/changes. It would good to have full OO, if possible. Just for the discussion sake. If it turns out mission impossible in this form then one can try to simplify. – zorank Sep 09 '11 at 14:53
  • @zorank I see. But adding true inheritance / polymorphism / subclassing / subtyping can really be a can of worms. There are many ways to do it and only a few to do it right / well. You will have to think about rules for overriding methods and fields and/or accessing parent's methods and fields, the order of constructor invocations, coding dynamic function dispatch, and lots of other stuff. Are you sure you will need OO - type inheritance / polymorphism all that much? Mathematica provides other means to achieve the same end result, such as patterns and pattern-based function dispatch. – Leonid Shifrin Sep 09 '11 at 16:11
  • If all you have is a hammer, you will see nails everywhere. But that is far better than trying to teach a screw to obey `this.fasten(tight)` – Dr. belisarius Sep 09 '11 at 19:20
  • 3
    @belisarius Agree :) But OTOH, I *do* benefit from past OO experience very much these days even when not writing OO code. I think it emphasizes some generally good practices of thinking / designing before coding, information hiding and separation of concerns. It's all too easy with FP to always follow a temptation to only design bottom-up, which IMO is not always a good idea. – Leonid Shifrin Sep 09 '11 at 22:36
  • 1
    @Leonid Of course I can see the advantages of top down design (and thinking), but OO is not the only paved way to structured design/thinking. I believe that trying to surf the OO wave without the proper tooling (and sometimes _with_ it) could be daunting, to say the less. For example, some numerical methods are usually much easier to think of in iterative terms than for example, functional and/or term/rewriting ways. You will always need `Table`, which is procedural `For` in disguise, which have an '+1 ... goto` showing just under the hood. So, modern software engineering (I think) should ... – Dr. belisarius Sep 09 '11 at 23:20
  • ... be kept into its nice and proper domain – Dr. belisarius Sep 09 '11 at 23:21
  • @Leonid: You are perfectly right. Full OO seems way above my head. Back to abstract data types then. How would one implement those in a smart way? – zorank Sep 11 '11 at 21:41
  • @zorank Well, in my answer above I gave some links to my past SO and Mathgroup posts where I demonstrated this. Once you tell me what you think is missing in the method I exposed, I may be able to improve it to meet your needs. One thing which I am sure of is that one can implement a kind of code-generator (the "compiler" that you mentioned) to generate the implementation code similar to the one I described in the mentioned links, from a much simpler specification similar to what you suggested. If this interests you, I will roll something out whenever I get time, some time soon. – Leonid Shifrin Sep 11 '11 at 22:47
  • @Leonid: That was really kind of you. I will do my homework and get back to you. Many thanks! Also, I presume that once ADT is in place one can try to extend the platform. It is better to begin with something concrete. Can't do it at work, of course. Will print out the material and study it in the evenings. – zorank Sep 12 '11 at 09:10