# Tag Info

31

Update It turns out that the correct way is to use ExtendedDefinition, not ExtendedFullDefinition. Please see the answer by @jkuczm for a detailed explanation. This is a simplification of your solution: LanguageExtendedFullDefinition[new] = LanguageExtendedFullDefinition[old] /. HoldPattern[old] :> new I believe LanguageExtendedFullDefinition ...

27

Yes, UpValues are certainly useful in that you can bind definitions and custom behaviours to the symbol rather than the operator. For instance, I can define (a simple, silly example): g /: g[x_] + g[y_] := g[x] g[y] to actually multiply the two when I add them. This definition is now stored in: UpValues[g] (* {HoldPattern[g[x_] + g[y_]] :> g[x] g[y]} *...

14

Oh yes. UpValues are used quite a bit. There are several common uses, and you may have a look at this and especially this question and answers therein to see some sample uses. As for practical uses: I will just mention a couple of examples for what I consider to be the main practical use: overloading functions (system or user-defined) on custom data types, ...

14

UpSet and UpSetDelayed make multiple assignments: UpSet associates an assignment with all the distinct symbols that occur either directly as arguments of lhs, or as the heads of arguments of lhs. f[a[__], b[__], c[__]] ^:= "UpValue" UpValues[a] UpValues[b] UpValues[c] {HoldPattern[f[a[__], b[__], c[__]]] :> "UpValue"} {HoldPattern[f[a[__], b[...

12

I think the reason, at least primarily, that it works differently for Plus is the following from its documentation: Unlike other functions, Plus applies built-in rules before user-defined ones. It may seem a little obscure, because perhaps we don't know all the rules, but these two are mentioned explicitly: Plus[] is taken to be 0. ...

12

Assignments to MakeBoxes and Format get special treatment. The definitions are stored as (under-documented) FormatValues: FormatValues[baseForm] // InputForm (* {HoldPattern[MakeBoxes[baseForm[a_, b_], fmt_]] :> ToBoxes[BaseForm[a, b]]} *) Note that if we omit InputForm from the expression above, then the system will attempt to apply the formatting ...

11

In answer to your first question, and as Leonid stated in a comment, you need to use TagSetDelayed to remove the ambiguity from your UpSet definition, e.g. DF /: Part[DF[expr_], r_String, rest___] := expr[[Position[expr, r][[1, 1]], rest]] I previously laid out a framework for this kind of problem, but you seem not to have used it. I shall attempt a ...

10

Adding to Szabolcs's answer, it's better to use ExtendedDefinition instead of ExtendedFullDefinition. In situation in which old symbol (the one that we want to copy), depends on anotherSymbol and anotherSymbol has old symbol somewhere in it's ...Values e.g.: ClearAll[new, old, anotherSymbol] old = anotherSymbol anotherSymbol[] := 2 old Full definition of ...

10

As Rojo notes, defining f/: Subscript[f,1][x_] doesn't work as f is too deep in the expression, however you could define your function in two steps to avoid tying the definition to Subscript. f /: Subscript[f, n_] := subs[f, n] subs /: subs[f, n_][x_] := g[x] This has the problem that Subscript[f,1] for instance will turn up in output as subs[f,1] rather ...

10

Your definition a[x_] == a[y_] ^:= Round[x] == Round[y] Is structural. It tells Mathematica how to rewrite certain expressions. It has no mathematical meaning. Mathematica has no mechanism to infer mathematical meaning from the rewrite rules you provide. It cannot determine what mathematical consistency might mean for your symbols. Rewrite rules are not ...

9

Does this work as you want to? SetAttributes[f, HoldAllComplete]; {first, rest___} ^:= HoldComplete[rest] f[args___] := {first, args} f[own, down[1], sub[1][2], N[n], up] HoldComplete["OwnValue", "DownValue", "SubValue", 3.14, up]

9

The explanation can be found in the doc to BeginPackage and Begin BeginPackage["context"] makes context and Systemthe only active contexts. Begin["context"] resets the current context. Therefore, at the moment you first mention the symbol test it is not created it in the Global context. This can be seen from you (simplified) example ...

9

Yes, you can set both with UpValues: x_G.f[] ^:= x h_[a___, G[x_, ___, y_], b___] ^:= h[a, y[x], b] G[2, e].f[] // Simplify (* e[2] *) It seems to work, but it is quite dangerous, as Leonid mention in the comment. For example, it was too easy to make a mistake in my previous revision. Here Simplify helps to deal with pure G[x_, ___, y_].

8

Another solution for this weird exercise is to make a combination from using $Pre and defining a new plus function. You use$Pre to replace every occurrence of Plus by your own definition which only act special at the input plus[2,2] and calls the normal Plus otherwise: SetAttributes[plus, Attributes[Plus]]; Unprotect[plus]; plus[2, 2] = 5; plus[args___] := ...

8

Warning: Modifying a built-in function is not advised As @m_goldberg already stated, Lookup has Attributes HoldAllComplete, so a workaround will be to remove this Attribute: Edit: As per m_goldberg's recommendation attr = Attributes[Lookup]; Attributes[Lookup] = {}; Now t1 = TempHead[a -> 1, b -> 2, c -> 3]; t2 = TempHead[c -> 3, d -> 4, ...

8

You don't need to use TagSetDelayed for the definition of the derivative because Derivative doesn't have attribute Protected. I'll extend add the derivative definition to arbitrary order n: ClearAll[ln]; Derivative[n_, 0][ln][x_, a_] := Derivative[n][Log][x] ln[x_, a_?NumericQ] := Piecewise[{{Log[x], Re[a] > 0}, {-Log[1/x], True}}] ln[x, -1/2] $... 8 General considerations This seems to be tricky, and I don't know how to do this without involving the inspection of Stack. The main problem is the order of rule applications. Since Dot evaluates its arguments, UpValues for f or G are only applied after both f[] and call to G have been fully evaluated - and then it's too late. Therefore, generally you have 3 ... 7 One solution is making your own function: MySinc[x_] := Sinc[x] Derivative[1][MySinc] ^= If[# == 0, 0, Derivative[1][Sinc] // Evaluate] &; MySinc[0] (* 1 *) MySinc'[0] (* 0 *) And then in expressions which use Sinc use expr/.Sinc->MySinc. To me this seems like the cleanest solution. However, this can be done with Sinc, too. But it is difficult ... 7 You should export the test symbol, ie define it between BeginPackage["TestPackage"] and Begin["Private"], for example by giving a usage to test. test::usage = "test[name] returns ..." (*or just*) test; for your definition, as said already in comments, I would use test[name] ^= "hello"; My answer to this post contains many application of UpValues, it ... 7 How about this ;-) \!$$\*InterpretationBox[2,3]$$+2 7 [Added: Virtually the same issue came up on StackOverflow a few years ago: Why do I have to evaluate this twice?] I would not consider it a bug if the manipulation of System` variables do no go the way you want. It turns out that the definition of TensorRank is not loaded until it is first evaluated. That initialization process resets the attributes of ... 7 Lookup has the attribute HoldAllComplete, which means the kernel evaluator will not see its arguments and, therefore, will not look at its up-values. 6 For read-only access to Excel data, I use a custom Set function that basically assigns an excel sheet to a symbol: setFromExcel::usage = "setFromExcel[symbol, file, sheet, opts] is a custom Set method which enriches 'symbol' for use as a data function."; skipRows::usage = "skipRows is an Option to the setFromExcel function. Use 'skipRows -> <... 6 Slightly modifying @jVincent's idea so that if there's no match with your definition you go back to the Subscript Module[{$guard = True, subs}, f /: Subscript[f, n_] /; $guard = subs[f, n]; subs[f, n_][sth_Integer] := g[sth]; subs[f, n_][sth_] := Block[{$guard = False}, Subscript[f, n][sth]] ] Now Subscript[f, 1][2] Subscript[f, 1][2.5] // ...

6

OptionValue and OptionsPattern[] are magical constructs, which work by certain macro-like trick at run-time. So, I am not surprised that OptionValue did not work here. I would suggest to use it's long form: OptionValue[f, {opts}, optionName], and declare options as opts:OptionsPattern[], rather than just OptionsPattern[] - it will work then, and ...

6

You can use Hold to simulate the behavior you originally had \$Version (* "10.2.0 for Mac OS X x86 (64-bit) (July 7, 2015)" *) ClearAll[mySymbol] mySymbol /: mySymbol + x_ := {mySymbol, x} mySymbol /: mySymbol + Hold[x_] := {mySymbol, x} tmp = mySymbol; tmp += 5 (* {mySymbol, 5} *) tmp = mySymbol; tmp += Hold[mySymbol] (* {mySymbol, mySymbol} *)

5

You can do this with the Notation Package and its Symbolize function: The definition is not attached to Subscript, but to pseudo-Symbol f1:

5

If I understand it correctly, the gist of your question is going from HoldComplete[x, y, z, up] to HoldComplete[1, y^2, z, up] assuming the following definitions: _[___, up, ___] ^= "UpValueEvaluated" x = 1 f[x_] := x^2 That is, evaluate everything inside the HoldComplete except the UpValue. I managed to do this using the following construction: ...

5

To answer my own question and further illustrate the kind of operation I am describing, here is a method using Set itself: SetAttributes[f, HoldAllComplete] f[args___] := Module[{h}, h[args] = 1; Level[DownValues@h, {4}, HoldComplete] ] f[own, down[1], sub[1][2], N[n], up] HoldComplete["OwnValue", "DownValue", "SubValue", 3.14, up]

5

An example I use from time to time is to "prettify" output. Suppose you have a not so huge matrix, e.g. aa = Array[Subscript[a, #1, #2] &, {3, 3}] which prints with commas between the Indexes. Sometimes, you don't want them and you can replace them with InvisibleComma. To do this, I use the following: runocommaindex={Subscript[a_, b___, x_, y_, c___]...

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