1
$\begingroup$

enter image description here

I'm reading the book

Mathematica® programming: an advanced introduction by Leonid Shifrin

and there is a very nice evaluation. Here is:

This, plus a large number of quite generic and efficient built-in higher-order functions (that is, functions that manipulate other functions) allow for efficient general Mathematica programming techniques. These techniques are not too difficult to learn, and in some sense they split the entire Mathematica language into a "scripting" (quick to write, but often slow to execute), "intermediate" (a bit more thinking but faster code), and "system" (less intuitive thinking, but yet much faster code) language layers

For example, the Pattern Matching style is elegant, short, but often slow. Personally, I didn't use often this type of Pattern Matching. For me, sometime it can cause some confusion.


Let's take this example:

We have a list of data {{x,y},..}. We use the Pattern Matching to make a new list {{x,f[y]},..}. To do this, we can do:

list/.{a_, b_} -> {a, Log[b]}

However, someone can fall in the trap. For me, it's rather dangerous.

If you have a list of 1 point. It works:

{{1, 2}} /. {a_, b_} -> {a, Log[b]}
{{1, Log[2]}}

If you have a list of 3 points. It works too:

{{1, 2}, {2, 4}, {3, 6}} /. {a_, b_} -> {a, Log[b]}
{{1, Log[2]}, {2, Log[4]}, {3, Log[6]}}

But for a list of 2 points, the logic has changed. It doesn't work as intended.

{{1, 2}, {2, 4}} /. {a_, b_} -> {a, Log[b]}
{{1, 2}, {Log[2], Log[4]}}

My question:

I understand this behavior. But it takes me a bit of time to debug this. And I forget this type of "strange" behavior, and I often avoid to use Pattern Matching in Mathematica.

Do you have any example that using the Pattern Matching Style is faster than the classical Functional, or Procedural style?


Good read from Leonid's book:

The part of the difficulty of learning Mathematica programming is that there is no good formal distinction between these layers. Typically, the first is characterized by heavy use of the procedural (or otherwise straightforward) code, the second corresponds to use of functional programming and the third by heavy use of optimized structural operations, but this is not an absolute criteria. One and the same operation can play a "scripting" role in one context and "system" role in another.

For many problems (especially purely scientific), "scripting" layer is sufficient. This layer consists mainly in using built-in commands or gluing them with a typically procedural code. A big part of the bad reputation that Mathematica used to have for its "slow performance" is related to the fact that most people are only aware of this language layer, because it corresponds most directly to their programming experience in other (procedural) languages.

$\endgroup$
7
  • 8
    $\begingroup$ In robust programming, you shouldn't use ReplaceAll much anyway. Replace with a level specification is usually what you want to use instead to avoid these sort of ambiguities. And always make your patterns as specific as possible using names of heads etc. $\endgroup$ Nov 2, 2020 at 20:16
  • 2
    $\begingroup$ In a use case like this it makes sense to specialize the pattern e.g. to {a_,b_?NumericQ} to avoid accidental/undesired matches. $\endgroup$ Nov 2, 2020 at 23:32
  • $\begingroup$ Thank you @DanielLichtblau. +1 $\endgroup$
    – Nam Nguyen
    Nov 3, 2020 at 9:08
  • 1
    $\begingroup$ I think you mixed together two different questions: one on performance, and one on general applicability of rule-based approach for various use cases. The fragments of the book you cited were mostly concerned with performance aspect, and their point was that one has to be considerably more familiar with Mathematica to be able to come up with good performance than simply a quick working prototype, and that rule-based approach makes it easy to write slow code for users who don't have a good understanding of Mathematica's internals and its model of computation. $\endgroup$ Nov 3, 2020 at 13:07
  • 1
    $\begingroup$ As to applicability, my experience is that outside of math / algebraic context, rule-based code at large is useful for either quick prototyping, or in rather sophisticated scenarios where typically the user is an experienced WL programmer and needs to process complex symbolic expressions (such as e.g. syntax trees in the compiler. For instance, the new relational database integration functionality makes heavy use of rule-based code in WL to SQL compiler, which probably saved us a few man-years of work). Rules win big for problems which can be expressed as symbolic expressions transformations. $\endgroup$ Nov 3, 2020 at 13:17

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.