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$
  • 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 Jun 19 at 11:48
  • $\begingroup$ Thank you @Kuba, I am going to read all this material $\endgroup$ – Picaud Vincent Jun 19 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$ – Leonid Shifrin Jun 19 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$ – Picaud Vincent Jun 19 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$ – Leonid Shifrin Jun 19 at 21:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.