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

World: r3wp

[Core] Discuss core issues

Geomol
20-Aug-2009
[14506x3]
It does? That's not clear from this example:


>> f: func ['w b] [use reduce [w] reduce [to set-word! w 1 'do 'b]]
>> f i [print i]
** Script Error: i has no value
Changing 'b to b and it works:


>> f: func ['w b] [use reduce [w] reduce [to set-word! w 1 'do b]]
>> f i [print i]
1

(Still a bit confused.)
Is it possible to give a function with a refinement as an argument 
to another function? If I e.g. would make a MAP function in REBOL, 
it could be:


>> map: func [:function list /local result][result: clear [] foreach 
value list [append result function value]
>> map sine [0 15 100]
== [0.0 0.258819045102521 0.984807753012208]


MAP apply the function to each member of the list. But I can't give 
sine/radians to map:

>> map sine/radians [0 15 100]
== 100

Is there a way around this?
Sunanda
20-Aug-2009
[14509]
You could use the MAP syntax that R3 uses (soon to be renamed MAP-EACH)

 map x [0 15 100] [sine/radians x]
== [0.0 0.650287840157117 -0.506365641109759]
Geomol
20-Aug-2009
[14510x2]
It seems to work, if I put DO before function:


map: func [:function list /local result][result: clear [] foreach 
value list [append result do function value]]
It's because, sine/radians is seen as a path! datatype, when the 
argument is defined as :function
Chris
20-Aug-2009
[14512]
G: re. confused - try stepping through the function in the order 
it is interpreted.  Should be clear by the time 'use evaluates the 
two blocks...
Graham
21-Aug-2009
[14513x5]
Anything more efficient than this?



findall: func [s items [block!] /local result][result: copy [] foreach 
i items [repend result [find s i]]]
I want to make sure each item in the block of items occurs in the 
series S
reformatted 

findall: func [s items [block!] 
	/local result
][
	result: copy [] 
	foreach i items [repend result [find s i]]
	all result
]
if the first item is not found, it still searches all the rest which 
is no good
is this something that one can use 'map for?
Geomol
21-Aug-2009
[14518x2]
Using INTERSECT leads to a shorter function, but I'm not sure, it's 
the fastest way:

findall: func [s items [block!]] [items = intersect s items]
Being danish, I'm wondering, if the word INTERSECTION cover the same 
meaning as a JOINT set? If yes, why isn't INTERSECT called JOINT?
Graham
21-Aug-2009
[14520x3]
I guess joint is commonly used for marijuana
>> findall "this is a test string" [ "this" "not here" ]
** Script Error: Expected one of: string! - not: block!
** Where: findall
** Near: items = intersect s items
>>
graham- findall "this is a test string" [ "this" "not here" ]
== none
Geomol
21-Aug-2009
[14523x2]
I guess joint is commonly used for marijuana


LOL, I didn't see that! (And I went to a Reggae festival last week, 
so I should know.) :-)
Do you want your function to find "ring" in this string: "this is 
a test string"?
Graham
21-Aug-2009
[14525]
yes
Sunanda
21-Aug-2009
[14526]
Geomol -- your code works only if the blocks are sorted, and contain 
no duplicates:
     findall [5 4 3 3 2 1] [3 2 1 1]
     == false
One way to fix that:

     findall: func [s items [block!]] [0 = length? exclude items intersect 
     s items]
     findall [5 4 3 3 2 1] [3 2 1 1]
     == true

But it does not help much with Graham's example which is looking 
for substrings :(
Geomol
21-Aug-2009
[14527]
What about this version?


findall: func [s items [block!]] [foreach i items [if not find s 
i [return false]] true]
Graham
21-Aug-2009
[14528x2]
I thought with map you can apply a function over all the parameters 
...
looks good
Geomol
21-Aug-2009
[14530x3]
Yes, you can with map, but you want it to stop, if one item isn't 
found, so not on all parameters.
Chris wrote: "G: re. confused - try stepping through the function 
in the order it is interpreted.  Should be clear by the time 'use 
evaluates the two blocks..."


What I find a bit confusing is, when I have to BIND and when I don't. 
It's the context binding rules in REBOL, that is not 100% clear to 
me. Let me give a simple example:

>> b: [print i]
== [print i]
>> f: has [i] [i: 1 do b]
>> f
** Script Error: i has no value


This doesn't work, because the b block is defined outside the f function, 
outside f's function context. Therefore I have to bind b to f's context, 
like this:

>> f: has [i] [i: 1 bind b 'i do b]
>> f
1


That is clear, and I would expect USE to work by the same rules, 
but it doesn't quite, it seems to me:

>> f: does [use [i] [i: 1 do b]]
>> f
1


By some magic, this works without the need to BIND. I'm a bit confused 
by that.
ARGH! It only works, because I first made the f function using BIND. 
So b was already bound to f, when I changed f to include USE. If 
I try to USE version from a fresh REBOL, it doesn't work. (More confusion!) 
:-p
Anton
21-Aug-2009
[14533x2]
Graham, I think your FINDALL is not well named. Just because it's 
using FIND doesn't mean it's doing the same thing. It should be more 
like COLLECT-ALL or COLLECT-EVERY.
Sorry, I'm wrong. Wrote too quickly.
Geomol
21-Aug-2009
[14535]
Ok, from a freshly started REBOL, this doesn't work:

>> b: [print i]
== [print i]
>> f: does [use [i] [i: 1 do b]]
>> f
** Script Error: i has no value

But this does work:

>> b: [print i]
== [print i]
>> f: does [use [i] reduce [to set-word! 'i 1 'do b]]
>> f
1


Is it because, when b is reduced, I kinda get a new fresh copy of 
the block? Like if I wrote the block, [print i], myself instead of 
using a reference to b?
Anton
21-Aug-2009
[14536]
REDUCE makes a new block, and then USE does its binding.
Geomol
21-Aug-2009
[14537]
Oki doki, that explains it.
Anton
21-Aug-2009
[14538x2]
BIND recurses into blocks, eg. 'b will be bound in the nested block 
[[b]],

but if 'b happens to currently have a value that is a block with 
words in it, that doesn't matter to BIND, BIND won't go in there.
Let me say that again, to be clear.

eg. Binding [[b]] somewhere will cause 'b to be bound (as long as 
'b exists in the "somewhere" context).

but if, before this bind occurs, b has a block value eg.  b: [some 
words] , then the bind will not touch 'some and 'words,

because it won't look to recurse into word values that happen to 
be blocks.
Geomol
22-Aug-2009
[14540]
How to check for a datatype using TYPE? within a function in REBOL 
2? Let's say, I wanted to create my own ACTION? function using TYPE?:

>> a?: func [value] [action! = type? value]
>> a? :action?
== false

Doesn't work. Does the logic work outside a function?

>> action! = type? :action?
== true

Yes. So maybe I need to specify the argument as a get-word! ?

>> a?: func [:value] [action! = type? value]
>> a? action?
== false

No, still doesn't work. Now on to REBOL 3 to see, how that work:

>> a?: func [value] [action! = type? value]
>> a? :action?
** Script error: value is missing its value argument

Huh? Trying with a get-word! :

>> a?: func [:value] [action! = type? value]
>> a? action?
== false

No, doesn't work. What am I missing? Or is it bugs?
Anton
22-Aug-2009
[14541]
Try this in the console:

	>> action?
	== false


No arguments were provided. The function can accept unset! values.
Geomol
22-Aug-2009
[14542x2]
Anyone got an old REBOL 1 lying around, I could have a look at?
Anton, ah, but my function doesn't work with other action! values 
anyway:

>> a?: func [:value] [action! = type? value]
>> a? first

** Script Error: value expected series argument of type: series pair 
event money date objec
t port time tuple any-function library struct ...

Trying dobble get-word! :

>> a? :first
== false

So maybe this doesn't work with any action! datatype?
Anton
22-Aug-2009
[14544x2]
It looks like your a? function evaluated the argument 'value. (I 
forget what get-word function parameters do...)
Works better like this:

	a?: func [value][action! = type? :value]
Better is
	a?: func [value][action? :value]
Geomol
22-Aug-2009
[14546x4]
>> a?: func [value] [action! = type? :value]
>> a? :action?
== true

Bravo!
My mistake. I get it now!
Thanks!
Anyone got an old REBOL 1 lying around, I could have a look at?
Anton
22-Aug-2009
[14550]
I noticed a get-word parameter prevents a paren argument value being 
evaluated first.
>> f: func [a][print mold a]
>> f (action?)
false
>> f: func [:a][print mold a]
>> f (action?)
(action?)
Geomol
22-Aug-2009
[14551x5]
Yeah, and you would probably like it to be mold :a in the function 
to not do the same mistake, I did. In your first example, you have 
evaluation of a two times, first as (action?) leading to false, and 
then false is evaluated when doing mold a.
Hey, I just read all that again. I can't figure out, why your second 
example returns (action?). That parenthesis should be evaluated, 
when you write mold a, shouldn't it?
It's the same in R3.
On the other hand, with the current behaviour, paren! works as block! 
in such situations. Blocks are not evaluated, when we write mold 
a, and a is a block. So why should a, if a is a paren! ? :-)
>> p: to paren! [a b c]
== (a b c)
>> mold p
== "(a b c)"

That's ok, I think.