# Tag Info

61

Leaving the general discussion on design patterns for some later time, I will try to collect a comprehensive information on some specific design patterns / idioms, one pattern per post. This time it will be memoization Basic memoization What is memoization Memoization is a technique which enables a program to reuse parts of computations it has done ...

53

It is a simple way to implement Memoization. The trick is that if you define a function as f[x_]:=f[x]=ExpensiveFunctionOf[x] then when you for the first time call e.g. f[3], it will evaluate as f[3]=ExpensiveFunctionOf[3] which will evalulate the expensive function, and assign the result to f[3] (in addition to giving it back, of course). So if e.g. ...

48

Memoization is perhaps the most common application, but it is not the meaning of that construct. More generally it is a construct for a function that redefines itself. This has many uses beyond memoization. Consider this function: f[y_] := (f[y] = Sequence[]; y) It is used to remove duplicates in a list. When the function is first called with a ...

43

This answer may be unacceptable right from the outset because it uses undocumented functions. However, it has advantages over some of the approaches suggested so far which might be redeeming enough in certain scenarios to recommend it in practice. In particular, it provides totally encapsulated state (unlike, e.g., DownValues or Temporary symbols) and O(1) ...

42

Update: Mathematica 10 has introduced Association, which can be used as a close equivalent of structs. params = <| "par1" -> 1, "par2" -> 2 |> params["par1"] (* ==> 1 *) In version 10 pure functions can have named arguments, and can be effectively used as expression templates where the slots can be populated from an association. This is ...

30

There were several attempts to emulate structs in Mathematica. Emphasis on emulate, since AFAIK there is no built - in support for it yet. One reason for that may be that structs are inherently mutable, while idiomatic Mathematica gravitates towards immutability. You may find these discussions interesting: Struct-data-type-in-mathematica ...

28

Linked lists: general discussion I would like to describe here a pattern which is IMO quite important yet seems to be generally under-appreciated and under-used in our community (and probably in Mathematica programming in general) - namely, linked lists. Linked lists are important for several reasons. Here is a (partial) list of benefits they can bring to ...

28

Using symbols to store data and object-like functions Here are interesting functions to use symbols like objects. (I originally posted these thoughts in What is in your Mathematica tool bag?). The post has grown quite big over time as I used it to record ideas. It's divided into three parts, one describing the function Keys, another one where properties ...

27

It's ... oh, why not let the docs speak: tutorial/FunctionsThatRememberValuesTheyHaveFound (in Doc center) Edit You may also find additional information by searching for "memoization" on this site. This has always been a great trick to avoid having to re-evaluate the result of a computationally intensive function call. In the above link, it is also used ...

26

This is my first reply in this group. So please bear with me if I make any mistake, it would not be intentional, just lack of familiarity with the rules. Although the replies above mention important aspects, I generally like to view things from alternative perspectives. I'd like to offer a few of those on this question. Understanding is enhanced by viewing ...

21

"Design patterns" are a standard approach to a class of problems. They may become idioms if the community adopts them. They may be simple, but non-trivial to figure out and identify (for oneself) as a pattern worthy of re-use. Here's one particular pattern I personally like to use: Example: the "TransformBy" approach There are functions which transform ...

19

The answers already posted show that built-in Mathematica functionality can be used to get the meaningful functionality provided by a C struct. If you want your code to be readable by other Mathematica users, I suggest using a list of rules as already advised above. However, if you really want struct-style syntax I'll offer an implementation that I've ...

17

At the risk of repeating myself, I would like to stress that one has to be critical towards the superficial flexibility offered by Mathematica, when (particularly mutable) data structures are concerned. Using mutable data structures assumes a programming style for which Mathematica is not optimized. It can emulate it, yes, and we have seen a number of such ...

17

It is probably debatable to what extent it has built-in object oriented features. In any case, this answer is not intended to lead you to try to emulate object oriented programming, which is in general a bad idea. (see @Leonid 's answer) However, it is not debatable that Mathematica is tremendously flexible (as to style and notation at least, the evaluation ...

16

This is just a beginning of some notions of what the patterns of Mathematica programming might be. Others should feel free to add or correct anything here. It might well be that I've simply misunderstood what patterns in software development really are. Pattern-based overloading to create polymorphous functions It's pretty common to use Mathematica's ...

16

So the naive way to set up a data structure like struct is, as the OP suggested, to simply used DownValues and/or SubValues. In the below, I use SubValues. Copying the Wikipedia C language struct example struct account { int account_number; char *first_name; char *last_name; float balance; }; struct account s; // Create new account labelled s ...

15

It also has another practical side. If you have a random function, which you only want to evaluate once, but you don't know where exactly it will be evaluated or you want to declare it before the parameters it depends on are defined, and you want it to be the same after the first evaluation, for any subsequent call, you can use the memoization trick: ...

15

I arrived very late to this party and I'm very much afraid that nobody comes here anymore. Still I'm posting this in hope that an occasional visitor may find it a practical approach to implementing data structures with named fields within Mathematica. The concept The idea is to use protected symbols to name a structure and its fields. The symbol that names ...

14

I think the simple answer is, there isn't one, but you could always just use UML itself, particularly for behavioral diagrams, even if the code isn't object oriented. You wouldn't use class or object diagrams, but there is nothing to stop you from using, say, a component diagram. You may find the tutorial and white paper on building large software systems ...

13

As Michael Pilat explained here it is more robust to use MakeBoxes, rather than Format. Using MakeBoxes: MakeBoxes[diag[m_?MatrixQ], _] ^:= InterpretationBox[RowBox[{"diag", "[", #, ",", #2, "]"}], diag[m]] & @@ ToBoxes /@ {Dimensions[m], Diagonal[m]} Here is a definition for handling Part extraction: diag[m_?MatrixQ][[part___]] ^:= m[[part]] ...

11

The "unnecessary" complication is needed for those cases where you specify deeper levels than the first: MapIndexed[f, {{a}, {b}}, {2}] (* {{f[a, {1, 1}]}, {f[b, {2, 1}]}} *) The following code produces what you want: myMapIndexed[f_, l_] := Inner[f, l, Range[Length[l]], List]; myMapIndexed[f, {a, b, c, d}] (* {f[a, 1], f[b, 2], f[c, 3], f[d, 4]} *)

7

Although some of the techniques below use the core language, they could nonetheless be new to a beginner or intermediate Mathematica user. Many illustrations can be found in my answer here: Where can I find examples of good Mathematica programming practice? that collects interesting questions and answers, I'm just trying to summarize here some techniques I ...

7

The answer to the more general question of how necessary "software architecturizationing" is in Mathematica is, in short: Not that necessary. The reason is basically 1) lists 2) dynamic typing and 3) lists + dynamic typing. For example, Mathematica doesn't need classes/OO because lists allow you to represent a huge swath of data structures. You would gain ...

6

One of my favorite Mathematica paradigms is what we used to call "self modifying code." Back in assembly language days (before the dinosaurs) this was considered a VERY BAD THING and was discouraged -- many modern languages forbid it. But it's a normal and common part of the Mathematica syntax. For example, say you need to implement a filter on an image, but ...

4

Well that's a hairy one. I like it though, as it forced me to think about aspects of evaluation that I am normally oblivious to. Unfortunately that thinking didn't lead to any great insights. My only idea so far is to interrupt evaluation and mess with the Stack as Leonid did for How do you set attributes on SubValues? I have little experience in this ...

4

How about the old Gayley-Villegas trick? Obj /: (lhs_ = Obj[id_]) := Block[{$inSet = True}, lhs /: (lhs["Property"] = value_) := setObjProperty[id, value]; lhs /: Unset[lhs] := ClearAll[lhs]; lhs = Obj[id] ] /; ! TrueQ[$inSet] Then we get the following behaviour: obj = Obj[1]; UpValues[obj] {HoldPattern[obj["Property"] = value\$_] ...

4

From a first look, late at night. In the third panel of code, aren't all of the terms really parts of a list p, and should therefore be written as p[[1]], p[[2]], etc., rather than p[1], p[2], etc. The paired single square brackets would surround the argument(s) of a function, e.g. Sin[x] or Sqrt[x]; paired double square brackets designate an element of a ...

4

Necessary? No they are not necessary, but they are extremely useful, just as in any other programming system. I would say that the abstraction level of a programming language has no effect on the usefulness of design patterns. There must be hundreds, perhaps thousands, of Mathematica design patterns. I recently answered a question concerning table ...

4

I don't know a way with subvalues, but you can use Module to create objects without explicit identifier in makeObj: makeObj[] := Module[{field = 0}, Switch[#, "increase", field++; #0, "field", field]&] (Note that I slightly changed your "increase" function to return #0, that is, "self", so I can chain ...

Only top voted, non community-wiki answers of a minimum length are eligible