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

World: r3wp

[!REBOL3]

Geomol
17-May-2011
[8671x2]
Gab, doesn't Scheme have such syntax, we don't like?
Seem to have all the paranthesis, Lisp have.
Ladislav
17-May-2011
[8673x2]
This needs some thought, Geomol. Actual example:

f1: closure [/local a][a: 1 [a]]
f2: func [blk /local a][a: 2 do blk]
f3: func [blk /local a][a: 3 do bind blk 'a]

>> f2 f1
== 1

>> f3 f1
== 3
Now tell us, how your preferred code achieving the same result should 
look like.
Geomol
17-May-2011
[8675x2]
I wouldn't have closure, but use object instead (or context, as I 
call them), if that functionality is wanted. And block content isn't 
bound to start with, so if I write:

>> f1: [a]
>> f2: func [blk /local a] [a: 2 do blk]
>> f2 f1
== 2


because 'a' inside f1 is bound to local 'a' in f2, when evaluated. 
If I want another 'a', I could write:


>> context [a: 1 set 'f1 compile [a]]	; f1 will be a block, [a], 
where the 'a' is bound to 'a' in the context
>> f2 f1
== 1

and the last result could be achieved:

>> f3: func [blk /local a] [a: 3 do compile blk]
>> f3 f1
== 3


Calling f3 will be slower, as blk is recompiled each time. This language, 
I illustrate, isn't REBOL, but another with many similarities to 
REBOL, but with a compile function. Maybe kinda the same could be 
achieved in REBOL, if the binding rules was changed, and "compile" 
in my examples above was changed to a "rebind" function.
I need to think it through, if other unwanted consequences is the 
result of this. I'm just wondering, why it's designed as it is in 
REBOL.
Ladislav
17-May-2011
[8677x2]
I wouldn't have closure

 do I understand correctly, that you do want the programmers to enjoy 
 the benefits of having closures?
err, "do not want" is what I wanted to write
Geomol
17-May-2011
[8679]
Well, if function variables is needed, after the function is finished, 
then it can be achieved by putting the function in a context, and 
have the local vars be vars in the context instead. It's simpler, 
I think, to program.
Ladislav
17-May-2011
[8680]
It is not simpler, you just are forbidding a useful feature.
Geomol
17-May-2011
[8681]
I guess, the closure functionality could be achieved by a mezzanine 
and using object! and function! datatypes without having closure! 
datatype. I'm not an expert in closures, so I may be wrong. Are there 
more to them?
Ladislav
17-May-2011
[8682]
So, if you would not forbid the CLOSURE to be implemented as a mezzanine, 
my question remains valid.
Geomol
17-May-2011
[8683]
Is a closure a function, where the vars is in a map (or whatever 
data structure is used for an object/context) instead of on the stack?
Ladislav
17-May-2011
[8684]
You can have a look at

    source closure

in 2.7.7 or above
Geomol
17-May-2011
[8685]
I wouldn't and couldn't forbid closures, if they could be implemented 
using function! and object!, even if the language didn't have closure! 
.
Ladislav
17-May-2011
[8686x2]
In that case, as already mentioned, my example remains valid, and 
the question is, how would you want to implement that functionality.
(the above implementation does not use the object! datatype)
Geomol
17-May-2011
[8688x2]
I just noticed. Interesting! :) I need to read the source to "closure" 
closely.
Do you follow my ideas for blocks without default binding? I think, 
it could work.
Ladislav
17-May-2011
[8690]
So, my question was, how would you implement F1, F2 and F3 in your 
hypothetical language to get:

>> f2 f1
== 1

>> f3 f1
== 3
Geomol
17-May-2011
[8691x3]
It is not simpler, you just are forbidding a useful feature.


If closure! could be avoided, then the C source for the language 
is simpler. That's what I mean. If the closure functionality can 
be achieved by a mezzanine, nothing has been forbidden. Of course, 
if the language doesn't have problems with keeping the C source simple, 
a closure! datatype could be included, as it would possible be faster.
I already gave examples to do that. They were:

>> context [a: 1 set 'f1 compile [a]]
>> f2: func [blk /local a] [a: 2 do blk]
>> f2 f1
== 1
>> f3: func [blk /local a] [a: 3 do compile blk]
>> f3 f1
== 3


I haven't finished reading about CLOSURE, so maybe it can be even 
simpler.
Isn't it correct, that the CLOSURE mezzanine in R2 only work (without 
using object! in any way), because functions are already closures 
in R2?
BrianH
17-May-2011
[8694]
Nope.
Geomol
17-May-2011
[8695x4]
Yeah, it is. Else the CLOSURE mezzanine would work in R3 with R3's 
functions, and it doesn't.
Why does R2's CLOSURE parse of set-word! in the spec? Doesn't make 
sense.
parse *for* set-word!
It would be easier in R2 to create CLOSURE this way:

>> closure: :func
>> f: closure [a b] [[a + b]]
>> do f 1 2
== 3
BrianH
17-May-2011
[8699]
R3 has two context types: object and function. R2 only has one context 
type: object. This is why you can create a persistent context using 
a function in R2, while you can't in R3.
Geomol
17-May-2011
[8700]
I know. So functions are closures in R2.
BrianH
17-May-2011
[8701x4]
R2's functions have object contexts that are reused on subsequent 
calls, so you can't count on the context to persist if the function 
is called again. That is the difference between R2's functions and 
R3's closures.
Creating a new context every time the function is called is the whole 
point to closures, the only reason that you would use them instead 
of a function.
The PARSE statement in CLOSURE creates the code for a call to a function 
that the resulting outer function creates every time it is called. 
If you want to understand what the PARSE statement is doing, make 
a function with CLOSURE and look at its source.
Why does R2's CLOSURE parse of set-word! in the spec?


The set-word! in the PARSE spec is a special-case, so that set-words 
aren't counted in the set word any-word! portion of the next alternate 
in the rule. Set-words in function specs are keywords for special 
purposes in function creation (just return: in R2), they don't refer 
to parameters, and the other word types are collected as parameters.
Geomol
17-May-2011
[8705]
Creating a new context every time the function is called is the whole 
point to closures

And R2 is not doing this with its functions?
BrianH
17-May-2011
[8706x3]
>> f: func [a] ['a]
>> w1: f 1
== a
>> w2: f 2
== a
>> get w1
== 2    ; note that the value has changed

>> c: closure [a] ['a]
>> w1: c 1
== a
>> w2: c 2
== a
>> get w1
== 1    ; note that the value persists
>> source c

c: func [a][native action function! [[throw] :a [any-type!]] ['a] 
a]
Those first three values in the source of C are direct references 
to the functions DO, MAKE and the type function!, so there are no 
word conflicts.
Geomol
17-May-2011
[8709]
(just return: in R2)

Can you create a function with a return: set-word! in the spec?
BrianH
17-May-2011
[8710]
The type is reserved for future use. If it's an error, the MAKE function! 
at the end will catch it.
Geomol
17-May-2011
[8711x2]
Where did you get this info?
Interesting example, you gave with W1 and W2. Funny how recursive 
functions works then!?
BrianH
17-May-2011
[8713]
From Carl, years ago. Set-words in function specs are supposed to 
be used for more in R3 later.
Geomol
17-May-2011
[8714]
Did Carl write about the set-word! in function spec anywhere?
BrianH
17-May-2011
[8715x2]
There is a bug in CLOSURE though. This line:
    insert tail bdy to word! :word

will have problems with some datatypes. I'll fix it for the next 
version.
Set-words in function specs are used by the routine! type now.
Geomol
17-May-2011
[8717]
It's not so good and almost sad, that Carl used so much energy to 
include new stuff (like also routine!) instead of concentrating on 
making the old stuff (from R2) work correctly first.
GrahamC
17-May-2011
[8718]
And now he's burnt out?
BrianH
17-May-2011
[8719]
R2 has routine!, R3 doesn't.
Geomol
17-May-2011
[8720]
I would expect anybody to be burnt out when taking that approach 
to things. It's like building a skyscraper by loosely make all floors 
first, then trying ot fix everything. Better to get first floor solid 
before moving on.