1
$\begingroup$

I want to wrap some association data into a dedicated symbol (S by example)

S /: S[a_Association][k_] := a[k]
S /: Format[s_S] := 
 "Demo, here are my keys " <> ToString[Keys[First[s]]]

I use such approach (but AFAIK this is a common one) as I see two benefits:

1/ easy argument filtering

foo[S[a_Association]]:="Hello S!"

2/ syntaxic & looks sugar:0

s = S[<|"A" -> 1, "B" -> 2|>]
s["A"]

prints:

"Demo, here are my keys {A, B}"
1

However when you have a nice syntax for s["A"], you also want a nice syntax for s["A"]=3. This is even mandatory, as

s["A"]=3

is misleading/bug prone:

It does not change the internal association:

s // First    

<|"A" -> 1, "B" -> 2|>

but only binds 3 to s["A"]:

s["A"]

3

So far my solution to the problem is to modify the buildin Set function as follows:

Unprotect[Set]
Set[s_Symbol[k_], v_] /; MatchQ[Hold[s] /. OwnValues[s], Hold[_S]] := 
 Block[{a = First[s]}, a[k] = v; Set[s, S[a]]]
Protect[Set]

Now

s["A"]=3
s["C"]=4
s // First

prints

"Demo, here are my keys {A, B}"
"Demo, here are my keys {A, B, C}"
<|"A" -> 3, "B" -> 2, "C" -> 4|>

as expected.

My question:

Before using this in "real" developments, I would like your advices:

  • is this approach ok (no side effect,...) ?

  • is there a better approach/solution ?

$\endgroup$
8
  • 2
    $\begingroup$ In general you may want to set a mutation handler, see 165910 and go through linked examples. And here is a broader topic that may cover what you need: 198378 $\endgroup$
    – Kuba
    Commented Jun 19, 2019 at 11:48
  • $\begingroup$ Thank you @Kuba, I am going to read all this material $\endgroup$ Commented Jun 19, 2019 at 12:25
  • 1
    $\begingroup$ Redefining Set like this is really a last resort and is best avoided. There are alternative ways (@Kuba provided references to such). $\endgroup$ Commented Jun 19, 2019 at 19:00
  • $\begingroup$ @LeonidShifrin thanks for the comment. I understand that we are very close to the "danger zone" when redefining such builtin functions. However in this very peculiar case is there a problem? (that was my motivation to ask this question here). I have started reading Kuba material, but have not digested everything yet :) $\endgroup$ Commented Jun 19, 2019 at 19:32
  • $\begingroup$ I have discussed the issues associated with Set overloading here, so I refer you to that discussion for arguments against it. Also check out this question. None of those discussions will likely have a direct answer to your question, but the references provided by @Kuba should point you to the better direction. $\endgroup$ Commented Jun 19, 2019 at 21:25

0

Your Answer

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

Browse other questions tagged or ask your own question.