1
$\begingroup$

I'm trying to use Associations as object, and specifically want to use them as they are used in other languages using the dot notation. I'm using the code below to get started.

Unprotect[Dot];
Dot[a_Association, p_Symbol] :=
  Return[Evaluate[ a[p]]];
Protect[Dot];

This works fine for many things.

a=<|firstName->"Joe",lastName->"Smith",age->20|>;
a.firstName
(* Joe *)

But, it does not work for other things

a.age^2
a.firstName <> " " <> a.lastName

I know there are things I can do to resolve this issue, but the best way is eluding me.

Thanks in advance.

$\endgroup$
6
  • 4
    $\begingroup$ This happens because Precedence[Dot] is fairly low compared to that of Power and StringJoin. For example, (a.age)^2 and (a.firstName) <> " " <> (a.lastName) will work. I don't know exactly how the precedence should be changed, though. $\endgroup$ Commented Mar 5, 2021 at 8:22
  • 3
    $\begingroup$ . has very low precedence in WL: tutorial/OperatorInputForms way too low for an access operator. You can put () around but that is not a point. I'd say it is impossible in MMA because you don't have access to FE parser and patching Kernel parser will be a huge task. a.age^2 is automatically RowBox[{"a", ".", RowBox[{"age", "^", "2"}]}]] so you are not even starting from a plain input form string but already structured input. $\endgroup$
    – Kuba
    Commented Mar 5, 2021 at 8:26
  • $\begingroup$ Thanks Sjoerd & Kuba. I didn't realize it was a precedence issue. For now, parentheses may suffice. $\endgroup$
    – mitcheljh
    Commented Mar 5, 2021 at 11:50
  • 1
    $\begingroup$ Would you be satisfied with a solution where you use an input alias to enter the dot? For example, <kbd>Esc</kbd> <kbd>.</kbd> <kbd>Esc</kbd>? $\endgroup$
    – Carl Woll
    Commented Mar 5, 2021 at 16:24
  • $\begingroup$ Thanks for asking, Carl. Yes, I'd be happy to give it a try. $\endgroup$
    – mitcheljh
    Commented Mar 5, 2021 at 16:33

1 Answer 1

6
$\begingroup$

If you are willing to use input aliases to enter the dot, you could do:

CurrentValue[EvaluationNotebook[],{InputAliases,"."}] = TemplateBox[
    {},
    "Accessor",
    DisplayFunction->("."&),
    InterpretationFunction:>("@"&),
    SyntaxForm->"@"
];

Note that this overrides the standard alias for \[CenterDot]. Your association:

a=<|firstName->"Joe",lastName->"Smith",age->20|>;

Then, in the following, I use Esc . Esc instead of just .:

a.firstName
a.age^2
a.firstName <> " " <> a.lastName

"Joe"

400

"Joe Smith"

$\endgroup$
1
  • $\begingroup$ Nice! Works nice, without a lot of extra keystrokes, and still has the 'look' I was striving for. Thanks! $\endgroup$
    – mitcheljh
    Commented Mar 5, 2021 at 19:09

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.