[go: up one dir, main page]

Page MenuHomePhabricator

The generic Type of a Typed list is not always evaluated in Expected results?
Open, Needs TriagePublicBUG REPORT

Description

Steps to replicate the issue (include links if applicable):

What happens?:
Z16833 fails whereas Z19007 passes

What should have happened instead?:
They should both pass (or both should fail)

Software version (on Special:Version page; skip for WMF-hosted wikis like Wikipedia):

Other information (browser name/version, screenshots, etc.):

Z19007 tests equality of generic Types and returns Z41, which passes Boolean equality. Z16833 uses the same equality function to test actual results against expected results (the generic Types extracted from Boolean-typed lists by the same function: https://www.wikifunctions.org/view/en/Z16829)

Details (of failing Z16833):

Expected result: { "Z1K1": "Z7", "Z7K1": "Z16829", "Z16829K1": [ "Z40" ] }
Actual result: { "Z1K1": "Z4", "Z4K1": { "Z1K1": "Z7", "Z7K1": "Z881", "Z881K1": { "Z1K1": "Z4", "Z4K1": "Z40", "Z4K2": [ "Z3", { "Z1K1": "Z3", "Z3K1": "Z40", "Z3K2": "Z40K1", "Z3K3": { "Z1K1": "Z12", "Z12K1": [ "Z11", { "Z1K1": "Z11", "Z11K1": "Z1002", "Z11K2": "identity" } ] }, "Z3K4": "Z41" } ], "Z4K3": "Z140", "Z4K4": "Z844", "Z4K7": [ "Z46" ], "Z4K8": [ "Z64" ] } }, "Z4K2": [ "Z3", { "Z1K1": "Z3", "Z3K1": { "Z1K1": "Z4", "Z4K1": "Z40", "Z4K2": [ "Z3", { "Z1K1": "Z3", "Z3K1": "Z40", "Z3K2": "Z40K1", "Z3K3": { "Z1K1": "Z12", "Z12K1": [ "Z11", { "Z1K1": "Z11", "Z11K1": "Z1002", "Z11K2": "identity" } ] }, "Z3K4": "Z41" } ], "Z4K3": "Z140", "Z4K4": "Z844", "Z4K7": [ "Z46" ], "Z4K8": [ "Z64" ] }, "Z3K2": "K1", "Z3K3": { "Z1K1": "Z12", "Z12K1": [ "Z11", { "Z1K1": "Z11", "Z11K1": "Z1002", "Z11K2": "head" } ] } }, { "Z1K1": "Z3", "Z3K1": { "Z1K1": "Z7", "Z7K1": "Z881", "Z881K1": { "Z1K1": "Z4", "Z4K1": "Z40", "Z4K2": [ "Z3", { "Z1K1": "Z3", "Z3K1": "Z40", "Z3K2": "Z40K1", "Z3K3": { "Z1K1": "Z12", "Z12K1": [ "Z11", { "Z1K1": "Z11", "Z11K1": "Z1002", "Z11K2": "identity" } ] }, "Z3K4": "Z41" } ], "Z4K3": "Z140", "Z4K4": "Z844", "Z4K7": [ "Z46" ], "Z4K8": [ "Z64" ] } }, "Z3K2": "K2", "Z3K3": { "Z1K1": "Z12", "Z12K1": [ "Z11", { "Z1K1": "Z11", "Z11K1": "Z1002", "Z11K2": "tail" } ] } } ], "Z4K3": "Z831", "Z4K7": [ "Z46" ], "Z4K8": [ "Z64" ] }

Event Timeline

Hmm. I think the problem here is the use of Z17464, which is defined for references. The fully-resolved types that are returned are Z4/Types, not Z9/References. It seems to be that there should be a Type equality function for this case. Am I missing something?

Hmm. I think the problem here is the use of Z17464

Well, I’m only guessing at what the problem might be, but Z19007 also uses Z17464. The only obvious difference is that the objects there are compared within the evaluation (“call”), rather than one object being the evaluation result and the comparison being performed in “result validation”.

I see. There are a few things going on here.

  1. Z17464 is only "accidentally" working for this case, as it were. It happens to work when the type has not been expanded into a full Z4 but has remained a Z9/Reference. So, as mentioned, a Type Equality function would be appropriate here.
  2. This is going to be hard to control until we rewrite the tester workflow.
  3. We don't normally expand the types of objects in the result that is returned, but calling Z16829 changes that because we end up evaluating the result of the function call.

Point 1 is something to consider: should we write an equality function that respects that an expanded Z4 should be equal to the identity that points to it?
Point 3 is interesting from the backend's perspective. I'm going to ask the team what they think.

I see. There are a few things going on here.

  1. Z17464 is only "accidentally" working for this case, as it were. It happens to work when the type has not been expanded into a full Z4 but has remained a Z9/Reference. So, as mentioned, a Type Equality function would be appropriate here.

I believe it works so long as both Types are fully resolved or both are References. I don’t know how a community function can control this (but References make more sense in the user interface, if you ask me).

  1. This is going to be hard to control until we rewrite the tester workflow.

Yes. I think we could reify the Types, for example, but the tester workflow doesn’t permit this because the outermost function has to be the function being tested (which we should change).

  1. We don't normally expand the types of objects in the result that is returned, but calling Z16829 changes that because we end up evaluating the result of the function call.

Ideally, I would have preferred to get a Reference back (specifically, the return from Z803 should not be expanded, because the value associated with a key is what it is, neither more nor less). However, if the function returns an expanded Type, we should have a way to prove its correctness by testing against an expanded Type.

Point 1 is something to consider: should we write an equality function that respects that an expanded Z4 should be equal to the identity that points to it?

Or vice versa… if the canonical or normal forms are the same, the objects are different representations of the same thing (if you ask me).

Point 3 is interesting from the backend's perspective. I'm going to ask the team what they think.

[edit: to clarify my remarks above, Z16829 has Z803 as its outermost function call, specifying Z4K1 as the key reference. From first principles, I would expect a Z4K1 value to be either a Z9/Reference or a Z7/Function call, not a Z4/Type. In practice, Z903 consistently returns either a Reference or an expanded Type, according to the Type in question. (For example, it returns the Reference "Z40" if a Type is Boolean and the expanded Z13518 Type if a Z1K1/type or Z4K1/identity is Natural number.)]

Thank you for your thoughts. We do have an Object Type equality function (Z15801), but that also doesn’t work in this context (I haven’t tried each of the implementations separately yet, however). This isn’t the test I wanted, by the way. I would have preferred to be able to demonstrate that the Type of the Typed list was equal to the Z881 function call. But it isn’t, apparently because the "Z40" is expanded in the evaluation (of the “call”) but not in the “result validation” (nor, I suppose, in the Z4K1 itself).

I have now created functions for Is a Typed list (Z19020) and Type of Typed list (Z18626) and I am inclined to suppose that it is more useful for Z16829 to return the combined results of those two functions rather than the generic Type itself (or an actual function call that would evaluate to the generic Type).

(Above, I am repeating T362278#10123241 to some extent, but the world moves on…)

Also, with regard to Z803, T363623 may be connected. Do we know why Z803 fails for Strings? (It fails for "Z6K1" as well as "Z1K1".)

My understanding is that the problem is indeed (as @cmassaro points out) with the Z17646/same reference function.

To give an example: if we do a Z866/same string between a String value of "string" and Z18551 (which currently is a String with the value "string") we should get Z41/true (which we do).

What we should be using here is a Function such as "same type" (which currently doesn't exist).

In a composition, that function should probably work off either the reified arguments, and then dive down the (unreified) Z4K1 (if available) until we either get to a Z4 or a Z7. If it is two Z4s, then we can check if the references are the same. If it is a Z7, we would need to make sure the function call is the same. We need to stop the evaluation manually, because the system would evaluate.

In JavaScript or Python this might be more straightforward, because there is nothing that will automatically evaluate and expand the Z4K1.

This approach *should* be possible in contributor space right now (but might not because of time outs). I would be curious for someone to try it out. There might be bugs discovered on the way there.

Other than that, I think the functions here kinda work as intended, more or less. The fact that Z19007 passes Z17466 is an 'accident', it really shouldn't, because the result of Z16829/type of object on Z881/Typed list(Z40/Boolean)[Z41/true, Z42/true] really isn't a reference, and thus should be ill-defined (i.e. in my opinion that function call should raise an error). Same is true for Z16833, which also should raise an error, I think.

I created “same Type” (Z19084) and converted Z16833 to use this function. It still fails, however. Z19084’s own version of the same logical test (Z19092) passes.

I’ll consider restricting “same Reference” to Z9 arguments but it is quite widely used:
https://www.wikifunctions.org/w/index.php?limit=100&namespace=0&title=Special:WhatLinksHere/Z17464. It may be better to create a new function for Reference equality and deprecate Z17464.

cmassaro subscribed.