# UpValues evaluation with Dot operator

I would like to simplify some database notation, and I'm doing some tests with UpValues for that.

For example, if I set this Upvalue fot tab1:

tab1 /: tab1.column1 = 1


When I evaluate

tab1.column1


I get 1 as expected. But if later I set column1 = "x", when I evaluate it again, I get tab1."x" instead of 1 as I need.

There is some way that I can change this behavior? So I could get 1 and prevent variables name conflict?

Update

To avoid misinterpretation here is the evaluation sequence.

Quit the kernel and evaluate:

tab1 /: tab1.column1 = 1;
column1 = "x";
tab1.column1


The result is tab1."x" in the first evaluation.

-
I get 1, as expected, in version 9.0.0 (Windows Vista). – kglr Feb 4 '13 at 0:00
@kguler Hi.. Strange behavior... see post update. – Murta Feb 4 '13 at 0:21
I can't reproduce either of the reported behaviors. On OS X, V9.0.0, I get tab1."x" for all evaluations of tab1.column1. That's what I would expect because I think the ownvalue for column1 is in inserted into Dot before tab1 is checked for upvalues. – m_goldberg Feb 4 '13 at 0:59
@m_goldberg it's this. The if you do Unprotect@Dot; SetAttributes[Dot, HoldAll] it will works as I need, but now I'm looking for some way to do that without use Unprotect@Dot (I don't know if it's possible). Another test is tab1.Unevaluated@column1. Tks. – Murta Feb 4 '13 at 1:06
@Murta Very closely related (perhaps a duplicate?): mathematica.stackexchange.com/questions/4161/… The trick is to create a localized scope for the modifications using InternalInheritedBlock – Ajasja Feb 4 '13 at 12:58

You could do:

Unprotect[Dot];
SetAttributes[Dot, HoldAll]


Then

   tab1 /: tab1.column1 = 1 ;
column1 = "x";
tab1.column1


returns 1

Is this what you want?

-
Yes!.. it's this! But it's safe? There is some way to do it in the moment of define the UpValue, (without change Dot)? – Murta Feb 4 '13 at 0:31
I was thinking in something like tab1 /: Dot[tab1, x_] := Dot[tab1, Unevaluated@x] but it does not works. – Murta Feb 4 '13 at 0:53
It's safe. But why do you really want to do this? I would rather invent new Mathematica or DatabaseLink - like functions to do what you want. – Rolf Mertig Feb 4 '13 at 1:10
You can see the application in the Updated part of this post. I really don't like the way I handle database table today. I'm seeking some way to make the code better. – Murta Feb 4 '13 at 1:23
Hi Rolf!.. I just discovery that Unprotect Dot is dangerous. Today I discovery that DateRange do not work if we set SetAttributes[Dot, HoldAll] – Murta Feb 4 '13 at 14:07

You could introduce your own notation. Something like the following.

SetAttributes[qualifed, HoldAll]
Needs["Notation"]
Notation[ParsedBoxWrapper[
RowBox[{"u_", "∘", "v_"}]] \[DoubleLongLeftRightArrow]
ParsedBoxWrapper[RowBox[{"qualifed", "[", RowBox[{"u_", ",", "v_"}], "]"}]]]
TagSetDelayed[qualifed, qualifed[u_, v_] = val_, TagSet[u, qualifed[u, v], val]]

tab1∘col1 = 1; tab1∘col1


1

col1 = 42; tab1∘col1


1

tab1∘col1 = 42; tab1∘col1


42

I'm using \[SmallCircle] (∘) in place of dot (.). It can be entered with [esc]sc[esc]. I've tested this only a little. I'm not sure it's foolproof.

-
Interesting approach. Tks! – Murta Feb 4 '13 at 4:03

Are you sure you're not looking for this:

tab1 /: tab1.column1_ := 1;


That is whatever column1 binds to rather than the literal column1?

this way

tab1."x"


evaluates to

1

-
Today I know that use columns names as symbol instead of strings create a lot of troubles. But tks +1 – Murta Dec 31 '14 at 10:36
But this approach would also work with symbols: tab1.anothercolumn evaluates to 1 as well – Carlo Dec 31 '14 at 10:38