• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp4382
r3wp44224
total:48606

results window for this page: [start: 39201 end: 39300]

world-name: r3wp

Group: !REBOL3 ... [web-public]
Graham:
24-Feb-2010
Pekr, putting a trace before demo and it doesn't crash.  Very odd.
PeterWood:
24-Feb-2010
I tried the chat then demo trick under linux and Rebol crashed with 
a segmentation fault. Normally, the demo gives a script error. I 
also tried on Mac OS X but that was okay - the demo gave a script 
error.
Graham:
26-Feb-2010
and other issues http://twitter.com/rebol3
Steeve:
27-Feb-2010
I think i will change again some habits in the way I code.


It seems that the try/except idiom has better perfs than EITHER if 
you use it  that way:
>> try/except [...frequent case...][...rare case...]

Try this and give me your results...

f1: funct [v][either zero? v [0][1 / v]]
f2: func [v][try/except [1 / v][0]]

print dt [loop 100000 [f1 1]]
print dt [loop 100000 [f1 0]]

print dt [loop 100000 [f2 1]]
print dt [loop 100000 [f2 0]]
BrianH:
27-Feb-2010
Wow, I never realized what overhead TRY/except has, but that overhead 
seems to be fixed. As long as you can safely run until an error without 
having to roll back changes, that could be a good strategy. Sticking 
to the R3 safety model (generating errors before it matters with 
functions like ASSERT) you can make code that runs faster in the 
default case, and safely always.
BrianH:
28-Feb-2010
Or you can look at the source of DECODE-CGI in R2 and make something 
useful of it for your purposes. Nothing built into R3 though.
BrianH:
28-Feb-2010
And that parse rule would work in R2 or R3. We can't R3-optimize 
it yet with the change rule since change rule paren hasn't been implemented 
yet.
Paul:
28-Feb-2010
I built my own decoder for the query-string and it works pretty good. 
 But I was wondering what the /only refinement is for  construct. 
 This looks new in R3.
Paul:
1-Mar-2010
They probably had to break away and do some projects to pay some 
bills.
BrianH:
1-Mar-2010
CONSTRUCT by default translates the built-in logic words to logic 
values, unset values to none, lit-words to words, and lit-paths to 
paths. This makes it easier to use it to handle headers. CONSTRUCT/only 
doesn't do any of those things - it only constructs the object with 
the data provided.
Sunanda:
2-Mar-2010
Thanks for the kind words, Brian,

But I am not sure we can yet agree on the issue involved. I've added 
my response to your detailed analysis:
  http://www.curecode.org/rebol3/ticket.rsp?id=1506

Without the ability to catch _all_ errors, REBOL is vulnerable to 
sudden, unexpected and unhandlable crashes.
Gregg:
2-Mar-2010
Great analysis Brian. And I think Sunanda's point about arbitrary 
code is the key element for me. Some things we can address with language 
"Don do that", but error handling like this is very important to 
get right, and explain clearly (with examples of how to write robust 
apps).
Sunanda:
2-Mar-2010
I've given it some more thought and think I have combined two issues 
that could better be dealt with separately:

1. TRY and ATTEMPT as ways of protecting my code:

Generally, the current behavior is surprising but in most cases acceptable.

It is rare that something as stupid as attempt [exit] would make 
it to production status. So, in many cases  no problem. [perhaps 
an odd problem if my app is generating code (eg a genetic algorithm). 
But knowing the problem, that could be guarded against]. 

2. TRY and ATTEMPT for protecting arbitrary code

As Gregg suggests, that needs a careful, systems-level design to 
get right and to make robust. REBOL3 offers some help (SECURITY policies, 
ATTEMPT, TRY, CALL) but isolating code into a safe sandbox, and recovering 
from any possible error/lapse/attack is not something the language 
alone can provide.


Still, making TRY and ATTEMPT fully predictable [succeed or return 
an ERROR] would be most welcome!
BrianH:
3-Mar-2010
The trick, Sunanda, is that the code that you want ATTEMPT to catch 
isn't actually erroneous. EXIT itself never generates an error - 
it basically is like a fancy goto that has to be caught by a handler. 
However, the handler can trigger an error (the one that you see) 
if the goto supposedly isn't handled; actually, all such goto functions 
are always handled and never cause an error directly, it is the handlers 
that cause the error.


The problem is really one of perception: Code that you think is erroneous 
(but isn't) is not triggering errors (and shouldn't), and the code 
that is triggering the error is not actually inside the code block 
that you are passing to TRY or ATTEMPT. Perceptual problems are tricky 
- either you have to change your perceptions, or rewrite the basic 
semantics of the language. Which is easier in this case?
Sunanda:
3-Mar-2010
But 
  exit
_is_ an error on its own.

It is hard to see why ATTEMPTing an error "is never an error on its 
own", especially as trying it by itself in a console does create 
an error.  
  exit  ;; REBOL says is an error
  attempt [exit]  ;; Brian and I disagree if this is an error

it creates a horribly inconsistent mental model.

You could create a trivia/gotcha quiz arond this. Which of these 
stop with an error?
  attempt [throw]
  attempt [throw 0]
  attempt [throw/break]
  attempt [throw/break 0]
  attempt [throw/name]
  attempt [throw/name 0 0]
  attempt [throw/name 0 'x]
BrianH:
3-Mar-2010
And the first two THROW/name examples are wrong too, because of argument 
compatibility.
BrianH:
3-Mar-2010
THROW 0 is always correct in and of itself. It's not THROW's fault 
you called it outside of a CATCH, it's yours.
BrianH:
3-Mar-2010
No, but it works the same, just faster. Almost all functions that 
had a [throw] attribute in R2 (or needed one, like ATTEMPT) were 
converted to natives in R3. We're still waiting for the new equivalent 
of the [throw] attribute to be added to R3 - right now USE, OBJECT 
and CONTEXT are the only built-in functions that still need it, afaik.
BrianH:
3-Mar-2010
Note that the ticket was marked as a problem, not dismissed (yet). 
The problem was explained in the comments, and more thoroughly now 
in my more recent reply there.
BrianH:
3-Mar-2010
Actually, the first is an error too. It turns out that the way BREAK, 
EXIT, RETURN, THROW, HALT and QUIT work is by throwing pseudo-errors 
that are technically instances of the error! type, but not really 
errors. The ERROR? function disables that throwing for all error! 
values, even the fake ones. It's an error in ERROR?.
Henrik:
3-Mar-2010
From my perspective, attempt [break] is working correctly. ATTEMPT 
has nothing to do with the BREAK, it simply passes it to the outer 
context (if you can say that) and then the BREAK doesn't hold up, 
because it's not inside a function. Seems simple to me.
Henrik:
3-Mar-2010
>> a: does [attempt [exit] 1]
>> a
>>

Looks fine and dandy.
Henrik:
3-Mar-2010
Once, and it did.
Henrik:
3-Mar-2010
Twice, and it did.
BrianH:
3-Mar-2010
The question (only for Carl) is whether task-local runtime contextual 
information can be made available to BREAK, EXIT, RETURN and THROW 
to let them know that they are going to be handled by the console, 
which would let them throw the error that the console should be throwing, 
on behalf of the console. Basically, letting them be more polite. 
The problem is that it is *really* likely (only Carl would know) 
that this would slow down all function! and closure! calls, all loops, 
and every call to DO (even indirectly, as in IF) by quite a bit. 
It could make R3 a lot slower (maybe several times slower).
Henrik:
3-Mar-2010
I'm not sure what you would expect here. Wrapping break and continue 
in attempt has no effect, because we know there are no errors inside 
the attempt block and the context outside is correct for break and 
continue. The attempt has absolutely no effect here.
Henrik:
3-Mar-2010
I'm curious now: How do those functions know they are inside loops 
and functions?
BrianH:
3-Mar-2010
And in REBOL there is no way to statically determine whether an exception 
will be handled without tracing the code. You could in theory determine 
it at runtime (from the internals), but that would have overhead. 
The question is how much overhead.
BrianH:
3-Mar-2010
ATTEMPT and TRY push a handler for exceptions with codes over 100 
on the task-local handler stack. Those exceptions are generated by 
DO MAKE error! (or code called by natives with the same effect).
Sunanda:
3-Mar-2010
Thanks for the repeated attempts to explain, Brian!

For me, the work around is:
    error? try [....]
That seems to work in all cases I have tried.


[Ironically, 99% of all the REBOL code I have ever written uses ERROR? 
TRY --  ATTEMPT did not exist when I started REBOL, and my fingers 
have learned to type the idiom. It's only with R3 that I'ved tried 
to update my error handling.....Seems I should stick with my older 
ways for a while...:)]
Andreas:
3-Mar-2010
The gist of it: I think most control transfer functions should be 
unbound globally, and only bound in code executing within their respective 
control transfer handler.
Andreas:
3-Mar-2010
For example, BREAK should be unbound globally, and bound only within 
loop bodies.
Andreas:
3-Mar-2010
That means, an erroneous use of e.g. BREAK would simply result in 
a "has no value" error, just as the use of any other unset word. 
And this error would of course be nicely caught by ATTEMPT.
Andreas:
3-Mar-2010
And I also think there's an easy way to fix things that they work 
as you expect
Andreas:
3-Mar-2010
I also think it is reasonably straightforward to implement and has 
no significant impact on performance. But I don't have the time to 
write down why I think this, at the moment.
BrianH:
3-Mar-2010
Sunanda, that error? try [....] code you keep mentioning doesn't 
work in all cases you mention. The problem is this:
>> error? break
== true

This is an error (bug#771 and bug#862): It should not return true, 
it should break and then later on trigger an error for an unhandled 
break. To illustrate why:
>> loop 1 [error? break 'buggy]
== buggy

That should have returned unset, not continued. The BREAK is supposed 
to halt execution and resume it somewhere else, either after the 
enclosing loop or at the top level. The same error is affecting your 
error? try [....] code, which is not behaving correctly. 


Your problem, Sunanda, is that you are thinking that ATTEMPT is not 
catching bad code (bugs) that it is supposed to catch - this is not 
strictly true. ATTEMPT isn't supposed to catch bugs, it is supposed 
to catch triggered errors. And a lot of logic bugs don't trigger 
errors, because the code itself is technically correct (what REBOL 
can check for), but not in accordance with the programmer's intentions 
(which REBOL can't know).


Now in this case the logic bug is that you have forgotten that the 
purpose of the BREAK, CONTINUE, THROW, EXIT and RETURN functions 
is escape from the normal flow of the code ("structured" gotos, aka 
non-local returns, exceptions, ...) - you remembered this about HALT 
and QUIT - and didn't realize that the error you are trying to catch 
with ATTEMPT is not in the code that you have wrapped in the ATTEMPT: 
It is not bad code. The error is triggered by the code on the other 
end, the handler, which is not wrapped in the ATTEMPT at all.

So you need to realize that this code is technically correct:
>> attempt [break]
** Throw error: no loop to break
but doesn't do what you thought it should.

And this code is absolutely incorrect:
>> error? try [break]
== true

but doesn't trigger an error because of a weird design quirk in R3 
that is arguably a bug, but not necessarily fixable (see bug#771 
and bug#862).
Paul:
3-Mar-2010
I think we need a way to pass that block so that 'a and 'b can evaluate 
to none
Paul:
3-Mar-2010
It is clear why it setting a and b to 1 but we need to have something 
a bit safer.
BrianH:
3-Mar-2010
We want that behavior and much code depends on it. You can add the 
none explicitly if you need that value.
BrianH:
3-Mar-2010
And CONSTRUCT doesn't evaluate anything, so safety is not an issue.
Paul:
3-Mar-2010
Still we need to check it and we could simply have another switch 
that could fix construct to be even more superior.
Paul:
3-Mar-2010
But let's you access the elements as if they are an object and can 
already exist in a block style spec that can be passed to context.
BrianH:
3-Mar-2010
On the other hand, you can APPEND to objects and maps in R3, so you 
don't need the block at all.
BrianH:
3-Mar-2010
And appending to objects doesn't chain assignments.
Gregg:
4-Mar-2010
Paul, creating your own func is the way to go for that. And emails 
can be very complex. REBOL doesn't try to validate against the true 
grammar, it just looks for @.
Sunanda:
4-Mar-2010
cc#1509 -- Thanks Brian for consolidating a whole handful of bug 
reports [and/or misunderstandings].
That should help focus the core RT crew into clarifying / fixing.
Andreas:
4-Mar-2010
I think that RETURN, EXIT and BREAK, CONTINUE should be only available 
in their respective contexts (functions, and loops). CATCH/THROW 
will need special treatment. QUIT, Q, HALT can be left as is.
Andreas:
4-Mar-2010
This said, and leaving the discussion of improved semantics aside, 
I think that the implementation of improved error causation as described 
by Brian in bug#1506 would be very worthwile and should be pursued.
Paul:
4-Mar-2010
Andreas, I still think that issue should be resolved by introducing 
another function since the cases where we would need such assurance 
is minimal in comparision to the overall application of attempt. 
 Why add more overhead to 98 precent of the cases when you can adapt 
to the 2 percent with another function or just implementing your 
own check and parsing.
BrianH:
4-Mar-2010
Andreas, I don't have a problem with that solution in principle. 
It's just that it wouldn't work, and wouldn't be task-safe. The handlers 
for those functions would be task-local, the code blocks not. Plus 
it would break code that uses code block references rather than nested 
blocks, code that uses those functions through function values, and 
any function with the [throw] attribute (which we will be getting 
back in R3 with different syntax), and all of those exist in R3 mezzanine 
code. Plus there's all the extra BIND/copy overhead added to every 
call to loop functions, startup code, etc., and don't think that 
you won't notice that because that can double the memory usage and 
executiion time, at least.


The solution I proposed in the ticket comments is to have DO, CATCH 
and the loops set a task-local flag in the interpreter state when 
the relevant functions become valid, and unset it when they become 
invalid, then have the functions check the flag at runtime before 
they do their work (which they could because they're all native). 
This would be task-safe, only add a byte of task-local memory overhead, 
plus the execution overhead of setting and getting bits in that byte 
in a task-local way. It's the execution overhead that we don't know 
about, whether it would be too much. It would certainly be less than 
your proposal though.
BrianH:
4-Mar-2010
Carl is the authority on subtle implementation overhead, but for 
gross implementation overhead anyone can tell by just using the profiling 
tools and extraploating. And what you are proposing is definitely 
in the gross overhead category.
BrianH:
4-Mar-2010
However, CATCH/name and THROW/name would need the additional memory 
overhead of a single block of words per task in the dynamic solution 
to store the currently handled names.
BrianH:
4-Mar-2010
It might be hard to believe, but R3 has gotten so efficient that 
BIND/copy overhead is really noticeable now in comparison. In R2 
there were mezzanine loop functions like FORALL and FORSKIP that 
people often avoided using in favor of natives, even reorganizing 
their algorithms to allow using different loop functions like FOREACH 
or WHILE. Now that all loop functions in R3 are native speed, the 
FORALL and FORSKIP functions are preferred over FOREACH or FOR sometimes 
because FOREACH and FOR have BIND/copy overhead, and FORALL and FORSKIP 
don't. The functions without the BIND/copy overhead are much faster, 
particularly for small datasets and large amounts of code.
BrianH:
4-Mar-2010
It's funny: While regular R3 code looks a lot like regular R2 code, 
optimized code looks a lot different because the balance of what 
is fast and what isn't has shifted. At least regular R3 code looks 
a lot more like optimized R3 code than regular R2 code looks like 
optimized R2 code. This is because we have been focusing on making 
the common, naive code patterns more optimized in R3, so that people 
don't have to do as much hand-optimization. The goal is to make it 
so that only writers of mezzanine and library code need to hand-optimize, 
and regular app developers can just use the optimized code without 
worrying about such things.
Andreas:
4-Mar-2010
And if you re-read that, you will notice that it's precisely what 
you later describe.
BrianH:
4-Mar-2010
Btw, non-local code blocks are a common optimization trick in mezzanine 
code, one which shows up a lot in Carl's code. It's probably the 
reason why REBOL supports the concept in the first place. And I've 
written code in REPLACE that uses the BREAK function as a function 
value, though I haven't checked whether other people use this trick 
:)
BrianH:
4-Mar-2010
It seems so. I've asked Carl to look at those tickets and chime in, 
so we'll see what he thinks.
BrianH:
4-Mar-2010
If you want to see how weird really optimized R3 code can get, take 
a look at the source of LOAD and IMPORT - they are probably the most 
heavily optimized mezzanine functions. For the most part the rest 
of the mezzanine code is written for readability and maintainability, 
and the language optimized to make readable code fast. It's a good 
tradeoff :)
BrianH:
4-Mar-2010
IMPORT uses code blocks as a way of reusing duplicate code, though 
it might not be affected either. And REPLACE would be affected because 
'break wouldn't be bound at the point it is used: Being in a function 
isn't enough, it's outside of the loop. BREAK is used to break out 
of loops, not functions.
BrianH:
4-Mar-2010
That means that the BIND/copy overhead for BREAK and CONTINUE would 
happen at every call to a loop function, not just FOR, FOREACH and 
REPEAT. And 'break and 'continue would become keywords rather than 
function names, unable to be used for loop-local variables.
BrianH:
4-Mar-2010
LOOP, WHILE, FORALL and FORSKIP don't currently have BIND/copy overhead. 
Which is why they are used a lot in R3 :)
BrianH:
4-Mar-2010
I don't have the time now to provide examples, I'm afraid, must run 
an errand. Try it yourself and see what you find out :)
BrianH:
4-Mar-2010
REMOVE-EACH and MAP-EACH already have the BIND/copy overhead though.
Andreas:
4-Mar-2010
Only verified it for FOREACH yesterday and assumed that the other 
loop functions that need binding would also copy.
BrianH:
4-Mar-2010
But all the loop functions that take a word argument have BIND/copy 
overhead, and the rest don't.
BrianH:
4-Mar-2010
Already proposed in CureCode, and the R2 2.7.7 version does that 
already.
Gabriele:
5-Mar-2010
Andreas: what you ask for has been discussed extensively when R3 
was started, by me, Ladislav and Carl. There are a number of disadvantages 
to that, starting from the fact that you need to bind/copy a lot 
more than you do now (eg. inside CATCH). It would also, unfortunately, 
not work in cases like this:
Ladislav:
5-Mar-2010
Andreas: "I think that RETURN, EXIT and BREAK, CONTINUE should be 
only available in their respective contexts (functions, and loops)." 
- that is what I preferred too, but Carl did not like it (binding 
takes time).
Ladislav:
5-Mar-2010
Nevertheless, at least for Return and Exist this does not look like 
an issue, since binding is likely to occur anyway in these cases
Ladislav:
5-Mar-2010
and, the speed difference for Return and Exit may still exist, but 
only if the respective function does not have any parameter
Ladislav:
5-Mar-2010
I think that the implementation of improved error causation as described 
by Brian in bug#1506 would be very worthwile and should be pursued.

 - again, this is a thing I discussed with Carl quite long ago, but 
 it seems, that Carl disliked the fact, that the implementation would 
 have to be more complicated, than it currently is, while the effect 
 Sunanda would like to achieve is probably achievable even now
BrianH:
5-Mar-2010
We've been able to find out a lot from stuff posted so far and the 
scientific method though :)
BrianH:
5-Mar-2010
I think a lot of the problems would be solved by just letting developers 
plug in their own recovery code into the console handler, and that 
would be more efficient too.
Ladislav:
6-Mar-2010
(and, you omitted Try)
Carl:
6-Mar-2010
Ladislav: actually, I agreed with you.  RETURN and EXIT should be 
definitionally scoped!
Henrik:
6-Mar-2010
I'm not saying that. I'm just asking if there is any new development 
in error handling between A97 and A98.
Carl:
6-Mar-2010
And also, because it was a hot topic above... with many of the key 
people chatting on it. So, good time to get it finalized.
Henrik:
6-Mar-2010
The example just below that sentence with definitional scoping: I 
agree on that.


I ran into exactly this issue just last night in an attempt to wrap 
some function bodies in a primitive callstack mechanism (R2 code) 
so I could debug it easier. The debugging mechanism kept crashing 
there, because it ran straight through the first 'return and "returned" 
twice.


R3 of course doesn't need function scoped return for that reason, 
since I can already see the stack trace on an error, but for other 
reasons (correctness?).
Carl:
6-Mar-2010
Yes, but word, :word, and 'word are taken.
Paul:
6-Mar-2010
Just so that we can do some dynamic building of blocks with set-words 
and pass it to construct and not worry about a set-word getting assigned 
a value from the chain.
Andreas:
6-Mar-2010
Paul, just iterate through the block before you construct it and 
whenever a set-word! is followed by another set-word! insert a none 
in between.
Andreas:
6-Mar-2010
Write such a function and offer it to be included as mezzanine.
Paul:
6-Mar-2010
Chris, I had an issue where I was putting data into a block dynamically 
and then had a skip pattern over it so that every other word was 
turned into a set-word and then passed to construct.
Andreas:
6-Mar-2010
Paul, set-word!s are syntax for SET. [a: b: 2] is syntactical short-hand 
for [SET 'a SET 'b 2]. SET returns sets a word to a value and returns 
that value. If you don't want to pass the result of (SET 'b 2) as 
argument to SET 'a, then just don't do it.
Andreas:
6-Mar-2010
Great, then write /as-is as a mezzanine for now and propose it to 
be included.
Paul:
6-Mar-2010
And now I would ask you why add that function to R3 when you already 
pass a spec to contruct in the first place?
Paul:
6-Mar-2010
So if I went to falcon or Lua and said do that and they did they 
could say they could handle such code safer than REBOL could.
Paul:
6-Mar-2010
let's say you have a service oreient protocal that is sending unencrypted 
blocks of data that is getting sent into contstruct on the other 
end.   All I have to do is capture it midstream alter the block and 
forward on and I can cause your code to behave differently.
Henrik:
6-Mar-2010
Paul, you don't create services that carelessly evaluate data that 
is potentially manipulated by an attacker. That's a security hole 
and bad coding. That's one of the good things about dialects.
Chris:
6-Mar-2010
Agreed, and that's what this is - a dialect - as Rebol's sop is chaining...
Henrik:
6-Mar-2010
yes, we do. with PARSE and dialects.
Andreas:
6-Mar-2010
And that's what you should do too, Paul.
Andreas:
6-Mar-2010
And no, it's not "all of us", as none of us have those specific needs.
Gregg:
6-Mar-2010
I vote against the proposed change to CONSTRUCT. I believe the need 
is better served with a mezz. If it becomes popular and useful, then 
consider making it part of the standard distro.
BrianH:
6-Mar-2010
Carl, if you make RETURN and EXIT definitionally scoped, it would 
help if the throw: attribute would disable that, so functions like 
USE would work properly. Also, please keep BREAK, CONTINUE and THROW 
dynamically scoped - most of the functions that they break out of 
don't do definition, so making them do so would add unwanted BIND/copy 
overhead.
Ladislav:
7-Mar-2010
Note to the "Should we catch unwinds?" question in the http://www.rebol.com/r3/notes/errors.html
article - the subject of the CureCode #1506 is, that it is (or should 
be) possible for the interpreter to find out, whether the unwind 
would cause a "No catch for throw" type error, and, that Try should 
catch such an "unhandled" unwind.
BrianH:
7-Mar-2010
I wrote a few comments to the blog, explaining the advantages of 
the definitionally scoped RETURN and EXIT proposal. The optional 
function attribute we would need would not change them to dynamically 
scoped, it would just tell the function to not redefine RETURN and 
EXIT within, allowing them to keep their existing bindings. No dynamic 
scoping of those functions would be needed at all.
Geomol:
8-Mar-2010
(Continuing from "Rebol School".)


I've thought about TRY/EXCEPT too, since it popped up a few days 
ago. My thoughts are more about design. Why do we have TRY? Why not 
make /EXCEPT a refinement of DO? DO can do any type, TRY only works 
on blocks. If you wanna do a script on the net, and it can go wrong, 
we have to write:

try/except [do <url>] [<handle error>]

With /EXCEPT on DO, it could be:

do/except <url> [<handle error>]


My point is: is it good to have all these words in the language? 
It may add depth, but it also add confusion and complexity. Maybe 
the depth could still be there with fewer words, and the language 
would be easier?
Henrik:
8-Mar-2010
I don't miss a simplification of DO/TRY as much as structures for 
sequential tests that may or may not fail. REBOL doesn't have anything 
here, so you have to roll your own. Say you're trying to connect 
somewhere in a protocol and one of 50 things can go wrong, so you 
have to state 50 tests, 50 error messages, 50 exit routes. That's 
a lot of lines of almost identical code.
Geomol:
8-Mar-2010
There may be another concern with this. How do we get the error in 
the except block, so we can handle it? A common way is:

if error? result: try [1 / 0] [probe result]

This doesn't work:
(Remember to clear result, if you did the above first.)

result: try/except [1 / 0] [probe result]

And having /EXCEPT on DO is the same problem.
39201 / 4860612345...391392[393] 394395...483484485486487