)]}'
{"tvix/docs/value-pointer-equality.md":[{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"cfa705c2398380ca1f5bc96bc80ba3fbe8f35e03","unresolved":true,"context_lines":[{"line_number":13,"context_line":"the relevant part of this behavior for platform comparisons in the following (true)"},{"line_number":14,"context_line":"Nix expressions:"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"487ae06c_c984f89e","line":17,"range":{"start_line":16,"start_character":0,"end_line":17,"end_character":46},"updated":"2022-11-24 06:42:25.000000000","message":"Nixlang changes much more slowly than nixpkgs, and this document is likely to remain relevant for much longer than nixpkgs\u0027 current `lib/systems` will.  Perhaps it might be worthwhile to use examples that don\u0027t depend on today\u0027s `stdenv`?  E.g.\n\nFor any function `func` and attrset `attrs` all three of these are true:\n\n```\n                   func !\u003d func\n          { f \u003d func; } \u003d\u003d { f \u003d func; }\n { f \u003d func; } // attrs \u003d\u003d { f \u003d func; } // attrs\n```","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":13,"context_line":"the relevant part of this behavior for platform comparisons in the following (true)"},{"line_number":14,"context_line":"Nix expressions:"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"7547fc50_74c9dd08","line":17,"range":{"start_line":16,"start_character":0,"end_line":17,"end_character":46},"in_reply_to":"487ae06c_c984f89e","updated":"2022-11-24 13:12:33.000000000","message":"True, but this is just meant to be an introduction, so I want to start with the “real world” use case. Eventually we\u0027ll move this document into the spec anyways and then this can go away.\n\nI guess I wanted to this doc to be a bit entertaining to read, maybe for the worse?","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"cfa705c2398380ca1f5bc96bc80ba3fbe8f35e03","unresolved":true,"context_lines":[{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"844548bc_b855c78c","line":19,"range":{"start_line":19,"start_character":38,"end_line":19,"end_character":63},"updated":"2022-11-24 06:42:25.000000000","message":"We should probably mention that \"function pointer equality\" means pointer equality of both the lambda and its upvalues.  Importantly, the upvalues must be *pointer*-equal, not merely normal-form equal.  See cl/7372.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"5de62c8ff6c420dab5d06088c0f52e1d37de4d91","unresolved":true,"context_lines":[{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"bcb55b21_870a6f61","line":19,"range":{"start_line":19,"start_character":38,"end_line":19,"end_character":63},"in_reply_to":"801b835d_22b3c0bc","updated":"2022-11-25 01:33:13.000000000","message":"My point is that, as you are using it,\n\n```\nfunction pointer equality \u003d\u003d function (pointer equality)\nfunction pointer equality !\u003d (function pointer) equality\n```\n\n(a closure is a `function pointer` plus the values of all captured variables).\n\nLet\u0027s hope the reader infers parentheses the same way you do.  I didn\u0027t, at least not at first.\n\n\u003e there is no way to trick Nix into “deduplicating” the same values\n\nCorrect, but that\u0027s not what I was talking about.\n\nIf you understand that my point is about parsing `function pointer equality` and don\u0027t think other readers will misparenthesize it like I did, just ACK this.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":true,"context_lines":[{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"801b835d_22b3c0bc","line":19,"range":{"start_line":19,"start_character":38,"end_line":19,"end_character":63},"in_reply_to":"844548bc_b855c78c","updated":"2022-11-24 13:12:33.000000000","message":"I tend to disagree with this account or would at least argue that it is confusing. Equality is determined by checking if the two values have the same memory address (when this is the case is of course not well defined), but in general it means that both values have been constructed at the same place.\n\nThis is well illustrated by this REPL session, it needs to be the same individual value and there is no way to trick Nix into “deduplicating” the same values to a single memory location if they are constructed independently.\n\nnix-repl\u003e let mk \u003d x: name: x + \", \" + name; in [ (mk \"foo\") ] \u003d\u003d [ (mk \"foo\") ]\nfalse\n\nnix-repl\u003e let mk \u003d x: name: x + \", \" + name; x \u003d \"foo\"; in [ (mk x) ] \u003d\u003d [ (mk x) ]         \nfalse\n\nnix-repl\u003e let mk \u003d x: name: x + \", \" + name; x \u003d mk \"foo\"; in [ x ] \u003d\u003d [ x ]           \ntrue\n\nThe only way for things to be pointer equal seems to be if they eventually resolve to the same let binding, maybe there are more though?","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"9ea15cedca036e02daac9b784d5c2012086b5bc9","unresolved":false,"context_lines":[{"line_number":16,"context_line":"* `stdenv.hostPlatform.canExecute !\u003d stdenv.hostPlatform.canExecute`"},{"line_number":17,"context_line":"* `stdenv.hostPlatform \u003d\u003d stdenv.hostPlatform`"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"d7cb2445_d703694d","line":19,"range":{"start_line":19,"start_character":38,"end_line":19,"end_character":63},"in_reply_to":"bcb55b21_870a6f61","updated":"2022-11-25 10:25:30.000000000","message":"I see, updated the wording a bit. Also linked to the relevant upstream issue below.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"cfa705c2398380ca1f5bc96bc80ba3fbe8f35e03","unresolved":true,"context_lines":[{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"However, a maybe lesser known trick is to write a function such as the following to"},{"line_number":25,"context_line":"allow comparing functions:"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"36308769_51afe33a","line":22,"range":{"start_line":22,"start_character":5,"end_line":22,"end_character":24},"updated":"2022-11-24 06:42:25.000000000","message":"or list","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":19,"context_line":"This fact is commonly referred to as “function pointer equality” which is not entirely"},{"line_number":20,"context_line":"accurate, as we\u0027ll see. This account of the behavior states that, while functions are"},{"line_number":21,"context_line":"incomparable in general, they are comparable insofar, as they occupy the same"},{"line_number":22,"context_line":"spot in an attribute set."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"However, a maybe lesser known trick is to write a function such as the following to"},{"line_number":25,"context_line":"allow comparing functions:"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"8efa9ae9_0b04837f","line":22,"range":{"start_line":22,"start_character":5,"end_line":22,"end_character":24},"in_reply_to":"36308769_51afe33a","updated":"2022-11-24 13:12:33.000000000","message":"This bit is meant to be an introduction and I think this description of the behavior is a common misconception which is why I write “which is not entirely accurate, as we\u0027ll see”.\n\nLMK if that is unclear.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000036,"name":"flokli","email":"flokli@flokli.de","username":"flokli"},"change_message_id":"4d3a2c5e112bb8220e7a63fb90c6507765a92f91","unresolved":true,"context_lines":[{"line_number":38,"context_line":"```"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"Here, clearly, the function is not contained at the same position in one and the same"},{"line_number":41,"context_line":"attribute set, but at the same position in two entirely different attribute set. We can"},{"line_number":42,"context_line":"also see that we are not comparing the functions themselves (e.g. their AST), but"},{"line_number":43,"context_line":"rather if they are the same individual value (i.e. pointer equal)."},{"line_number":44,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"7780e8e2_8d919c7b","line":41,"updated":"2022-11-23 22:51:35.000000000","message":"s/set/sets/ (the 2nd one)","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":38,"context_line":"```"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"Here, clearly, the function is not contained at the same position in one and the same"},{"line_number":41,"context_line":"attribute set, but at the same position in two entirely different attribute set. We can"},{"line_number":42,"context_line":"also see that we are not comparing the functions themselves (e.g. their AST), but"},{"line_number":43,"context_line":"rather if they are the same individual value (i.e. pointer equal)."},{"line_number":44,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"7f4c945e_513a4c79","line":41,"in_reply_to":"7780e8e2_8d919c7b","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"8d2f5a2c04ddea9b383356c7899d33ed1dd064ee","unresolved":true,"context_lines":[{"line_number":80,"context_line":"```"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"It\u0027s interesting that `EvalState::eqValues` forces the left and right hand value before trying pointer"},{"line_number":83,"context_line":"equality. It explains that `let x \u003d throw \"\"; in x \u003d\u003d x` do not evaluate successfully, but it is puzzling why"},{"line_number":84,"context_line":"`let f \u003d x: x; in f \u003d\u003d f` does not return `true`. In fact, why do we need to wrap the values in a list or"},{"line_number":85,"context_line":"attribute set at all for our `pointerEqual` function to work?"},{"line_number":86,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"0cf93fef_7bf5664c","line":83,"range":{"start_line":83,"start_character":57,"end_line":83,"end_character":59},"updated":"2022-11-23 20:12:42.000000000","message":"does","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":80,"context_line":"```"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"It\u0027s interesting that `EvalState::eqValues` forces the left and right hand value before trying pointer"},{"line_number":83,"context_line":"equality. It explains that `let x \u003d throw \"\"; in x \u003d\u003d x` do not evaluate successfully, but it is puzzling why"},{"line_number":84,"context_line":"`let f \u003d x: x; in f \u003d\u003d f` does not return `true`. In fact, why do we need to wrap the values in a list or"},{"line_number":85,"context_line":"attribute set at all for our `pointerEqual` function to work?"},{"line_number":86,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"7b4896be_176bf3ca","line":83,"range":{"start_line":83,"start_character":57,"end_line":83,"end_character":59},"in_reply_to":"0cf93fef_7bf5664c","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"baa631b7b19b13a0e39a19a130b4017536dd9efc","unresolved":false,"context_lines":[{"line_number":96,"context_line":"}"},{"line_number":97,"context_line":"```"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"As you can see, two _distinct_ `Value` structs are created, so they can never be pointer equal even"},{"line_number":100,"context_line":"if the `union` inside points to the same bit of memory. We can thus understand what actually happens"},{"line_number":101,"context_line":"when we check the equality of an attribute set (or list), by looking at the following expression:"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"4bb32687_c07e8e81","line":99,"range":{"start_line":99,"start_character":0,"end_line":99,"end_character":94},"updated":"2022-11-23 21:09:30.000000000","message":"This is so totally batshit crazy.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000036,"name":"flokli","email":"flokli@flokli.de","username":"flokli"},"change_message_id":"4d3a2c5e112bb8220e7a63fb90c6507765a92f91","unresolved":false,"context_lines":[{"line_number":96,"context_line":"}"},{"line_number":97,"context_line":"```"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"As you can see, two _distinct_ `Value` structs are created, so they can never be pointer equal even"},{"line_number":100,"context_line":"if the `union` inside points to the same bit of memory. We can thus understand what actually happens"},{"line_number":101,"context_line":"when we check the equality of an attribute set (or list), by looking at the following expression:"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"f815b1e3_3ce33a57","line":99,"range":{"start_line":99,"start_character":0,"end_line":99,"end_character":94},"in_reply_to":"4bb32687_c07e8e81","updated":"2022-11-23 22:51:35.000000000","message":"\u003c3","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"baa631b7b19b13a0e39a19a130b4017536dd9efc","unresolved":true,"context_lines":[{"line_number":117,"context_line":"```"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"…, it\u0027ll work: The two attribute sets are compared by value, but their `x` attribute turns out to be pointer"},{"line_number":120,"context_line":"equal _after_ forcing it. This does not throw, since forcing an attribute set does not force its value"},{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"d0b7988f_c6aa0699","line":120,"range":{"start_line":120,"start_character":97,"end_line":120,"end_character":102},"updated":"2022-11-23 21:09:30.000000000","message":"s/value/attributes\u0027 values/","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":117,"context_line":"```"},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"…, it\u0027ll work: The two attribute sets are compared by value, but their `x` attribute turns out to be pointer"},{"line_number":120,"context_line":"equal _after_ forcing it. This does not throw, since forcing an attribute set does not force its value"},{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"9fd1d81d_a4e14596","line":120,"range":{"start_line":120,"start_character":97,"end_line":120,"end_character":102},"in_reply_to":"d0b7988f_c6aa0699","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"baa631b7b19b13a0e39a19a130b4017536dd9efc","unresolved":true,"context_lines":[{"line_number":120,"context_line":"equal _after_ forcing it. This does not throw, since forcing an attribute set does not force its value"},{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"372b8047_8fa4b86e","line":123,"range":{"start_line":123,"start_character":66,"end_line":123,"end_character":78},"updated":"2022-11-23 21:09:30.000000000","message":"s/incomparable/otherwise-incomparable/\n\nor just delete incomparable\n\nor leave it and ACK this, it\u0027s a matter of taste.  (I had to re-read this clause a few times to figure out what was going on but maybe it\u0027s just me)","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":120,"context_line":"equal _after_ forcing it. This does not throw, since forcing an attribute set does not force its value"},{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"409bf51e_ebf149d4","line":123,"range":{"start_line":123,"start_character":66,"end_line":123,"end_character":78},"in_reply_to":"372b8047_8fa4b86e","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"8d2f5a2c04ddea9b383356c7899d33ed1dd064ee","unresolved":true,"context_lines":[{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"128b64d9_5b653c99","line":124,"range":{"start_line":124,"start_character":44,"end_line":124,"end_character":48},"updated":"2022-11-23 20:12:42.000000000","message":"lists","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":121,"context_line":"(as forcing a list doesn\u0027t force its elements)."},{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"d65644ac_762da100","line":124,"range":{"start_line":124,"start_character":44,"end_line":124,"end_character":48},"in_reply_to":"128b64d9_5b653c99","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"ed86746c4af752a377f31bab724af0a33cc4b199","unresolved":true,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"},{"line_number":128,"context_line":"evaluated before pointer equality can kick into effect."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"c84c2180_92328bf2","line":125,"updated":"2022-11-23 21:43:57.000000000","message":"missing `","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"As we have seen, pointer equality can not only be used to compare incomparable function values,"},{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"},{"line_number":128,"context_line":"evaluated before pointer equality can kick into effect."}],"source_content_type":"text/x-markdown","patch_set":2,"id":"9ca42e66_d8138e0a","line":125,"in_reply_to":"c84c2180_92328bf2","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"8d2f5a2c04ddea9b383356c7899d33ed1dd064ee","unresolved":true,"context_lines":[{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"},{"line_number":128,"context_line":"evaluated before pointer equality can kick into effect."},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"## Summary"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"f210cfd8_3c226eea","line":127,"range":{"start_line":127,"start_character":23,"end_line":127,"end_character":26},"updated":"2022-11-23 20:12:42.000000000","message":"or","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":124,"context_line":"but also other incomparable values, such as list and attribute sets that would cause an evaluation"},{"line_number":125,"context_line":"error if they were forced recursively. We can even switch out the `throw` for an `abort. The limitation is"},{"line_number":126,"context_line":"of course that we need to use a value that behaves differently depending on whether it is forced"},{"line_number":127,"context_line":"(think `builtins.seq`) and forced recursively (think `builtins.deepSeq`), so thunks will generally be"},{"line_number":128,"context_line":"evaluated before pointer equality can kick into effect."},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"## Summary"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"76fb3911_cdedf1d1","line":127,"range":{"start_line":127,"start_character":23,"end_line":127,"end_character":26},"in_reply_to":"f210cfd8_3c226eea","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"8d2f5a2c04ddea9b383356c7899d33ed1dd064ee","unresolved":true,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"When comparing two Nix values, we must force both of them (non-recursively!), but are"},{"line_number":133,"context_line":"allowed to short-circuit the comparison based on pointer equality, i.e. if they are"},{"line_number":134,"context_line":"the same exact value in memory, they are deemed equal immediately. This is completely"},{"line_number":135,"context_line":"independent of what type of value they are. If they are not pointer equal, they are"},{"line_number":136,"context_line":"(recursively) compared by value as expected."},{"line_number":137,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"37a00ccf_2569f8f7","line":134,"range":{"start_line":134,"start_character":0,"end_line":134,"end_character":3},"updated":"2022-11-23 20:12:42.000000000","message":"at the same exact location in memory","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000034,"name":"sterni","email":"sternenseemann@systemli.org","username":"sterni"},"change_message_id":"f9c2eb9b35e3b86767c0071d9d499f4514b00590","unresolved":false,"context_lines":[{"line_number":131,"context_line":""},{"line_number":132,"context_line":"When comparing two Nix values, we must force both of them (non-recursively!), but are"},{"line_number":133,"context_line":"allowed to short-circuit the comparison based on pointer equality, i.e. if they are"},{"line_number":134,"context_line":"the same exact value in memory, they are deemed equal immediately. This is completely"},{"line_number":135,"context_line":"independent of what type of value they are. If they are not pointer equal, they are"},{"line_number":136,"context_line":"(recursively) compared by value as expected."},{"line_number":137,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"7f90ce47_92f96059","line":134,"range":{"start_line":134,"start_character":0,"end_line":134,"end_character":3},"in_reply_to":"37a00ccf_2569f8f7","updated":"2022-11-24 13:12:33.000000000","message":"Done","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"baa631b7b19b13a0e39a19a130b4017536dd9efc","unresolved":false,"context_lines":[{"line_number":135,"context_line":"independent of what type of value they are. If they are not pointer equal, they are"},{"line_number":136,"context_line":"(recursively) compared by value as expected."},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"However, when evaluating the Nix expression `a \u003d\u003d b`, we *must* invoke our implementation\u0027s"},{"line_number":139,"context_line":"value equality function in a way that `a` and `b` themselves can never be deemed pointer equal."},{"line_number":140,"context_line":"Any values we encounter while recursing during the equality check must be compared by"},{"line_number":141,"context_line":"pointer as described above, though."},{"line_number":142,"context_line":""}],"source_content_type":"text/x-markdown","patch_set":2,"id":"fe143350_3ac90647","line":139,"range":{"start_line":138,"start_character":0,"end_line":139,"end_character":95},"updated":"2022-11-23 21:09:30.000000000","message":"Ugh.  Because if we do allow pointer inequality, we won\u0027t force them, and we could continue evaluation in a situation where cppnix would throw or abort.\n\nUgh.","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"},{"author":{"_account_id":1000066,"name":"Adam Joseph","display_name":"amjoseph","email":"adam@westernsemico.com","username":"amjoseph"},"change_message_id":"baa631b7b19b13a0e39a19a130b4017536dd9efc","unresolved":false,"context_lines":[{"line_number":184,"context_line":"Now, I can\u0027t speak for the upstream C++ Nix developers, but sure can speculate."},{"line_number":185,"context_line":"As already pointed out, this feature is currently needed for evaluating nixpkgs."},{"line_number":186,"context_line":"While it\u0027s use could realistically be eliminated (only bothersome spot is probably"},{"line_number":187,"context_line":"the `emulator` function, but that should also be doable), removing the feature"},{"line_number":188,"context_line":"would seriously compromise C++ Nix\u0027s ability to evaluate historical nixpkgs"},{"line_number":189,"context_line":"revision which is arguably a strength of the system."},{"line_number":190,"context_line":""},{"line_number":191,"context_line":"Another indication that it is likely here to stay is that it has already"},{"line_number":192,"context_line":"[outlived builderDefs][], even though"}],"source_content_type":"text/x-markdown","patch_set":2,"id":"aa77c2ee_149cec51","line":189,"range":{"start_line":187,"start_character":58,"end_line":189,"end_character":52},"updated":"2022-11-23 21:09:30.000000000","message":"+1","commit_id":"5c9bc044b32be8e876f26d21b26bfe6dc827ab06"}]}
