The overhead is limited by the number of choice points to be cut.
And each choice point can only be cut away once.
Seems B is making big progress towards
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/cleanup
I don't reflect on access to the current choice-points, although
this could also be a good idea. Just compare with ancestors/1,
which allowed access to the call chain, one could also do
something like choice_points/1.
I only reflected on access to the count of the current
choice-points. As an alternative to the deterministic/1
predicate.
Currently I am printing out the number via statistics/0
and I am also allow retrieving it via statistics/1.
Its very interesting to see the number go up when
debug/0 is on... Sniff.
The problem is that the following would not work:
setup_call_cleanup(S, G, C) :-
sys_atomic_call((once(S), sys_on_cleanup(C))),
G,
deterministic(X),
(X==true, !; true).
The above would not work, since deterministic cannot
return true, even when G deterministically succeeds,
since there is the choice point from sys_on_cleanup/1.
So that is why I came up with the following solution:
setup_call_cleanup(S, G, C) :-
sys_atomic_call((once(S), sys_on_cleanup(C))),
current_prolog_flag(sys_choices, X),
G,
current_prolog_flag(sys_choices, Y),
(X==Y, !; true).
> This forum is fine for ...
This wouldn't be the first time that somebody tries to
speak for a collective. Please feel free to continue and
divert from the subject matter.
Bye
The bindings of C are required and needed in several uses. The most
obvious use is to detect determinism of a goal:
setup_call_cleanup(true, Goal, Det=yes)
Which is indeed the most procedural usage.
Other uses are when you want to construct a term lazily, but
after cleanup the term must look like a normal term. In that case,
the remaining variables are unified by the cleanup.
>If there are really implementations around, that
>performe a once, then the call_and_fail could
>be mentioned as an alternative.
It is not clear what you are discussing now: The sharing, or
having C executed as once(C0). Two different issues.
(I don't discuss the code you post as it seems to be very
specific to your implementation. It would help to discuss
properties observed, actual test code, as this would ve
of interest to others, too.)
The post-N215 could say it is once/1 when coming
from cut or determinism and it is call_and_fail/1
when coming from fail or exception.
So that no uncessary bindings are compiled in fail
or exception.
Or the better the once/1 semantics is something
only for setup_call_catcher_cleanup/4, and the default
for setup_call_cleanup/3 is call_and_fail/1.
And the beast setup_call_catcher_cleanup/4
needs also be dealt with in ISO!
So:
setup_call_cleanup/3 would do call_and_fail/1
setup_call_catcher_cleanup/3 would do once/1,
but the cleanup goal can decide whether it
will turn the once/1 into a call_and_fail/1.
Best Regards
This is not my problem.
> Often, this is written like:
>
> setup_call_cleanup(open(S),..., ( close(S), Closed = yes ) ).
>
> Idioms like that are in use since end 1997.
The value of Closed can only be used after cut or
determinism. So maybe the concept of this kind of
usage of a cleanup is flawed, and it would be money
invested better in some exception handling of
cleanup. Things allong the following lines:
- Cleanup is not allowed to fail.
- Cleanup is not allowed to do bindings.
- Cleanup exceptions are not suppressed.
- Cleanup exceptions are accumulated and not overshadowed.
- What else...?
Only the more general setup_call_catcher_cleanup/4 is
allowed to divert from these rules. So setup_call_cleanup/3
would be a specialized form of setup_call_cleanup/3
for the average user with a lot of safety built-in.
This could be appropriate for 2012! Yes we can.
Best Regards
This says: create a socket and connect it. If connect raises an error,
close the socket, else keep it. Note that tcp_connect/2 cannot fail;
it succeeds or raises an error. Thus, you can do
...,
tcp_socket(Socket),
catch(tcp_connect(Socket, Host:Port), E,
( close(Socket),
throw(E))),
Which is almost the same, except that a timeout or error between
a succeeding tcp_socket and the start of tcp_connect will leave
the socket open. setup_call_catcher_cleanup/4 should be safe.
Cheers --- Jan
I fully agree with you, although the cases where you want cleanup with
non-determinism is exactly the reason for which you need setup_call_cleanup/3.
I.e., in the deterministic case it is merely syntactic sugar.
Otherwise, I do not see the relation to my statement. I was saying that
setup_call_catcher_cleanup/4 can be used as syntactic sugar for the case
where you only want cleanup if the main goal raises an error. In addition
to being easier to read than the corresponding catch-cleanup-rethrow
alternative, it has the advantage of signal safety (I agree if
you say this is not an ISO issue).
Cheers --- Jan