r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

DanielSz
31-Aug-2007
[8659x4]
Gregg, do you mean Finite State Machine. Care to expand?
Ok, here is an updated version of 'retry. What is it?  It is a higher 
-level function that takes as input a user function and repeats it 
the number of times specified. The current version handles user functions 
that take arguments.
Usage:

retry :user_function 5 

For a user function that doesn't take arguments

retry/args :user_function 5 [args]

For a user function that take arguments


retry: func [user_function [function!] retries [integer!] /local 
.retry [function!] tries [integer!] value [any-type!] args_length 
[integer!] /args block [block!]] [
	tries: 0
	args_length: length? first :user_function

 if ((args_length > 0) and (not args)) [print ["User function require" 
 args_length "arguments. Provide them in a block and use the /args 
 refinement."] return]
	if not args [args_length: 0 block: []]
	.retry: func [.user_function [function!]] [

  either not error? try [value: do compose [.user_function (copy/part 
  block args_length)]]
			[
			if not unset? value [return value]
			]
			[
			print "Retrying..."
			tries: tries + 1

   if tries > retries [print rejoin ["Tried function " tries " times. 
   Exiting"] return]
			.retry :.user_function
			]
	]
	.retry :user_function
]

Everybody is invited to improve on this.
I wrote 'retry to use in scripts heavy in network calls where failure 
is, by nature of the internet, common, so instead of aborting when 
such a failure occurs, I can use 'retry to repeat individual functions 
any number of times I wish, improving the success of the script.
Gabriele
1-Sep-2007
[8663x2]
>> retry: func [code times] [
[    loop times [
[        attempt [
[            break/return do code
[            ]
[        ]
[    ]
>> retry [1 / probe -1 + random 2] 5
0
1
== 1
DanielSz
1-Sep-2007
[8665x5]
Very elegant, and concise, Gabriele. Maybe you can propise have an 
expanded version to handle arguments the code should be invoked with
Sorry, I pressed Enter by mistake, here I go again: Very elegant, 
and concise, Gabriele. Maybe you can propose an expanded version 
that can handle arguments that the code should be invoked with.
That's what 'retry currently does.
If you provide that capabilty, I take your version in no time. Mine 
is too obscure.
Another requirement is tthat if the code returns a value, retry should 
return that exact same value as well. I believe your version currently 
doesn't.
Ingo
1-Sep-2007
[8670x2]
After reading about /no-set to reduce, is this an error? / inconsistency?

>> reduce ['s: 3 * 3]
== [s 9]
shouldn't it be

== [s: 9]

?
Gabriele
1-Sep-2007
[8672x3]
Daniel, since my version takes a block, you can pass as many args 
as needed.
example: retry [user-function arg1 arg2 arg3 ...] 5
of course, it could be enhanced by reporting the error instead of 
returning none if it fails more than the given times, and so on.
DanielSz
1-Sep-2007
[8675x10]
I was going to apologize to you, Gabriele, a few minutes ago I had 
the sudden realization that your version can indeed handle user-function 
with arguments, as your latest post explains.
Your version really makes rebol shine. Its expressiveness is beyond 
par. Bravo.
Gabriele, just one thing, imagine the following user function: f1: 
func [] [return "f1 body"]
Now: retry f1 4 yields none.
It should return "f1 body", no?
Antoher issue that might be a rebol bug is the use of attempt. Normally 
attempt should return a none  value when an error occurs, but consider 
this.
f2: func [] [ do [1 + "x"]]
>> retry f2 4
** Script Error: Cannot use add on string! value
** Where: f2
** Near: 1 + "x"
That's not what we want.
Again apologies, again my stupidity, all the issues I raised in the 
latest posts are non issues, I made a mistake referencing my functions, 
it should be retry :f1 4, retry :f2 4 (note the colon before the 
function name). and then it behaves as expected. Thanks, Gabriele, 
for this humbling lesson in rebol.
[unknown: 5]
1-Sep-2007
[8685]
shouldn't poke work on port data if pick does?  Seems strange behavior 
for it not to
Gabriele
2-Sep-2007
[8686x2]
i'd actually suggest retry [f1] 4  or   retry [f2] 4   with my code. 
 :f also works but if f takes arguments it would break. so it's cleaner 
to just always use a block.
actually, there is one problem with return, which is if you want 
to do   retry [... return 'something ...]  and have it return from 
the calling function, not retry (like if cond [return 'something]). 
to allow that, you need to add the [throw] func attribute, ie. retry: 
func [[throw] code times] ...
DanielSz
2-Sep-2007
[8688x2]
Thanks for the advice, Gabriele, I'll play around with it for a while...
Gabriele, I'm trying to understand in what kind of situation a throw 
is required. f1: func [] [if true [return "something"]] works without 
a throw, for example. Can you provide a concrete example of code 
that requires the throw attribute to 'retry? Thanks!
Gabriele
3-Sep-2007
[8690x3]
i'm not sure it is needed or not for retry. it depends on how you 
use it.
f: func [] [
    retry [
        ; do something...
        if cond [return something-else]
        ; ...
    ]
    some-val
]
if you want the return inside retry to return from F and not RETRY, 
then you need [throw].
DanielSz
3-Sep-2007
[8693]
Thanks, Gabriele, I haven't thought about that.
Joe
4-Sep-2007
[8694x3]
is the sort block dialect broken ?
b-test: ["xxx" "V" 4 "xxx" "M" 3 "yyy" "Laaaa" 2 "yyy" "Lbbbb" 2 
"yyy" "Kaaaa " 2 "yyy" "Haaaa" 2 "yyy" "Aaaaa" 2]

									print ["init               " mold b-test]

sort/skip/compare b-test 3 [reverse 3 2] 			print ["reverse 3 2  
      " mold b-test]

sort/skip/compare b-test 3 [reverse 3 reverse 2]	print ["reverse 
3 reverse 2" mold b-test]
It seems to use the first reverse 3 but ignore the second comparator. 
Any ideas ?
btiffin
4-Sep-2007
[8697x2]
Joe;  I think you need to pass sort/compare a function! not a block! 
 The function template is [a b] and returns true or false or whether 
to swap.  Something like
sort/compare data func [a b] [a > b]

(Note: the names a and b could be any words but the function is called 
with two arguments).
Never mind my blabbering.  Learned something new today.  :)
Graham
5-Sep-2007
[8699]
Can someone remind me how bind a bunch of words to a different context? 
 I want to use the named colors in a special context.
Chris
6-Sep-2007
[8700]
colors: context [red: 255.0.0 green: 0.255.0 blue: 0.0.255]
reduce bind [red green blue] in colors 'self
Graham
6-Sep-2007
[8701]
I'll give it a go :)
[unknown: 5]
6-Sep-2007
[8702]
anyone know if REBOL runs on PocketPC?
Graham
6-Sep-2007
[8703x2]
core used to ...
wince 1.1 ?
james_nak
6-Sep-2007
[8705]
I don't know if the CE version does but: http://www.rebol.com/platforms-core.html
 (Note: these are oldies but goodies)
btiffin
7-Sep-2007
[8706]
Graham;  To quickly get all the colours, try
rebol []


do-thru http://www.rebol.org/library/scripts/capture.rcapture on 
help tuple! capture off
colors: copy []
parse to block! find get-captured newline [
    some [set col word! (append colors col) word! tuple!]
]

;; This will fail, no context
print disarm try [get first colors]
;; Now bind the words to the REBOL context
bind colors 'red  print get first colors
Gregg
10-Sep-2007
[8707]
Joe, did you try "[reverse 3 forward 2]" as your comparator?
btiffin
11-Sep-2007
[8708]
Request for opinions;  What would you rather read? 
   var: none
...
   var: either flag [value] [none]
or 
   var: if flag [value]


Assuming var can safely be none or a value but the init may not be 
close to the code.