Install deferred actions #574
Replies: 13 comments
-
|
which is the difference with: scope( s ) { ? |
Beta Was this translation helpful? Give feedback.
-
|
That if you have a fault in your code then that release won't be executed, differently from the finally block in Java, which is always executed even if you have exceptions. |
Beta Was this translation helpful? Give feedback.
-
|
ok. Something like this? scope( a ) { |
Beta Was this translation helpful? Give feedback.
-
|
If the .... in the fault handler for myFault encounters a fault, you are not going to reach that rethrow. |
Beta Was this translation helpful? Give feedback.
-
|
ok. so what about this? scope( a ) { |
Beta Was this translation helpful? Give feedback.
-
|
An uncaught fault inside of scope |
Beta Was this translation helpful? Give feedback.
-
|
Ok, but this is a case of bad programming |
Beta Was this translation helpful? Give feedback.
-
|
What's your point? |
Beta Was this translation helpful? Give feedback.
-
|
I am trying to see the evidence of the benefit to introducing a new kind of handler. scope( a ) { it is not so heavy I think. Ok, it is not structured I agree, but why it should be? scope( a ) { but we have to define what happen in the case of termination and compensation. Also in those case the finalize is always executed. Right? |
Beta Was this translation helpful? Give feedback.
-
|
The benefit is just that the code is more modular. It doesn't add expressivity, just like in the other languages. It's a convenience. We have other conveniences, like default. The code: is not really modular because maybe the programmer wants to rethrow the fault, or not. You have to go and change the code. With defer, you keep the finalisation code separate from all the rest. I don't know if I can like your finalize, since it's static while defer plays with our current concepts and can be dynamically updated using cH. Your finalize block cannot. |
Beta Was this translation helpful? Give feedback.
-
|
default keyword alters the expressivity of the language because otherwise you need to specify all the handlers for all the faults. I see the advantages to exploit the dynamic updating of the handlers, but I do not see when it could be useful. Why the finalizing activities should be updated during the execution? |
Beta Was this translation helpful? Give feedback.
-
|
About default: that's what I mean. You can encode it using the rest of the language, hence it adds no expressivity, it's only a convenient feature. You statically know which faults can possibly be thrown by your code, since fault names are static in the throw primitive and in interfaces. About using dynamic handlers, we get two convenient features.
So, if we add a finalisation primitive like defer, I see install as a simple and powerful way that will just provide the same handler installation mechanism we have now. Defer seems like a handler to me, so I don't see why it should be different from the others, from an elegance/linguistic perspective. Now, should we add it at all? That's a different story. For this, we indeed need examples, that's why I'm asking for opinions. @jolie/developers : Have you encountered situations where you have to remember releasing stuff (or something similar) in a system? Anything goes: locks in a concurrency library, Here are a couple of examples from me: These are not enough to convince me though, yet. I'm looking for feedback on whether more examples exist, meaning that: if you can think of any, please post. ;-) |
Beta Was this translation helpful? Give feedback.
-
|
This thing has come up again lately when developing caching mechanisms. It's not strong enough yet to motivate me to actually open a code editor and add the feature, but I'm putting it here for future reference. ;-) I have a few remote resources that I want to cache locally (for speed/resilience) and update periodically (to keep them fresh). Without faults, the code looks like this: However, that's very flaky: if downloading the page raises a fault, you will never set the timeout and thus will never update the page again. One might think of setting the timeout before downloading the page, but that's not what I want (I want to take how much time it takes to download the page into account). So you end up with this: |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Many languages have the feature of indicating handlers to be executed no matter what, when we exit the current scope.
For example, in Java we have the finally clause for try blocks:
try {
File f = ...;
} finally { f.close(); }
(Which is automatised in try-with-resources, but that's besides the point since try-with-resources does not handle generic code blocks.)
In Swift, we have something that resembles the Jolie install primitive (albeit just syntactically, since the install primitive handles complex parallel situations and fault handling). Roughly, paraphrasing Java:
File f = ...;
defer { f.close(); } // this will be executed no matter what when we exit from the current scope
What if we added something like this to install?
scope( s ) {
install( defer => releaseResource@ResourceManager()() ); // will be executed no matter what when we exit from scope s
}
Opinions?
To me, it happens relatively often that I have to duplicate this kind of code in my fault handlers and in the normal code inside of the scope.
Beta Was this translation helpful? Give feedback.
All reactions