-
Notifications
You must be signed in to change notification settings - Fork 440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
check if a field exists in 'super' #311
Comments
#305 asks for the same thing. My preferred approach is to put metadata: { } in the super object, but if that is not possible, we might have to revive the standalone super, which I removed because the implementation was very complex. |
As we build out ksonnet, we want to be able to "mix in" things that the super object may not know about apriori. An alternative would be to have something like |
Is this limited to a new notation or function would reduce complexity ? eg: or |
So in general +: can be used to extend an array, string, or even to add to a number. So a |: syntax sugar would have to default the super field to the correct "zero" value for the RHS of the operator. What I used to do is have a template for my "base" objects that came from the library. So you do:
That allows you to add stuff to Base as you extend the library. Can you do that? |
@sparkprime this is much of what we are doing now. The end result is that there is a lot of ugly cruft left over in the final rendered output (hence prune). As things get deeply nested this gets pretty big. We also may find ourselves in a situation where we have:
But that is pretty order dependent and a bit dangerous. This triggers a thought: Another reason to allow detection on super would be to assert the thing you are clobbering is empty already. That would prevent users from putting a base on top of something that already has data. |
In addition to what Joe and Antoine are saying, our goal is to use mixins with Kubernetes API objects that may not have been created using our templates, and therefore, may not have our zero values. This use case is very, very important to us, and it would be very helpful to have language level support. |
In the old world where standalone
which would be equivalent to |
What about if super[f], rather than yielding an error if f is not in super, instead returned some special value that triggers an error if used in any way other than on the LHS of a +, in which case the semantics are that the result of the + operator is the RHS of the +. The net effect of all of that is that This should be backwards compatible because it's only introducing new semantics in a case that used to yield an error. |
My intuition here is that in an OO language, if you do class A extends B { public void f() { } }, there was no requirement for there to be an empty function f() in B. It either defines or overrides. So, fundamentally, what you're asking for is natural. |
An alternative way to achieve this is to make +: a first class primitive, i.e. it is not just a desugaring to |
Unless I'm missing something, the option That seems to leave the options of making What do you think? If that sounds more or less inline with your thinking, it would be great to have a breakdown of the work you would expect to ship the feature, so that we can prioritize it later next week. (BTW, we will also be discussing the changes to |
What kind of foot shooting do you anticipate with a more permissive super[f] ? |
Speaking for myself, I think it introduces corner cases that would not be obvious to me as a new user. The failure mode as it exists now is not super subtle: it becomes clear immediately what is and is not allowed (e.g., you now know you can't check if In the case of a more LHS-amenable |
To 100% verify what you'd say, we'd have to find some case where Two things come to mind:
The difference between "more permissive +:" and "standalone super" is that the former allows you to write your mixins more easily. I can imagine you defensively coding every field using reflection, and that's going to hurt readability and maybe performance too. Having +: (and friends) be a first class operator with extra powers means you can't use a mixin to prepend to an array, or insert into a set, which might be useful. I think what we need is a new operator, and I can think of two possibilities (syntax TBD) and I haven't thought about how to define the semantics in the spec yet (object-inherit rule):
Some test cases:
|
Another option:
|
Assuming I understand your proposal, it seems to be similar to C#'s null coalescing operator, but instead of coalescing when the value is I do wonder two things:
|
Yeah everything we've discussed has been a twist on that kind of defaulting operator, except specifically for super. There is Java's @OverRide annotation which might work for the case where you want to assert the existence of something in the super class. That works for these more complex nested things and in the basic case of A + { /* override */ f: 3 } where you don't want to add on to super.f but just replace it (e.g. zero is just z where z + v == v, so since + is only defined on a few types, it is { } [ ] "" or 0. |
Ok, so does it make sense at this point to put together a proposal for how to proceed? I'm not sure generally what the process is. |
I think we're doing the process right now :) I think |
Right, sorry, what I'm saying is that it would be helpful for me is if we had a breakdown of stuff to do so that I could start to push to put that in our planning cycle. Unless you want to do the implementation, of course. :) |
I'd like to sort out all remaining design questions before we start implementing, as I'm not worried about the implementation and can do it all myself if needed. However I'd rather not have to backtrack the design after it's gotten adoption. Typically, the design part is the hard part :)
If the design ends up being bigger, that's fine as we can stage the implementation. So you'll still be able to take advantage of this quickly. Here's a breakdown of implementation tasks with dependencies: Code:
I propose I do 1, 2, 3, 4, 5 as (5) in particular involves ugly code and a delicate garbage collector. Docs & Releasing:
|
I don't think that I understand what you mean in questions (2) and (3). I'm not sure if you're proposing new syntax/semantics, or what your proposing symmetry between. I can talk a little bit about point (1) though. A lot of the proposed syntax is similar to various implementations of null-coalescing operators (you might say they're null-coalesque), but semantically different (i.e., we coalesce when Just to be completely explicit, let me describe the semantics of the C# implementation of null-coalescing operators (in the case of the latter operator, there is a similar implementation in JavaScript). Given this, it seems like we have a few options:
I'm less concerned about other operators wanting to use the question mark. The obvious one is Javascript's optional-value |
The closest thing we have to null coalescing is As for avoiding two different kinds of coalescing operators -- one for OO and one for expressions, that's an another argument for the proposal that just returns a bool. We have the keyword 'in' that is not used except in comprehensions. I believe we could use that as a binary operator without introducing parsing headaches. This actually aligns with Python, which is nice.
It would make sense to also define it for arrays: The use within comprehensions is currently limited to arrays, whereas in Python it allows you to iterate over dict fields. Maybe we should extend comprehensions too. In order for it to solve the original problem, it would have to return true if the field is hidden. I think that makes sense -- these reflective constructs are more useful during computation, whereas hidden / non-hidden is more about manifestation. |
This also answers my questions (2) and (3), because Python has already decided:
|
Ok, so the proposal at this point seems to be something along the lines of using It is verbose, but acceptable. It seems like this removes the need for |
Yes but also changing +: to test it as well, which should cover almost all cases Sent from my Motorola Nexus 6 using FastHub |
Sweet. So is the next step to write the spec, write the code, or something else? |
Also, just for planning purposes, what are you thinking about timelines? (Obviously we are hoping to have everything somewhat sooner, but I also understand you are busy. :) ) |
Some progress already:
|
Yeah, also give it a go and see if you can write the code you're expecting to be able to write |
Excellent. It seems to work for at least a core handful of scenarios we care about. I'll start writing actual things against it and let you know if I hit problems. |
Interestingly, it breaks the invariant that |
Actually, |
Ok, thinking about this has led me to realize that the new implementation does not match the new spec. I haven't written the new spec, but planned to use the fact that the spec's core language allows standalone super to simply desugar Basically, the question is "Should |
Alright, I'm going to tentatively say that this works for our use case. I'll post back with some examples of an end-to-end scenario after we finish adapting the codegen to use this feature. From our end, what do you need from us? If you want code review I'm still happy to do that. (My one lingering concern was whether this would work for nested types, which is why I asked whether the zero value of a nested object type should really be |
I've been grappling with the semantic crisis I described in my last 3 comments, and I'm leaning towards Appreciate your thoughts on it! |
It is not clear to me that I suppose my main question is: why not support both? We could keep If that is not to your liking, it seems like you can maintain the equational reasoning if you have some way of explicitly specifying the default value of |
It's definitely a tricky one. As for |: having two ways to do it that are quite similar is not so good. Especially since we already have 6 'colon' operators and |: would make it 9. It's also kinda like having two While I bought your argument that adding default super behavior to |
Feel free to review #318 btw. I still need to update the spec and other docs. The semantic crisis is resolved one way or another by changing a single line of code, so in that sense it is not a big deal :) |
I'll try to review tomorrow, but I have a wedding to get to later in the day so it might have to be the day after. |
Ok, so, not that you need my approval, but I think the proposal of an "n-permissive" So, I want to be careful not to position this as a total roadblock, but I think it's worth stepping back and considering two goal-level questions:
If your the answer to both of these is "no" then the proposal is probably mostly complete. But, for whatever it's worth, I do happen to see a lot of value in (1), and if you agree, and an operator is off the table, then we should discuss how we might approach this by, e.g., surfacing the I also do think that (2) is a problem. If you agree then that discussion can probably be similar to (1), e.g., it can also be solved with explicit |
If I paraphrase your first question:
You can can always use just : and do the expansion yourself, e.g. get the behavior of current master by explicitly doing Another approach is to add an assert that requires For question (2), you can always write that explicitly instead of using |
Oh it looks like we're miscommunicating: |
Ah, sorry, doing In any event, great, I buy your argument about the "fully permissive" mixin sugar. That seems like the way to go, given what you've just said. |
There's some examples at the bottom of test_suite/object.jsonnet |
Small update: I was out of office for a few days, now I'm working on the spec (figuring out how to left align things) |
Sweet. Need anything from us? |
I'm good, let me know if I can help with #307 :) |
I'm hoping to get some time to work on it later this week. BTW, we're planning on releasing the |
I think it is all done now. Do you want me to cut a release with this change or wait for #307? |
BTW I will remove the addition of std.zero from the PR since it is no-longer used in the desugaring. We can always add it back again if it has a use beyond what we discussed here. |
@sparkprime Speaking only for myself, I would prefer we cut the release now, since the |
That said, I am committed to doing it, just when things calm down a bit... |
No probs, let's do that then |
Fixed by #318 |
Hi,
I'm trying to do the following
It fails because super doesn't have the 'metadata' field. I would like to know if there is a way to test that condition ?
eg:
The text was updated successfully, but these errors were encountered: