Why Message is not always traced? - wolfram-mathematica

I am still puzzled by the fact that Message is not always traced when switching On[Message] while surely this function is called through the evaluator.
Consider:
In[1]:= On[Message,Plus];
1+1
Sin[1,1]
During evaluation of In[1]:= Plus::trace: 1+1 --> 2. >>
Out[2]= 2
During evaluation of In[1]:= Sin::argx: Sin called with 2 arguments; 1 argument is expected. >>
During evaluation of In[1]:= Message::trace: Message[Sin::argx,Sin,2] --> Null. >>
Out[3]= Sin[1,1]
In[4]:= Unprotect[Message];
Message:=Print[List[##]]&
1+1
During evaluation of In[4]:= {Plus::trace,1+1,2}
Out[6]= 2
It is obvious that Message is called in both cases through the evaluator because the call can be intercepted on the top level. But it is not traced in the case of 1+1. Why?

Related

How can I solve symbolically a polynomial equation in Mathematica if the coefficient of the highest power might be zero?

Assume, I would like to solve the following equation:
ax^2+bx+c=0
with a, b and c being parameters later to be determined, a might be even 0.
My try was the following:
In[1]:= sol = Solve[a x^2 + b x + c == 0, x]
Out[1]= {{x -> (-b - Sqrt[b^2 - 4 a c])/(2 a)}, {x -> (-b + Sqrt[b^2 - 4 a c])/(2 a)}}
Now if I would like to get the solution for the case when a=0, I get an error message:
In[2]:= sol /. {a -> 0, b -> 1, c -> 2}
During evaluation of In[2]:= Power::infy: Infinite expression 1/0 encountered.
During evaluation of In[2]:= Power::infy: Infinite expression 1/0 encountered.
During evaluation of In[2]:= Infinity::indet: Indeterminate expression 0 ComplexInfinity encountered.
Out[2]= {{x -> ComplexInfinity}, {x -> Indeterminate}}
Actually I have to solve a cubic equation, I wrote a quadratic one for the sake of simplicity.

A problem when wrongly using Dot command in Mma

In[1]:= SameQ[Dot[1, 2], 1.2]
TrueQ[Dot[1, 2] == 1.2]
a = 1; b = 2;
SameQ[Dot[a, b], a.b]
TrueQ[Dot[a, b] == a.b]
Out[1]= False
Out[2]= False
Out[4]= True
Out[5]= True
I know this uses Dot command wrong. Anybody can give me a clear reson for the above different results?
thanks!
a.b is interpreted as Dot[a,b] and then variables a and b are substituted, meaning Dot[1,2] and thus equality holds. This is not the same as 1.2 where the dot stands for the decimal separator and not for the inline operator of Dot.
When you write 1.2, Mma understands a number (aka 6/5), but if you write {1, 1}.{2, 2} or a.b Mma understands a scalar product, as usual in any book using vectors.
HTH!
It can be informative to view an expression under Hold and FullForm:
a = 1; b = 2;
SameQ[Dot[a, b], a.b]] //Hold //FullForm
Hold[SameQ[Dot[a, b], Dot[a, b]]]
With this combination of commands, Mathematica parses but does not evaluate the expression (Hold), and then shows the long pseudo-internal form of the expression (FullForm).
In this case, you can see that the second term a.b is parsed as Dot[a, b] before any evaluation happens.
When . appears with numerals as in 1.2 it is interpreted specially as a decimal point. This is similar to other numeric entry formats such as: 1*^6 which is recognized directly as 1000000:
1*^6 //Hold //FullForm
Compare trying to enter:
a = 1;
a*^6

How to intercept assigning new value for the In variable?

I wish to intercept assigning new values for the In variable.
I have tried to do this by defining UpValues for In but it does not help in this case:
Unprotect[In];
In /: Set[In[line_], expr_] /; ! TrueQ[$InsideSet] :=
Block[{$InsideSet = True},
Print[HoldForm#HoldForm[expr]; Set[In[line], expr]]]
In /: SetDelayed[In[line_], expr_] /; ! TrueQ[$InsideSet] :=
Block[{$InsideSet = True},
Print[HoldForm#HoldForm[expr]; SetDelayed[In[line], expr]]]
Is it possible to intercept it?
P.S. This question has arisen as a part of previous question on the stage when Mathematica creates new Symbols.
EDIT
I would wish to intercept explicitly the assignment new DownValue for the In variable. $Pre executes after this assignment and after creating all new Symbols in the current $Context:
In[1]:= $Pre := (Print[Names["`*"]];
Print[DownValues[In][[All, 1]]]; ##) &
In[2]:= a
During evaluation of In[2]:= {a}
During evaluation of In[2]:= {HoldPattern[In[1]],HoldPattern[In[2]]}
Out[2]= a
Have you looked at $Pre and $PreRead?
$Pre is a global variable whose value, if set, is applied to every input expression.
$PreRead is a global variable whose value, if set, is applied to the text or box form of every input expression before it is fed to Mathematica.
UPDATE (now with better example)
In[1]:= $Pre =
Function[{x}, Print["In[",$Line,"] is: ", Unevaluated[x]]; x, HoldFirst];
In[2]:= 2 + 2
During evaluation of In[2]:= In[2] is: 2+2
Out[2]= 4
In[3]:= InString[2]
During evaluation of In[3]:= In[3] is: InString[2]
Out[3]= "\\(2 + 2\\)"
UPDATE 2
Replace $Pre with $PreRead in my code above and you get close to what you want, I believe:
In[1]:= $PreRead = Function[{x}, Print[Names["`*"]]; x, HoldFirst]
Out[1]= Function[{x}, Print[Names["`*"]]; x, HoldFirst]
In[2]:= a = 1
During evaluation of In[2]:= {x}
Out[2]= 1
In[3]:= b = 2
During evaluation of In[3]:= {a,x}
Out[3]= 2
It's not possible to intercept In at the *Value level because the Kernel is simply not interacting with In via value manipulation in "top-level" Mathematica code.

Map (/#) behavior

I guess this is something easy that I'm overlooking is a clear sign of illiteracy, but anyway.
How is that
(Map[Sign, LessEqual[x, y]]) === LessEqual[Sign[x], Sign[y]]
-> True
But
(Map[Sign, LessEqual[-1, -100]]) == LessEqual[Sign[-1], Sign[-100]]
-> False
Using Trace on the lhs will help to show what has happened.
Trace[Map[Sign, LessEqual[-1, -100]]]
Out[2]= {{-1 <= -100, False}, Sign /# False, False}
Notice that Map has no HoldXXX attributes.
Attributes[Map]
Out[3]= {Protected}
So the LessEqual evaluates before Map does anything. At which point you get
Map[Sign,False]
As False is an atomic expression, this just evaluates to False.
The rhs of course evaluates to True, since Sign[-1] and Sign[-100] are both -1.
Daniel Lichtblau
Wolfram Research
Look what happens when you do it in two steps:
In[1]:= LessEqual[-1,-100]
Out[1]= False
In[2]:= Map[Sign, False]
Out[2]= False
The second result there may be surprising, but it happens to be how the Map function works; if you use Map on an expression with length 0 (like the symbol False), it just returns that expression unchanged. Another example:
In[3]:= Map[f, "Pillsy"]
Out[3]= "Pillsy"
On the other hand, obviously
In[4]:= LessEqual[Sign[-1],Sign[-100]]
Out[4]= True

How should I write a function to be used in Apply in Mathematica?

I am wondering how I can write a function to be used in the Apply function in Mathematica? For example, I want to trivially re-implement the Or function, I found the following
Apply[(#1 || #2)&,{a,b,c}]
is not okay since it only Or'ed the first two elements in the list. Many thanks!
This will work, no matter how many vars, and is a general pattern:
Or[##]&,
for example
In[5]:= Or[##] & ## {a, b, c}
Out[5]= a || b || c
However, in the case of Or, this is not good enough, since Or is HoldAll and short-circuiting - that is, it stops upon first True statement, and keeps the rest unevaluated. Example:
In[6]:= Or[True, Print["*"]]
Out[6]= True
In[7]:= Or[##] & ## Hold[True, Print["*"]]
During evaluation of In[7]:= *
Out[7]= True
This will be ok though:
Function[Null,Or[##],HoldAll],
for example,
In[8]:= Function[Null, Or[##], HoldAll] ## Hold[True, Print["*"]]
Out[8]= True
and can be used in such cases (when you don't want your arguments to evaluate). Note that this uses an undocumented form of Function. The mention of this form can be found in the book of R.Maeder, "Programming in Mathematica".
HTH
Or ## {a, b, c}
Equivalent
Apply[Or, {a, b, c}]
Equivalent
{a, b, c} /. {x_, y__} -> Or[x, y]
Apply works like this:
{2 #1, 3 #2, 4 #3} & ## {a, b, c}
{2 a, 3 b, 4 c}
Plus[2 #1, 3 #2, 4 #3] & ## {a, b, c}
2 a + 3 b + 4 c
Are you sure you are expecting the right thing from Apply? If you look in the documentation, http://reference.wolfram.com/mathematica/ref/Apply.html, you will see that Apply[f,expr] simply replaces the head of f by expr. It does not, in general, give f[expr].
If you wish to operate with function f onto expr, try f#expr or f[expr].
Perhaps you understand the above and your question really is, "how do I define some f that, when I do Apply[f,{a,b,c}], does the same job as Or[a,b,c]. Is that it?

Resources