-
Notifications
You must be signed in to change notification settings - Fork 40
MCP-0034 Ternary #2477
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
base: master
Are you sure you want to change the base?
MCP-0034 Ternary #2477
Conversation
…ul as array dimension
Language group at 101th design meeting: Poll: Scope of
Conclusion: No change for now. Poll: How to define
Conclusion: No change for now. Poll: How to refer to unknown:
Conclusion: No change for now. Define how to map
Conclusion: No change for now. Poll: Make specification changes and start collecting reviews:
Conclusion: Make spec changes and collect reviews. |
From phone-meeting:
|
@gkurzbach status? |
|
The widespread "shoudPass" typo (in the TernaryTest library) mentioned in yesterday's phone meeting has now been corrected. |
Design meeting: Questions:
Does
|
According to design meeting decision to make it more similar to enumerations.
Of the Next steps in #2477 (comment), the first has been completed. This brings us to the next item, which I'd like to put on the agenda for the upcoming phone meeting:
|
I have received local feedback on the proposal that I'm forwarding to the language group. It is the same old question about the external C mapping to By skipping 1 in the mapping, one could reliably detect when a
|
I really do not understand why we do not use But using a non-zero value for false just adds boilerplate code to C based implementations, with some funny intrinsic consequences. To represent false by All of this is of course, if we are concerned of C as implementation language at all -- it is not like the world is build around C. My understanding of your question is that we are concerned. |
My take of the long discussion behind #2477 (comment) was that we really didn't want a mapping that could easily be confused with the mapping of With Also note that with the |
From reading this, I get the impression that detecting an accidental misuse of |
I can see the benefit of the mapping to 1, 2, 3; since that makes Ternary close to a built-in enumeration type (and we could possibly extend enumeration types later so that it is just a built-in enumeration type). Obviously one can argue that Modelica should be closer to C for enumerations in general, which would argue for 0, 1, 2 - but that would be a breaking change. |
But adjusting 1-indexing to 0-indexing is easy to do, the question remains then, whether it will be |
I think a very strong reason to avoid mapping For those who prefer a 1-based mapping similar to enumerations, this can be combined with a safe mapping to {2, 3, 4}, by internally using an enumeration corresponding to:
When receiving values from an external C function, one can treat it as an enumeration, but instead of verifying that the value is in 1..4, one just modifies the test or adds an extra test that will reject |
Looking at the original motivation this seems to have become way too complicated compared to the problem it was intended to solve, i.e., handling a tool-specific default for visible as a third-value - such that a user can say something like To implement that we need:
The first part is to check what we currently have and in MSL we have 4-valued (Modelica.Electrical.Digital.Interfaces.UX01) and 9-valued logic (Modelica.Electrical.Digital.Interfaces.Logic), and built-in in the language we have one type that is sort of 5-valued logic (StateSelect - similarly as visible it allows a tool to have a default for a binary choice and the user to override it to force the underlying binary choice to be true or false). I believe the reason we missed the 4-valued and 9-valued logic in the original discussion is that we unfortunately didn't consider language and standard library as one entity. As you might guess they are all enumerations (a concept that was added together with StateSelect in 2.0). So, why not accept that Ternary is another built-in enumeration (as already suggested). Since we cannot name it Note that for The benefits of this are:
Note that this means that and/or will be blocks similarly as for 4- and 9-valued logic. (How they are implemented is of less importance - internally they can use min/max for 3-valued logic or tables as the 4- and 9-valued logic.) Note that Boolean is kind of the exception here, one reason is that Boolean expressions can be used to control if an equation is present or not - a binary decision that doesn't have a real counter-part in the other logics. Another is that we for some reason started enumeration-counting at 1 not 0. We can then later build on this - if needed; I guess there's a reason most computer languages don't have 3-valued logic built in. |
Let's not forget that the initial reason for creating this MCP was that you blocked any progress on dialog visibility control due to the lack of a ternary type in the language. Back then, it meant that there was a lot of work that had to be done for such a simple thing as a ternary visibility flag, but the idea of a Ternary in the language seemed useful enough that I considered it worthwhile trying to get this sort of obstacle out of the way once and for all. In endless design meetings since the beginning of 2020, the language group has guided the design towards the current state of the MCP. I must say I find too late to all of a sudden request a total change of direction now, but instead of discussing whether it's too late or not, let me give some good reasons for sticking with the current design. To break the current separation of language and standard library design by making them cyclically dependent would be a disaster in my opinion. It is bad enough that ModelicaServices isn't defined in the specification, but at least the rest of the specification doesn't depend upon ModelicaServices, so let's not put Unlike Ternary, it seems right to me that the domain-specific enumerations for digital circuits in Modelica.Electrical.Digital are defined within the library. For example, I really don't want to see Digital.Interfaces.UX01 being used in the standard language annotations. The Ternary of this MCP, on the other hand, is not a domain-specific type. It serves a much more basic and generic purpose in the language, and as we know from the background of this MCP, it is the kind of thing we would like to make use of in standard language annotations. A Ternary with implicit conversion from Boolean is very user-friendly compared to a built-in enumeration, as the user doesn't have to keep track of which true or false to use when expressing truth values. The implicit conversion from Boolean also means that functions and annotations can be enhanced in a backwards compatible manner by changing function inputs or annotation flags from Similar to the lack of blocks for StateSelect in the MSL, I don't see a strong need for Ternary blocks in the MSL, and it might even be desirable to not introduce such blocks until we have identified a block-oriented modeling domain where Ternary is a good model of the data in connectors. |
(Apologies if duplicated.)
To me it sometimes makes sense to step back and reconsider, and simplify the design based on previously considered variants.
That is not generally true, but depends on the tool support (or lack thereof). For a declared enumeration
In that case an implicit conversion is in fact less user-friendly, unless something is added for that as well. Obviously, it would be possible to support both - but it will still add to the cost in tool and to the user's mental model; and I'm not sure if it will ever become even as user-friendly as an enumeration. Adding new features, because the current ones (such as enumeration) aren't convenient enough, isn't a good way forward.
If we don't see a major need for Ternary blocks (or functions) in MSL (or other similar libraries), then I'm not sure if there is sufficient use of Ternary outside of annotations to make it more convenient. I'm not saying that there's no use for Ternary in model, just that I don't see it as significant enough to motivate the added complexity. |
Language group: |
It is not the expectation that there will be lots of That the external function value mapping is the de facto convention for other kinds of data interchange also means that if we agree on a mapping which makes it easy to detect mistakes when using external functions, it will also become easy to detect mistakes when dealing with things like simulation results and table data. In the end, these could be more important reasons to support easy error detection than the error detection in external functions. The less overlap with the mappings of Once we have agreed upon a mapping, there are good reasons to actually specify that this mapping should be used by the external language interface:
|
I also heard from @qlambert-pro that there were some questions in the meeting about the completeness of our test implementation. The easiest way to assess this is to look at the test library https://github.com/henrikt-ma/TernaryTest, which is fully supported. For those who find it boring to just look at the test library code, I can give a live demo where we can both look at the examples in the test library, as well as other cases brought up by the audience. Please react with 👍 in case you are interested! |
And we should take the logical next step, and see if we can avoid even having to ask those questions. We currently have the following kinds of types in Modelica:
Adding a new kind of primitive type has proven to be a substantial effort (based on experience with adding enumerations), and thus doing it needlessly would be an unnecessary hurdle for all Modelica users and implementers especially as Apart from not increasing the burden internally in tools (including code completion, drop-down menus for parameters, plotting) that also removes the need to consider the external C-interface, exporting to FMI, as all of that is already defined for the existing categories, and simplifies the user's mental model. Supporting a reasonable Ternary that solves the original issue shouldn't take more code than this comment. Going back to the original issue I also realize that we don't have consider compatibility for the new Ternary visible (or active?) as it doesn't replace an existing Boolean visible (or active?). That's why the lack of second implementation should have been a major warning flag. |
Just to make sure I understand this: |
In addition to that, it would be strange to provide semantics for operators (unless the language introduced a general mechanism for operators acting on enumerations). As I see it, it would be a major drawback to go for a solution without implicit conversion from Similarly, without implicit conversion from |
Yes, for the first part (not reuse), and more complicated for the second (convert). With Ternary as an enumeration the enumeration members cannot be named true and false, since they are reserved words; and thus we need different names for them - similarly as for StateSelect and for 4-valued and 9-valued logic. Having Ternary as an enumeration doesn't prevent us from having a conversion from Boolean even if a bit unusual. However, without the underlying enumeration it would be practically necessary. |
Yes, I can see that. But doesn't that suggest the need for a more fundamental construct to allow conversion to and from user-defined types? And such an extension would not only allow a good implementation of the type Ternary, but also the next type of similar characteristics. |
I'm afraid that would be so complicated that we'd never complete it. The proposal for |
Opening a draft pull request for MCP-0034 in order to create a forum for discussing the MCP at the stage of having a prototype implementation, hoping that there will be a clear direction to follow when writing specification changes. Such preliminary discussion, combined with just a short delay for writing specification changes, will then provide MCP reviewers with fresh background that should help reaching the under evaluation stage in a timely manner.