Skip to main content
Became Hot Network Question
Tweeted twitter.com/StackMma/status/1165549486187458560
edited tags
Link
Alexey Popkov
  • 62.5k
  • 7
  • 163
  • 405
deleted 3 characters in body
Source Link

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with one more testtests that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *) AssociateTo[a[[1]], 3 -> 4] (* AssociateTo::invak: The argument Association[1->2] is not a valid Association. *) (* AssociateTo[a[[1]], 3 -> 4] *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into a real Association when evaluated. For some reason, FullForm (which is supposed to be the most verbose) hides these details.

As a practical matter, I would like to be able to construct a Hold with a real Association inside, but whose values might be unevaluated expressions (wrapping each value in its own Hold is a possibility, but it would complicate matters).

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with one more test that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *) AssociateTo[a[[1]], 3 -> 4] (* AssociateTo::invak: The argument Association[1->2] is not a valid Association. *) (* AssociateTo[a[[1]], 3 -> 4] *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into a real Association when evaluated. For some reason, FullForm (which is supposed to be the most verbose) hides these details.

As a practical matter, I would like to be able to construct a Hold with a real Association inside, but whose values might be unevaluated expressions (wrapping each value in its own Hold is a possibility, but it would complicate matters).

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with more tests that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *) AssociateTo[a[[1]], 3 -> 4] (* AssociateTo::invak: The argument Association[1->2] is not a valid Association. *) (* AssociateTo[a[[1]], 3 -> 4] *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into a real Association when evaluated. For some reason, FullForm (which is supposed to be the most verbose) hides these details.

As a practical matter, I would like to be able to construct a Hold with a real Association inside, but whose values might be unevaluated expressions (wrapping each value in its own Hold is a possibility, but it would complicate matters).

added 383 characters in body; edited tags
Source Link

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with one more test that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *)   AssociateTo[a[[1]], 3 -> 4] (* AssociateTo::invak: The argument Association[1->2] is not a valid Association. *) (* AssociateTo[a[[1]], 3 -> 4] *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into ana real Association when evaluated. For some reason, FullForm (which is supposed to be the most verbose) hides these details.

As a practical matter, I would like to be able to construct a Hold with a real Association inside, but whose values might be unevaluated expressions (wrapping each value in its own Hold is a possibility, but it would complicate matters).

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with one more test that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into an Association when evaluated.

This question might have a remote connection to my older question, it is also about sameness of expressions and subtle differences observable only in certain forms.

I encountered this strange behavior:

a = Hold[<|1 -> 2|>] (* Hold[Association[1 -> 2]] *) b = Hold[Evaluate[<|1 -> 2|>]] (* Hold[<|1 -> 2|>] *) a === b (* False *) FullForm[a] (* Hold[Association[Rule[1, 2]]] *) FullForm[b] (* Hold[Association[Rule[1, 2]]] *) a[[1, 0]] (* Association *) b[[1, 0]] (* Association *) Uncompress[Compress[b]] === b (* False *) Uncompress[Compress[b]] === a (* True *) Print[Grid[{TreeForm /@ {a, b}}, Dividers -> All]] 

TreeForm What is going on here? What's the actual difference between a and b?


After I already started to write this question, I came up with one more test that might be more revealing:

MapAt[Hold, a, {1, Key[1]}] (* MapAt::partw: Part {1,Key[1]} of Hold[Association[1->2]] does not exist. *) (* MapAt[Hold, Hold[Association[1 -> 2]], {1, Key[1]}] *) MapAt[Hold, b, {1, Key[1]}] (* Hold[<|1 -> Hold[2]|>] *) Depth[a] (* 4 *) Depth[b] (* 3 *)   AssociateTo[a[[1]], 3 -> 4] (* AssociateTo::invak: The argument Association[1->2] is not a valid Association. *) (* AssociateTo[a[[1]], 3 -> 4] *) 

So, it looks that a does not hold a real Association, but rather some kind of "raw" expression that can turn into a real Association when evaluated. For some reason, FullForm (which is supposed to be the most verbose) hides these details.

As a practical matter, I would like to be able to construct a Hold with a real Association inside, but whose values might be unevaluated expressions (wrapping each value in its own Hold is a possibility, but it would complicate matters).

added 58 characters in body
Source Link
Loading
Source Link
Loading