World: r3wp
[Core] Discuss core issues
older newer | first last |
[unknown: 5] 23-Mar-2008 [9643x3] | >> str: "this is just a test of replace-all" == "this is just a test of replace-all" >> replace-all str #"t" #"d" == "dhis is jusd a desd of replace-all" |
The case did cut it down a bit on the evals: >> replace-all b 1 2 == [[2] [[[2]]] [2]] >> stats/evals == [209 100 42] | |
I would say that is one heck of a useful function | |
BrianH 23-Mar-2008 [9646] | I've been using timblk to profile, not stats. How useful have you found stats to be? |
[unknown: 5] 23-Mar-2008 [9647x4] | its pretty useful. Btiffin mentioned timblk also. I will have to look for it sometime. |
replace-all: func [ "Replaces all occurences of old value with new value" series "Series containing values to replace" oldval "Value to be replaced" newval "New value to replace old value" /local subf ][ subf: func [sd][ while [not tail? sd ][ case [ equal? first sd :oldval [poke sd 1 :newval] series? first sd [subf first sd] ] sd: next sd ] ] subf series series ] | |
same function just commented a bit and changed sub-ic to just subf meaning subfunction | |
catch throw-on-error? | |
BrianH 23-Mar-2008 [9651] | Add the [series!] type check to the series parameter of the outer function and you'll be set. |
[unknown: 5] 23-Mar-2008 [9652] | oh yeah |
BrianH 23-Mar-2008 [9653] | catch throw-on-error What do you mean? |
[unknown: 5] 23-Mar-2008 [9654x2] | Should it throw errors to a catch so that it doesn't expose the lower code? |
not sure how that would behave in this case | |
BrianH 23-Mar-2008 [9656] | You aren't doing anything in the inner code that could generate an error, so no need. |
[unknown: 5] 23-Mar-2008 [9657] | If were sure that all the values that it traverses are comptible then I agree. In fact I don't think we need one until it becomes known as a problem. |
BrianH 23-Mar-2008 [9658] | The only problem would be if your blocks have cyclic references and you get stack overflow. I'm not sure you can catch that. |
[unknown: 5] 23-Mar-2008 [9659] | replace-all: func [ "Replaces all occurences of old value with new value" series [series!] "Series containing values to replace" oldval [any-type!] "Value to be replaced" newval [any-type!] "New value to replace old value" /local subf ][ subf: func [sd][ while [not tail? sd ][ case [ equal? first sd :oldval [poke sd 1 :newval] series? first sd [subf first sd] ] sd: next sd ] ] subf series series ] |
BrianH 23-Mar-2008 [9660] | Don't put [any-type!]. The only difference between that and no type spec at all is that your function would be able to accept unset! values, and that would require other changes to your code to work properly. |
[unknown: 5] 23-Mar-2008 [9661x4] | here this is better to read: |
ahhh good point. | |
replace-all: func [ "Replaces all occurences of old value with new value" series [series!] "Series containing values to replace" old-value "Value to be replaced" new-value "New value to replace old value" /local subf ][ subf: func [sd][ while [not tail? sd ][ case [ equal? first sd :old-value [poke sd 1 :new-value] series? first sd [subf first sd] ] sd: next sd ] ] subf series series ] | |
I changed newval to new-value and oldval to old-value | |
BrianH 23-Mar-2008 [9665] | That is the REBOL way :) |
[unknown: 5] 23-Mar-2008 [9666] | hehe - looks good. |
BrianH 23-Mar-2008 [9667] | In general, I find that it is a good idea to let unset! values be erroneous, rather than changing your code to accept them. That makes it easier to make a clear distinction between non-values that are erroneous (unset!) and non-values that may not be erroneous (none!). |
[unknown: 5] 23-Mar-2008 [9668x4] | good tip |
Is it a good practice to unset series within functions if the series is an argument to the function? Not sure how the garbage handler in REBOL works or if it sees it as garbage until the next function call. | |
In other words if i pass a massive series of data as an argument to the function should I at the end of the function unset that argument? | |
I wish Carl would give us pointers on when to use unset function and how to optimize our use of the memory space and other performance tips. | |
BrianH 23-Mar-2008 [9672] | That was something I brought up during R3 development. R3 series don't retain references between calls, R2 series do. In general this is not a problem, but if the extra references are becoming a memory leak, change this: series to this: also series series: none |
[unknown: 5] 23-Mar-2008 [9673] | what is also? |
BrianH 23-Mar-2008 [9674] | You almost never need to use the UNSET function; setting to none is usually sufficient. |
[unknown: 5] 23-Mar-2008 [9675] | interesting. |
BrianH 23-Mar-2008 [9676] | ALSO is one of the R3 backports in 2.7.6. Here: also: func [ {Returns the first value, but also evaluates the second.} value1 [any-type!] value2 [any-type!] ][ get/any 'value1 ] |
[unknown: 5] 23-Mar-2008 [9677] | ok I remember some discussion about that. |
BrianH 23-Mar-2008 [9678] | This is one of those cases where unset! wouldn't be an error, so the code handles it. |
[unknown: 5] 23-Mar-2008 [9679] | It would be any problem? wouldn't the get/any cause a problem if it encountered the unset!? |
BrianH 23-Mar-2008 [9680] | That's what the /any is for. |
[unknown: 5] 23-Mar-2008 [9681x3] | indeed |
don't know that include unset! | |
don't = didn't | |
BrianH 23-Mar-2008 [9684x8] | RobertS, have you tried initialization functions? |
I think your INITIAL and INITIALLY functions could be combined though. | |
initially: func [[throw] tag [word!] code [block!] /local tags] [ tags: [] unless find tags tag [ insert tail tags tag do code ] ] | |
I suppose a catch attribute would be appropriate to add to the function too. | |
Or you could eliminate the tag: initially: func [[catch throw] code [block!] /local done] [ done: [] unless find done code [ insert tail done code do code ] ] | |
Sorry, not insert, insert/only. | |
It relies on the FIND finding blocks based on whether they are the same, not equal. That means that the reference to the code block that is passed to INITIALLY can itself be used as a tag. | |
Final version: initially: func [[catch throw] code [block!] /local done] [ done: [] unless find done code [ insert/only tail done code do code ] ] | |
[unknown: 5] 23-Mar-2008 [9692] | Rambo 3115 submitted for desire to include the replace-all function. |
older newer | first last |