-
Notifications
You must be signed in to change notification settings - Fork 40
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
Improve function (for purity) #3589
Comments
I agree that we need something more expressive than just I think a lot of this can be solved by extending the function variability described in https://specification.modelica.org/master/operators-and-expressions.html#function-variability. That is, by allowing function variability to be declared rather than just inferred from default arguments, much of what we need would follow automatically. Similar to today, function variability could remain inferred, but now not only from default arguments, but also from the function variability of functions used in the body. A key advantage of extending the function variability concept is that we get the semantic restrictions based on variability for free. With an extended function variability concept, we could use According to this idea,
I see a small syntactic challenge in that we don't have a variability keyword for the highest variability (non-discrete-time), while one would also like function variability to be implicit when no variability prefix is explicitly given. That is, to express
or
or
(When choosing syntax, one should also consider what it will look like when combined with Similar to |
I'm not convinced that it is really about variability. However, I have no problem with using
In particular I think the variability arguments breaks down here, as I don't see that "impure random" being on the "top of hierarchy" since it doesn't actually impact other functions (as level 3). Additionally, these functions don't really have side-effects (they depend on, but don't influence the external state), which would imply they are
I would more say that we keep external functions as impacting the external state. However, having the possibility to deduce these properties between functions would be helpful; the idea is that functions may in clever ways go down a level but not up (a function might use the random value in a way that removes the randomness - e.g., quick-sort of unique values internally using a random function to select the pivot; but a non-random function cannot become random). However, this also indicates that more discussion is needed and we have to figure out how to introduce this in a good way. It may indicate that the annotations are useful as an intermediate solution, while we figure out the best way forward. |
Thinking more I realized that The problem is that it differentiates it from impure constant, not from default impure - so |
@HansOlsson add two examples. |
For examples I will first present two example that I want to support in a good way: First a corrected example based on modelica/ModelicaStandardLibrary#4472
And a second simplified example:
The intents of the examples are:
Unpredictable cases are e.g.:
The problem here is that there's no guarantee that the "first" write-call will be ordered before the "second", so maybe B is written first and then A is added without appending to the file and thus overwriting B (the intent was the other order). I don't have a good solution for how to handle this, but adding impureConstant will at least ensure that we can see whether this issue may occur or not. I will not consider evaluable parameters in detail and think we can deal with that later. However, we can say that if we have to evaluate a parameter bound to a general impure function it becomes problematic (what about side-effects?). However, if it is impureConstant we can at least say that simulation is valid as long as the external environment wasn't changed. |
I still don't like the idea of hiding this information in annotations, and still believe that there should be orthogonal specification of whether a function may have side effects and with what variability it must be assumed to depend on the external environment. If one wants a |
For functions that have non-discrete-time dependency on the external environment, I guess one could actually use the following syntax:
where |
Continuing #1937
The current definitions of pure/impure are lacking in a number of ways, and that is getting problematic - and for users the problem is that since the definitions are so lacking the tools don't bother to implement and check the semantics.
Specifically
impure
is too coarse-grained and we can broadly see three levels:I used "level" to indicate that I don't see a need to care:
Being able to tell these apart has the following benefits in terms of clarity and future changes:
impure
functions, but for parameter-bindings only the first two levels are a good idea (whereas all work for when-clauses).And also performance for the first level.
A preliminary implementation in Dymola uses:
annotation(__Dymola_impureConstant=true)
for the first level; based on Improving semantics of "impure" keyword in Modelica 3.3 #1937 (and also without the__Dymola_
).annotation(__Dymola_impureRandom=true)
for the second level.It would be possible to turn this into syntax if we so desire (see #1937 for variants - including
impure input
).However, it might also be best to start with them as annotations to more quickly get this into libraries in a tool-independent way, and for the moment only view restrictions as tool-warnings - and then once we have more experience we can modify the syntax and semantics (and state that the annotations behave in a similar way for backwards compatibility).
For
pure
functions the corresponding issue is thread-safety. I assume that should be a separate issue.The text was updated successfully, but these errors were encountered: