Re: Understanding Mathematica's evaluation procedure
- To: mathgroup at smc.vnet.net
- Subject: [mg117421] Re: Understanding Mathematica's evaluation procedure
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Fri, 18 Mar 2011 05:59:13 -0500 (EST)
Alexey, > As I understand, by default no replacement rules are associated with > these functions, and they work "themselves". > > I was always confounded by this aspect of the system. The edge between > replacement and "the true functions which do the job" always remained > stumbling-block for my understanding. > > Can anybody clarify this moment? > My understanding is that there isn't much mystery here. Many built-in functions in Mathematica can work with both symbolic and numeric arguments. The symbolic part is governed by rules, just as for the user-defined functions. Some of these rules are written in the top-level Mathematica and can be inspected. Most are written on the system level and can not be inspected, but they are still replacement rules. So, many functions in Mathematica are inter-connected with a large number of rules governing their symbolic relationships, simplifications etc. On numerical (or, generally, atomic) arguments, the rules may just invoke the implementations that would return a number, list of numbers, etc. Here is an example to illustrate: we define our own sine function, and add just one simplification rule, as follows: Clear[sin]; sin[x_ + y_] := sin[x]*cos[y] + sin[y]*cos[x]; sin[x_?NumericQ] := sinC5[x]; where sinC is a Compiled to C function retaining only the first 5 terms of the sine expansion (to keep everything within a machine precision - my point here is just to illustrate): sinC5 = Compile[{{num, _Real}}, Sum[(-1)^k num^(2 k + 1)/(2 k + 1)!, {k, 0, 5}], CompilationTarget -> "C"] Now, when we call: In[162]:= sin[a + 1] Out[162]= 0.841471 cos[a] + cos[1] sin[a] So, what happened is that when the rule matched for a numeric argument, it *invoked* a lower-level C function which did the computation. The system functions work in a very similar way - the rules are applied, and when they match on "terminals" - lower-level function calls, they invoke them and substitute back the result of their evaluation. Apart from the somewhat special way that the rules work (the main evaluation loop), what happens here is no different from what happens in any language interpreter. You need a way to map your higher-level language statements and expressions onto an "instruction set" available to you in the implementation language. What makes Mathematica perhaps really different is that some computations may be purely symbolic and involve only simplifications based on rules (term rewriting), which is indeed probably not how most programming languages work. Regards, Leonid