38
$\begingroup$

Which Object-Oriented Paradigm (OOP) approach to use in Mathematica for:

  • general implementation, or

  • a particular project?

There are a lot of related questions and answers in MSE on doing OOP that concentrate mostly on the "How?" but not on discussing "Why/which OOP approach?" (Or "What are the pre-conditions and consequences of using ...?")

Here is a mind-map that shows a way to compare the proposed OOP implementations and styles. (The image links to a PDF that has clickable hyperlinks.)

OOP in Mathematica approaches

It is probably best the responses of this question to be summarized in a comparison table with columns and rows derived/related to that mind-map.

Links

Here is a link to a PDF of the mind-map with clickable/linked references also given below.

Core concepts of the implementations

Objects Pure objects
  • ClasslessObjects, Jakub Kuczmarski, (2014), GitHub, MSE

  • JavaScript style

Struct object
  • MTools, Faysal Aberkane (2016), GitHub, MSE
Associations Rules
  • “The Mathematica Programmer: Object-Oriented Programming”, Maeder (1990), WLA
Classes (types)
  • Type declarations, Leonid Shifrin (2012), MSE
Object-oriented design patterns
  • “Implementation of OOP Design Patterns in Mathematica”, Antonov (2016), GitHub, WordPress

  • Uses the same approach to classes as Leonid Shifrin’s

Signature overloading Modeling interactions between classes / objects UML diagrams
  • … included since it emphasizes the necessity of big-picture view in OOP designs
  • “UML diagrams creation and generation”, Antonov, (2016), GitHub, WordPress

Comparison table (example)

\begin{array} {|r|r|} \hline \textbf{Approach} & \textbf{Core concepts} & \textbf{Properties} & \textbf{When to use?} & \textbf{Why use it?} \\ \hline ClasslessObjects \\ \hline MTools \\ \hline Class \; types \; definitions \\ \hline ... \\ \hline \end{array}

$\endgroup$
  • 3
    $\begingroup$ SciDraw is a very nice package for making publication quality figures. It is based on an (unpublished) OOP framework. While the framework is unpublished, the code is well commented. This project is fairly unique because it does use OOP extensively while being one of the largest and most complex freely available Mathematica packages. There are many discussions of OOP in M, but not many truly large scale applications. $\endgroup$ – Szabolcs Jul 4 '16 at 16:05
  • 2
    $\begingroup$ One problem with SciDraw is that it is quite slow. I don't know if that has anything to do with the OOP framework. It could be, but I suspect option handling to be the culprit instead. Anyway, performance should be a prime concern for any OOP framework which aims to be usable in a large project. $\endgroup$ – Szabolcs Jul 4 '16 at 16:07
  • 4
    $\begingroup$ I should say that I have another version of OOP in the works, which I have been using for my purposes for some time, and which builds on my earlier developments. This new version will arguably be much more "grown-up" version, suited for production. I should be able to publish it relatively soon. $\endgroup$ – Leonid Shifrin Jul 4 '16 at 16:42
  • 4
    $\begingroup$ To the people who voted or consider voting to close the question as too broad. The question in the title is broad, but examine the mind-map. The comparison proposed there narrows down the question fairly well. The question can be answered with specific prescriptions of when and why for at least several of the approaches listed in it. $\endgroup$ – Anton Antonov Jul 5 '16 at 10:14
  • 1
    $\begingroup$ @Eric I think there is a still good reason to have proper OOP to work with, as otherwise one will be simply adapting oop-like features with Association all the time. Fortunately as you mention OOP implementations are now pretty easy with the advent Association. $\endgroup$ – b3m2a1 Jul 21 '17 at 6:21
8
$\begingroup$

Faithful OOP vs. Association

So per @AntonAntonov's suggestion I'm going to chime in on OOP vs. Association. In a comment, @Eric notes that:

"By the way, with the Association, namespace mechanism and the highy flexible rule-replacing system(contain functional programming as its small feature) in Mathematica, I roughly guess that there would be no need to think with or implement OOP anymore."

While this is partially true, I think there are a few things to consider (and note that I'm not really a programmer, so I might be spouting garbage here):

  • OOP is a paradigm, not a framework, so OOP can still be useful even if an OOP-framework is less useful that it would once have been
  • OOP and Association are fundamentally complementary

I think that last point bears some discussion, and to ground it, I'll disclose that I am biased, as most of my user-accessible code in Mathematica is object-oriented in some way. It might be code-as-data level psuedo-OOP, it might be true mutable OOP, but the paradigm is simply too useful to abandon altogether.

To start, let's consider struct-level OOP. Association makes this super easy. Just do something like:

<|
 "Username"->"b3m2a1",
 "Password"->"uh-oh-security-leak"
 |>

and you have a struct. I use this type of deal a bunch, for example here to represent notebook tabs in the TaggingRules.

To make this more useful, maybe we'll take our OOP one step further and attach some head to it, to make it a code-as-data level object:

CoolAppUser[
 <|
  "Username"->"b3m2a1",
  "Password"->"uh-oh-security-leak"
  |>
 ]

Then we can stick Format code on CoolAppUser and UpValues and junk like that. This is a powerful tool, and one of the most common ones I use.

This is most useful when you don't need to mutate your data. Generally you can get away without mutability, but sometimes it's just too useful to do without. And here's where you generally need some form of OOP framework. And here is also where we should take a detour to look at the (other) favorite language of jokes and hacks like me, python.

OOP association-wise in Python

Python is a fully-OOP language. With perhaps the exception of the most primitive of primitives, there is nothing but OOP in python. And what do python's objects look like in practice? Glorified hash-maps, which are implemented in Mathematica as associations. And if you pretty much just copy python's structure but copy it over to Mathematica, it's easy and powerful. And if you take some time to optimize, that's even better. To give a sense of just how easy, over about a year-and-a-half I've implemented 4 or so such frameworks.

Concrete implementations

The basic idea I've used is either that you make a wrapper head that holds a Symbol that can be mutated or, as I've been doing recently, making a single centralized holding symbol that tracks object and type data in a core Association and making a head that holds a pointer to an entry in that. I've found the latter to be somewhat more efficient and manageable. Note that we can do this in either a typed or untyped manner.

We need some mutability, but since we're working with a Symbol in either case we can get that out of a combo of AssociateTo and Set / SetDelayed. We can even vectorize the AssociateTo for efficiency.

And this truly is useful. It's got overhead for sure, it's relatively slow, yes, but as with everything Mathematica, if you know how to use it right, it can take you far. I use one such framework in a large chemistry package of mine, I used another version in a now-abandoned set of classes for a specific type of QM computation with random additions for databases and parallel objects and junk, and I developed one just as an exercise which I'm gonna get around to putting through its paces at some point.

Remarks

  • Just to comment on Anton Antonov's first question, I think if some OOP framework were integrated into the language it would be incredible, but I also totally understand why WRI doesn't put it in.

  • Additional comparison between Association and OOP over handling of "global" variables can be seen in this MSE answer of "Functions with changeable global variables".

Related

I made another few implementations here and here for the question How can I implement object oriented programming in Mathematica?

$\endgroup$
  • $\begingroup$ This is good -- thanks for answering. Some experienced Python users do say that the Object-Orientation (OO) is kind of forced in Python or bolted-in. That aligns with your explanations that OO in Python is done by glorified hash-maps. $\endgroup$ – Anton Antonov Aug 7 '17 at 13:57
  • $\begingroup$ @AntonAntonov Thanks, the extra structure is welcome. While I would agree the Python OO isn't as strongly bound as it is in, say, Java, I do think it's an effective approach for dynamic languages such as Mathematica. $\endgroup$ – b3m2a1 Aug 7 '17 at 19:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.