10
$\begingroup$

There seems to be an idiom whereby multiple parts generates Key->Value forms whereas for single part specifications, only a Value is returned. This however, can lead to inconsistencies as follows:

      assoc = <|"a" -> 7, b -> 8, "c" -> 9|>;
      {Query[{1, 2}][assoc], Query[1][assoc], Query[2][assoc]}
 (* -> {<|"a" -> 7, b -> 8|>, 7, 8} *)

but doesn't this contradict the documentation on multiple queries?

 Query::Docs] {op_1, op_2, ...} apply multiple operators at once to the result, yielding a list

firstly, a list is not "yielded" (returned) and secondly, each application of the operator ordinarily returns a value. A more consistent usage would therefore appear to be?

Query[{1, 2}][assoc]
(* -> {7, 8}  *)

(* not valid existing input/output - suggestive only *)

In addition, the mere presence of a range (e.g. 1 ;; 2) seems to induce individually specified parts to now return Values?

Query[{1, 2, 1 ;; 2}][assoc]
(*->  {7, 8, <|"a" -> 7, b -> 8|>} *)
$\endgroup$

1 Answer 1

3
$\begingroup$

In an earlier comment RunnyKine gave an example involving Key["a"] which if followed though provides an explanation. It also means that there is a subtle change in semantics using Part with an Association. Consider

 Query[{Key["a"], 2}]@assoc
 (* -> Missing["PartInvalid", {Key["a"], 2}] *)

suggesting that a list is not being interpreted as containing multiple queries but rather, it is being considered as a single query. Hence,

  Query[{1, 2}]@assoc
  (* ->  <|"a" -> 7, b -> 8|> *)

is not being parsed as a list of two queries (as the following unambiguously is)

Query[{Query@1, 2}]@assoc
(* -> {7, 8} *)

but instead is being parsed as

Query[Query[{1, 2}]]@assoc
(* -> <|"a" -> 7, b -> 8|> *)

or

assoc[[{1, 2}]]
(* -> <|"a" -> 7, b -> 8|> *)

but this in itself indicates a subtle semantic shift in the interpretation of Part between a List and an Association. The analogous

ls = {7, 8, 9};
ls[[{1, 2}]] 
(* ->  {7, 8} *)

has semantics - "take the list's first part -ls[[1]]- and its second part -ls[[2]]- and wrap them in a list - in other words it is the standard notational implementation of listability used throughout the Wolfram Language.

This interpretation no longer applies with an Association since assoc[[{1}]] (* -> <| a-> 7 |> *) now essentially says "wrapping parts in a list is not implementing listability for an Association but instead is simply a signal to include keys with specified parts". Personally I think it would have been more coherent to maintain a consistency with listability (especially since KeyTake can be used to return Key/Value pairs) as such consistency usually avoids the need for any disambiguation such as in this example.

$\endgroup$

Your Answer

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

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