• 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
r4wp1023
r3wp10555
total:11578

results window for this page: [start: 9401 end: 9500]

world-name: r3wp

Group: !REBOL3 ... [web-public]
BrianH:
23-Mar-2010
What if you want to emulate another language's OOP model? Or not 
do OOP at all? Or use functions like FOR, FOREACH, MAP-EACH, REMOVE-EACH 
and REPEAT in functions that are defined in an object, module or 
script? (That means every single time, btw)
Ladislav:
23-Mar-2010
re your question, Steeve: if you ask for the code to be evaluated 
by For, do you expect, that For binds some words in the block it 
evaluates in addition to the words you specify? I doubt it, and it 
makes a problem.
Steeve:
23-Mar-2010
honestly , i would never do such thing (to be forced to use a path/var 
just to avoid name collisions) because i know paths are slower to 
evaluate than immediate words.
And I don't do that in R2 too for the same reason.
Steeve:
23-Mar-2010
but there is no gain to illlustrate your point with something I would 
never do because simpler ways exist, no ?.
Ladislav:
23-Mar-2010
Actually, not, the only problem is, that for you it is a "not real-world 
enough" code. In that case, feel free to find any example, which 
would be "real world enough" for you, I do not claim to know, what 
it is.
Ladislav:
23-Mar-2010
This reminds me a good and funny local novel. Just to paraphrase:

S: "draw any triangle"
L: "here you are"
S: "this is not any triangle, it has a right angle!"
L: "here is another one"
S: "this is not any triangle, it is an isosceles triangle"
...etc, ad infinitum

as I said, I do not claim that I know, what is "real-world for you", 
and I do not see any point in your trying to convince me I am right
BrianH:
23-Mar-2010
this problem cannot be 

cured" by bind/no-self, since it requires the user to always know, 
how he wants to bind the words in the block, while such an information 
is already "automatically available" (as can be proven in R2)"


This is not true. In the case of USE, REPEAT, FOR, FOREACH, MAP-EACH 
and REMOVE-EACH we don't want the hidden 'self to be bound to the 
code block, but we *do* want the hidden 'self to be there in the 
context. In case the context persists beyond the execution of the 
function, it should be like a normal object context. The same goes 
for closures. Only for functions do the contexts not have indefinite 
extent (in R3) - they are stack-relative, so don't work beyond the 
return of the function.


However, in the case of your proposal to not have the 'self in some 
contexts, there is no way to specify that option in MAKE object! 
syntax, so the user can't tell whether it is the case or not. This 
is similar to the map! case-sensitivity option - we can't do it because 
we don't have the syntax. And we don't want to have anything that 
affects behavior on non-blackbox types that we can't see in MOLD 
or MOLD/all.
Ladislav:
23-Mar-2010
''In the case of USE, REPEAT, FOR, FOREACH, MAP-EACH and REMOVE-EACH 
we don't want the hidden 'self to be bound to the code block, but 
we *do* want the hidden 'self to be there in the context." - yes 
some may want all Rebol contexts to be isomorphic with objects, erasing 
a (perceived by me as useful) information (whether the context is 
supposed to be handled using BIND or BIND/NO-SELF, when applied on 
a block), which is present in R2, where the simple usage of BIND 
always does the right thing. It surely is a matter of preferences, 
that is why I am asking other users, what is more natural for them.
Ladislav:
23-Mar-2010
''In the case of USE, REPEAT, FOR, FOREACH, MAP-EACH and REMOVE-EACH 
we don't want the hidden 'self to be bound to the code block, but 
we *do* want the hidden 'self to be there in the context." - yes 
some may want all Rebol contexts to be isomorphic with objects, erasing 
a (perceived by me as useful) information (whether the context is 
supposed to be handled using BIND or BIND/NO-SELF, when applied on 
a block), which is present in R2, where the simple usage of BIND 
always does the right thing. It surely is a matter of preferences, 
that is why I am asking other users, what is more natural for them.
BrianH:
24-Mar-2010
Ah, but that's the problem. When that context is used by FOR, I want 
'self to not be bound. However, if the context persists after the 
FOR returns then I want BIND to do the 'self trick with any subsequent 
use of that same context; this is what I mean by "like a normal object 
context". That inconsistency is "the right thing". Having BIND not 
do the 'self trick based on some hidden quality of the object is 
*bad*. It means that I can't predict the behavior of BIND unless 
I know the originator of the object, and in many cases that wold 
mean dataflow analysis.
BrianH:
24-Mar-2010
This is another example of trying to make the interpreter second-guess 
the user and try to do they they "mean to do". That inevitably ends 
up in disaster. I don't want REBOL to do what I "mean to do", I want 
it to do what I *say* to do. I want its behavior to be utterly predictable 
given the same input (except deliberate indeterminacy functions like 
RANDOM). If it isn't then it's not as useful to programmers.
BrianH:
24-Mar-2010
I don't want REBOL to guess whether I would want BIND or BIND/no-self 
to be used: I've already said so, do what I say to do :)
Ladislav:
24-Mar-2010
When that context is used by FOR, I want 'self to not be bound. However, 
if the context persists after the FOR returns then I want BIND to 
do the 'self trick with any subsequent use of that same context; 
this is what I mean by "like a normal object context". - yes, and 
that is, where our POVs differ - similarly as Brian, I do not want 
one thing: I do not want Bind to behave differently when used twice, 
since it is not the right thing in my opinion - it means, that I 
cannot predict the behaviour of Bind unless I know the originator 
of the context. are there any other opinions, than mine and Brian's 
on this?
Ladislav:
24-Mar-2010
Brian does not want to Rebol to guess, but he actually forces it 
to do so - R3 now guesses, that you want to bind 'self, unless you 
say otherwise. In case of R2, that is not the case - Rebol does not 
guess, since it uses the context as defined by the user.
BrianH:
24-Mar-2010
Ladislav, your suggestion to have some contexts not have the hidden 
'self in them at all is not what you think. You are suggesting that 
we create object! contexts (for that is what all contexts are except 
for function! contexts) that *can't* be specified by MAKE object! 
syntax, ever. And thus these objects will have an attribute that 
doesn't show up when you MOLD it (because MOLD generates MAKE object! 
syntax) that affects one of the core features of the BIND function. 
And that attribute wouldn't be serializable even if you added it 
to the MOLD/all syntax, because MOLD/all serialization of objects 
doesn't work: MOLD/all syntax for objects doesn't restore word bindings, 
only DO syntax does.
BrianH:
24-Mar-2010
I like the trick for conversion of records from fixed block spans 
to objects, both for Steeve's example and for passing along to functions 
that take object! records. However, as Andreas says we don't need 
the 'self binding trick to do it, we can use the bind? function.
Gregg:
24-Mar-2010
...I cannot predict the behaviour of Bind unless I know the originator 
of the context.

 This seems like a core question to me. And while Steeve's example 
 is really neat, I wouldn't say it is REBOLish per se. BIND? doesn't 
 say a whole lot more, so I don't think either example is something 
 to hold up as a best practice. :-)


Is it by design? If so, how is it intended to be used, and how should 
it *not* be used? If not, what warnings do we need to include in 
docs?
Ladislav:
25-Mar-2010
one more example in hope, that it will be understandable enough. 
First, the description in words: we define a function obtaining a 
block of code, which uses e.g. a Repeat loop. During the loop, the 
Block argument shall be executed too, but bound to the loop context, 
to be able to use the loop variable (s). The code looks as follows:

a-function: func [block [block!]] [
    repeat i 1 [do-in-context block 'i]
]

do-in-context: func [block [block!] context [word! object!]] [do 
bind block context]


I hope, that everyone understands, that this may well be a part of 
a real-world application, but my example is minimized to contain 
only the constructs that illustrate the problem. Now, in R2 the block 
will be executed "in the right context", being able to use the cycle 
variable 'i. In R3, the block is executed "in the wrong context", 
since the 'self variable will be bound, which was unsolicited.
BrianH:
25-Mar-2010
What we *can't* do is to make the hidden 'self field not there at 
all, since there's no syntax that would support that as an option.
BrianH:
25-Mar-2010
If you want the 'self trick to be an option, you must realize that 
almost all R3 code will be processed *with* that option. LOAD, DO, 
INTERN, MAKE-MODULE, DO-NEEDS and IMPORT will all need to use that 
option, so that means that most code will have 'self bound.
Ladislav:
25-Mar-2010
(Why "cripple" all these contexts so, that Bind has to do unsolicited 
work?)
BrianH:
25-Mar-2010
One thing you shouldn't do with a programming language is assume 
that the programmer doesn't know what they want to do, so you try 
to second-guess them. That is always the worst approach because the 
programmer will always end up having to work around your guesses 
so that they can do what they actually want to do, *which only they 
can know for sure*.


It's a bad sign when the language designer talks about guessing what 
the programmer wants to do. It is much better to make a consistent, 
sensible default, then provide alternate behavior as explicitly chosen 
options. It is incredibly presumptuous for you to say that the programmer 
"didn't really want to do that", and then do something else. It is 
much better to make the behavior consistent *and documented* then 
assume the programmer *knows* what they want to do and has told you 
so.


It is not the job of a programming language or library to do what 
the programmer "wants" to do. It is the job of the programmer to 
determine what they want to do, and the job of the tool to do what 
the programmer *says* to do. And if the programmer makes a mistake, 
the tool should be as helpful as it can by throwing errors where 
it is unequivocally wrong, giving enough information to the programmer 
so they can figure out whether where they went wrong, and to behave 
consistently and predictably. Because (short of bugs) the tool is 
never at fault if it does what it's told to do. It might not be the 
right tool for the job though, but that means another tool should 
be used.
BrianH:
25-Mar-2010
:Why 

cripple" all these contexts so, that Bind has to do unsolicited work?" 
- The behavior of BIND is documented, so it is presumptuous of you 
to say that its behavior is "unsolicited" when it is behaving as 
it is documented to behave. It is much better to use the word "unwanted" 
here. It is clear that *you* don't want BIND to do the 'self unhiding 
trick, and if there's no way to turn that off then it is a problem 
for you, as a user of the programming language. So there should be 
an option, and maybe your preferred behavior should be the default.


However, you as a language designer (this is a different you, btw) 
has to consider what other users want to do, and that won't necessarily 
be consistent with what you (as a user) would want to do. So you 
(the designer) make tradeoffs, balance concerns, look for the most 
common behavior, make sensible choices, and try not to mess up. And 
then finalize the behavior in a tool that only does what it's told 
to do, and document that tool's behavior (at least on the surface). 
Then you (as a user) can know that the tool is going to respond the 
way it is documented to do when you tell it to do something - for 
a tool, this is what it means to do what it is supposed to do :)
Steeve:
25-Mar-2010
Perhaps more logical to do so. But as I said, I can deal with this 
problem with no overhead.

When time will come  to polish Rebol we will manage it, but now there 
are still important missing features or bugs.
Just a matter of priorities.
BrianH:
25-Mar-2010
For instance, if BIND/self (#1544) is implemented, then I will have 
to add the /self option to every usage of BIND in DO, LOAD, IMPORT, 
DO-NEEDS, INTERN and MAKE-MODULE, and perhaps some other places in 
the mezzanine code as well. This is not a problem (really, it isn't) 
but it is better to do this now while the scope of the effects is 
still calculable.
Ladislav:
25-Mar-2010
People who need the 'self binding sometimes with a context, and don't 
need it other times with *the same context*.

 - this is the issue in a crystal clear form. As far as I am concerned, 
 I need to bind every block supplied to the Bind function to be bound 
 the same way, when the same context is given, because I need the 
 code to behave consistently. Therefore, I dislike the state, when 
 I do not know, what "the same way" is. As opposed to that, you seem 
 to prefer to bind blocks differently, even when they are bound to 
 the same context, which seems to be necessary only in case, when 
 the usual contexts have to contain, as I call it "unsolicited" 'self.
BrianH:
25-Mar-2010
I only need to bind blocks differently to the same context *when 
I tell it to do so* (aka, when solicited). This is so I can write 
code that expects 'self to be bound without having to check whether 
the object I am binding to has the hidden 'self field. If I had to 
check for that, I would have to do that check with every usage of 
BIND where I had a 'self reference and use different code blocks 
depending on the results of that check. It is much better for BIND 
to just do what I tell it to do.
Ladislav:
25-Mar-2010
Regarding the Steeve's point: as far as I am concerned, your suggestion 
*is* consistent. (I see it as more consistent, than the current state) 
The only problem with it is, that some users may find it uncomfortable, 
since they do not need to have 'self related to e.g. Repeat, or other 
cycle functions...
Ladislav:
25-Mar-2010
And the programmer that matters when it comes to BIND is the one 
that is calling BIND, and providing the code block. Not the one that 
made the context.

 - this is interesting, again. My note is, that if the context was 
 created to support e.g. the functionality of For, then any subsequent 
 binding is meaningful for me, only if the functionality remains supported. 
 I think this way, even when I am the one calling Bind and providing 
 the block, unfortunately, I may not know, which alternative mentioned 
 by you to use, not knowing the type of the context I obtained.


As opposed to that, when I see a context without 'self, I know, that 
the context was created so, that it is not meant to support 'self 
binding, and that is all I need to know. How would you do it obtaining 
a context of unknown origin, that would contain '"unsolicited" self? 
(of course, not knowing that information, since there is no way how 
you can find that out)
Ladislav:
25-Mar-2010
...to *break* all other code that expects objects to behave like 
objects...

 - this has been demonstrated by Andreas to be false - I do not want 
 to break any behaviour of objects, I do want to not break behaviour 
 of other contexts than objects
BrianH:
25-Mar-2010
Sorry, i meant "go left only in a 20ft radius circle", I didn't mean 
something most people would want to do when they aren't showing off.
BrianH:
25-Mar-2010
Imagine that your DO-IN-CONTEXT function was written by someone else, 
to take any object, and depended on the 'self override. That is the 
most common case for functions that operate on objects they did not 
create and use 'self. Those would be broken if there is no 'self 
.
BrianH:
25-Mar-2010
Andreas, agreed, the problem could be solved by having two types. 
But that's unnecessary, since we have a solution already that doesn't 
require another type. And the two-type solution wouldn't help with 
loops and closures unless BIND? returned an object type from words 
bound to the non-object type, because to do otherwise would break 
BIND.
BrianH:
25-Mar-2010
Because even if we made BIND not do the 'self trick by default, we 
would still *need* to add the /self option, and that option would 
*need* to have a 'self field to do the trick with, *every time*.
BrianH:
25-Mar-2010
You have to assume that the 'self trick needs to be able to work 
with every "context" that you pass to BIND, even if BIND doesn't 
do the trick by default. Because the trick is necessary for a lot 
of code. And leaked 'self references can be a security hole, allowing 
access to otherwise encapsulated code.
BrianH:
25-Mar-2010
It's all well and good to say that the current BIND does the 'self 
trick and you don't like that. But there is a lot of code that depends 
on that trick, so if you don't want to do it for your code, you better 
make that an option (perhaps the default one).
BrianH:
25-Mar-2010
There is no problem with not doing the 'self trick if you don't want 
to. The problem would be if you *can't* do the 'self trick with any 
indefinite-extent context that exists, and you would run into that 
problem if it was possible to make an indefinite-extent context without 
the special 'self field.
Ladislav:
25-Mar-2010
so what Steeve, do you want to prove, that I did not use a real code 
and shorten it so, that the problem is still visible?
Andreas:
25-Mar-2010
And if that all matters is a question about how you assume typical 
BIND code to look like. Ladislav's point (at least as far as I understand 
it, Ladislav please correct me if I'm mistaken) is that there are 
situation in which I as BIND user don't know whether I want to do 
BIND/self or BIND/no-self on the context.
Gabriele:
26-Mar-2010
Do I need to say "KISS" here?
BrianH:
27-Mar-2010
Finally, the only reason we still need 'self is because you can't 
use path notation with the results of a function (BIND? in this case). 
So you have to have the result assigned to a word to be easily able 
to do the tricks one can do with path notation. Thus the only reason 
we need 'self is for convenience, so that the end developer doesn't 
have to constantly reinvent their own 'self references, badly.
BrianH:
27-Mar-2010
When I say "badly", we come to the only thing you can't do with a 
roll-your-own 'self: The UNPROTECT exception. UNPROTECT won't unprotect 
'self: it refuses to. And it will unprotect any other protected word 
(future security restrictions allowing). So the one thing you can't 
fake is a persistent word reference to the object that you can't 
modify (the way you can in R2). At least not without writing your 
own UNPROTECT.
BrianH:
27-Mar-2010
Admittedly, you can't do the BIND unhiding trick either, but if you 
roll your own (let's call it 'this), the 'this reference can go in 
another context and you will get the same advantages. Or you can 
bind all the code that needs to refer to 'this before you hide 'this, 
so you won't need to unhide 'this later (normally impossible).
BrianH:
29-Mar-2010
irreparable bugs

 isn't descriptive enough. Please add a comment explaining what the 
 bugs in question are, and why you think they are "irreparable", when 
 you link tickets that have known methods that can be used to solve 
 them, including one that is already fixed. And why DO-IN, a function 
 that only exists in the example code of the ticket, not in R3, matters. 
 If you don't do this *in the ticket or its comments* then the ticket 
 will need to be dismissed.
BrianH:
18-Apr-2010
TO and MAKE are considered different in R3, but for some types they 
do the same thing; not string though.
BrianH:
19-Apr-2010
There's no reason that the operation *would* be reversible. The TO-INTEGER 
was correcting for an incomplete binary in a DWIM way. If you had 
provided the whole binary it wouldn't have had to do that. And the 
TO-BINARY had a whole integer, so it didn't have to correct.
BrianH:
19-Apr-2010
It is not that Python was doing it "safely", it was that Python was 
doing it differently when there is no standard for what to do here.
Maxim:
19-Apr-2010
pekr... here I must say, you really do not know what you are talking 
about.


all the binary changes brought to R3 are due to user responses about 
how fucked up it really was to use binary stuff in R2.   really. 
 I had to build binary data-driven TCP servers in R2, for example, 
and I had to use so many shitty work-arounds and fix up numbers .. 
it was an ordeal.


R3 makes binaries, clean, no hassle and simple.  they are a simple 
series of bytes, nothing more.


they are manipulated from the start to the end in that order.  that's 
all there is to it.
Pekr:
19-Apr-2010
and 0x8000 will be a different value based on what variable type 
it is assigned to.
 ... do you REALLY mean it? 0x8000 is just one value, period ...
Pekr:
19-Apr-2010
OK, so in my above case, I am supposed to pad #{8000} to #{00008000} 
... what the hell do I do, if I am on 32 bit R3 version, not having 
64 bit integer? How do I know?
BrianH:
19-Apr-2010
0x8000 will be a different value based on what variable type it is 
assigned to.

Maxim, you're wrong on this one. 0x8000 is always an integer. It 
has nothing to do with #{8000}.
BrianH:
19-Apr-2010
Pekr, you do realize that TO-INTEGER #{8000} is a conversion of an 
incomplete binary, an operation, right? And that 0x8000 is syntax 
for an integer value? REBOL doesn't have hex syntax for integers, 
or any default interpretation of binary values as being of a different 
datatype. Just like Python doesn't have syntax for binary values 
(unless I'm mistaken about that last bit).
Anton:
19-Apr-2010
Pekr, I agree with BrianH (as I almost always do).

It seems the confusion is that C or Python's integer representation 
syntax and Rebol's binary datatype look similar, because they both 
use hexadecimal. But 0x8000 in C or Python is really an integer and 
has to fit inside an integer type with some specific size. Rebol's 
binary type is a series type and can be as long or short as you want 
(well, measured in 8-bit chunks, octets), and it doesn't make any 
assumptions as to what the meaning of those octets is.

In Rebol I miss being able to represent integers the way C does, 
it makes translation a bit more difficult.
Ladislav:
20-Apr-2010
Pekr, you are right when saying, that binary OR uses different padding 
(right) than conversion to integer (left).

As far as I am concerned, the left padding for conversion to integer 
looks more convenient than right padding, "producing" a useful result 
more often.

Regarding the OR operation: I guess, that it *could* use left padding 
too, but, in that case, I am not sure, whether left padding would 
produce a more useful result more often, than right padding. (although 
you provided one case, where left-padding *would* be more useful) 
Nevertheless, I do not think, that padding of these two operations 
has to be the same
Pekr:
20-Apr-2010
Anton - insane is just that ... insane :-) It is just word. I did 
not say Carl, BrianH or anyone else is insane, having some arguments. 
REBOL is not religion, as Brian says ... it is a tool. And I want 
the tool to work correct way, if possible. So - stop being stressed 
about someone claiming something is insane :-) 


The question to all above is - what is the correct behaviour. The 
qeustion even is - what is correct about correctness? I know from 
the past, that Carl really cares about simple things being simple. 
I can't remember the case, but I do remember I pointed out something 
will confuse ppl, and I was right - we could see the same kind of 
questions by novice again, and again, and again.


I think that if you claim, that to-integer #{8000} allow many interpretations, 
how is that we have choosen the concrete one? (32768) Because it 
is what we would expect. You might think that I don't understand 
what BrianH or Max or You talk about. Whereas only Ladislav got the 
correct answer for me - if it would hurt to have reverse padded OR 
operation.
Pekr:
20-Apr-2010
BrianH: I know :-) It is just that for the simple purpose of OR, 
you have to do all those conversions and tests for the integer size. 
Then original "shortcut" format of #{8000} be better avoided in the 
code.
BrianH:
20-Apr-2010
We made a MOVE function to resolve such discussions, we can do the 
same with PAD.
Pekr:
20-Apr-2010
Hmm, because I can't do shift on binary, enbase/base is giving me 
following result (understandable, as to-binary creates 64 bit binary)

>> enbase/base to-binary shift to-integer (copy l) -8 2

== {0000000000000000000000000000000000000000000000000000000010000011}

whereas:
>> enbase/base 2#{11110000} and 2#{10110000} 2
== "10110000"


Correct too? So when using shift, I need to use different scenarios, 
if I want bits represenation (copy/part)?
Pekr:
21-Apr-2010
one more line? Do you mean port/awake: :my-awake? But I first have 
to define 'my-awake, no? Just trying to understand the situation 
...
Ladislav:
21-Apr-2010
the only thing you can do is to convert "last 32 bits of 64-bit binary"
Steeve:
21-Apr-2010
what do you mean by no fast way to pad binaries ?
BrianH:
21-Apr-2010
Sounds good. But it is still better to do the conversions to the 
most efficient method ahead of time if you can. REBOL is hand-optimized.
BrianH:
21-Apr-2010
I have been giving the subject some thought, and even more so since 
Silverlight came out. It would be the best way to get REBOL into 
Windows Phone 7, for instance. I don't see how the tail-call thing 
would affect REBOL on Java though: REBOL doesn't do tail-call optimization 
anyways. But we might want to wait for Java 7 and its dynamic types 
(Java's cheap knock-off of the DLR).
Steeve:
21-Apr-2010
trying to do scheme above tcp to aid with async protos
Pekr:
21-Apr-2010
In such case, maybe it was better to still have read-io, write-io, 
and make read and write more higher level. What is the reason to 
first "prune down" function, and later on give-up, and add other 
refinements, because the practical merits push us to do so?
Pekr:
21-Apr-2010
so you talk x hours to me, trying to explain, that R3 broke with 
R2 almost-everything-is-string attitude, to later on admit, that 
we gave up on strictly deviding, what 'read/write are supposed to 
do
Steeve:
21-Apr-2010
probably we need a new FSM dialect, parse is not suited to do that 
job. We have to do too much hack to simulate a fast and clean state 
machine.
Maxim:
21-Apr-2010
sometimes you have to do stuff to think about even better stuff  
;-)
BrianH:
28-Apr-2010
This is why arguments like "We never needed to do that before!" break 
down. The reality is that we *didn't* do these things before because 
we couldn't, or because it wasn't safe, not because we didn't need 
to.
BrianH:
28-Apr-2010
(From chat #7216) Some tests pass, others fail. It's a good start.

- The tests in the example code of bug#1549 pass (Ladislav's philosophicals)

- The practical tests don't. In particular, bug#447, bug#1528 (for 
closures), bug#1529 and bug#1552 are still problematic.

- We need a SELFLESS? function (or whatever it should be called) 
to resolve the main downside of the #1549 approach, and we need it 
for the a98 release.

Here are the practical tests that need to pass:

; Objects
ob: object []
print same? ob do bind [self] ob
print same? ob do in ob [self]

; Functions
ob: object [f: func [/x] [do bind/copy [self] 'x]]
print same? ob ob/f
; Can't use the context after the function returns.
; This is not a side effect of Ladislav's proposal.

; Functions with a 'self parameter (#1528)
ob: object [f: func [/self] [do bind/copy [self] 'self]]
print not same? ob ob/f

; Closures (#447)
ob: do closure [x] [bind? 'x] 1
print 1 = ob/x
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Closures with a 'self parameter (#1528)
ob: do attempt [closure [self] [bind? 'self]] 1
print 1 = attempt [ob/self]
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Closures shouldn't bind 'self unless it is a parameter (#447)
print same? self do closure [x] [self] 1
print not same? self do attempt [closure [self] [self]] 1

; Loops (#1529)
ob: repeat x 1 [bind? 'x]
print 1 = ob/x
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Loops with a 'self variable (#1529)
ob: repeat self 1 [bind? 'self]
print 1 = attempt [ob/self]
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Loops shouldn't bind 'self unless it's a variable (#1529)
print same? self repeat x 1 [self]
print not same? self repeat self 1 [self]


See also #1552: There needs to be a way to distinguish selfless contexts 
from selfish contexts at runtime (a SELFLESS? function), and selfless 
contexts need to MOLD into DOable syntax (perhaps a different datatype, 
or a flag).
BrianH:
29-Apr-2010
Strangely enough, the code injection risk doesn't come from the DO 
vs. FIRST, it comes from the self vs. 'self. We can't use :self with 
=? in R3 because self is a frame! that evaluates to an object!, not 
an object! itself.
BrianH:
29-Apr-2010
Another way to resolve the risk would be to change the line to this:
    :self =? do bind/copy [:self] context
Pekr:
2-May-2010
BrianH/Ladislav - what do you think of Carl's opinion to add (back) 
to R3 struct like dtype, or function, to allow better binary to integer 
conversion? ( http://www.rebol.net/cgi-bin/r3blog.r?view=0314#comments
)
Steeve:
2-May-2010
About remove-each in R3, I dislike the new given output (numbers 
of values removed).
What the point to discard the most powerful feature of Rebol ? 
- Chaining operations on series.

Besides, To count how much values have been removed is trivial to 
do and a very rare use case.
Graham:
2-May-2010
Yeah ,... much to do about nothing
BrianH:
2-May-2010
Carl just posted this code, to be the new definition of EMPTY?:
empty?: make :tail? [
    [

        {Returns TRUE if empty or NONE, or for series if index is at or beyond 
        its tail.}
        series [series! gob! port! bitset! map! none!]
    ]
]

This means two things, one minor, one major:

- Minor: TAIL? won't take none, so we have an option of triggering 
the error if need be.

- Major: *You can do that kind of thing at all*. This opens a *lot* 
of possibilities :)
BrianH:
2-May-2010
I wonder what the effect will be on function! and closure! functions, 
whether there is body copying. It seems like a really interesting 
way to do optional arguments to commands though.
BrianH:
2-May-2010
If might help the insanity to know that you can't do this yet. After 
copying the above message to the clipboard:
>> do clipboard://
Script: "Untitled" Version: none Date: none
** Script error: invalid argument: [[
        "Constructs a specified datatype."

        type [datatype! any-object!] "The datatype or example value"
        spec [any-type!] "The attributes of the new value"
    ]]
** Where: make catch either either applier do
** Near: make :make [[
        "Constructs a specified datatype."
   ...
GiuseppeC:
4-May-2010
Ladislav,  we see Carl focusing on some or some other part of REBOL. 
This time he is working on the object part of the language. It would 
be good to have your (and the other) respected opinion about this 
topic now. Maybe we will be able to close this topic which has been 
opened in the blog in the distant year of 2006.
However, no one is forcing anyone to do anything...
Ladislav:
4-May-2010
And, maybe surprisingly, I really do not feel an urgent need to solve 
this, being pretty content with the current state of affairs
Maxim:
4-May-2010
init and destructor accessors too.

might be nice to support print accessors... what do you think?
BrianH:
4-May-2010
Which we can do already, but syntax support allows us to hide the 
overhead.
Maxim:
4-May-2010
sure, but then you have two references to the same attribute and 
setting the field doesn't use the rebol syntax for setting the field.


I do agree that in R3, since we can protect fields, at least we can 
now enforce the use of set-a and be sure its not replaced as-well.
BrianH:
4-May-2010
As do the objects returned by SELF or BIND? applied to module contexts, 
strangely enough.
GiuseppeC:
4-May-2010
Nothing to do with REBOL3 but I told you GoodNight and I want to 
inform the community it is not a good night !
PeterWood:
5-May-2010
How do you use reflection to ascertain the contents of a gob? I tried 
values-of, words-of, foreach forall - all give errors:

>> a: make gob! [text: "gob a"]       

  == make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob a"]

>> b: make gob! [text: "gob b"]        

  == make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob b"]

>> c: make gob! [text: "gob c"]         

== make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob c"]

>> d: make gob! [text: "gob container"] 

 == make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob container"]

>> append d [a b c]                   

   == make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob container"]

>> first d

== make gob! [offset: 0x0 size: 100x100 alpha: 0 text: "gob a"]

>> foreach gob d [print gob]

** Script error: foreach does not allow gob! for its data argument

>> forall d [probe first d

]
** Script error: invalid argument: make gob! [offset: 0x0 size: 
100x100 alpha: 0 text: "gob container"]

** Where: forall

** Near: forall d [probe first d]

>> values-of d

** Script error: cannot use reflect on gob! value

** Where: reflect values-of

** Near: reflect :value 'values

>> words-of d

** Script error: cannot use reflect on gob! value

** Where: reflect words-of

** Near: reflect :value 'words
Maxim:
5-May-2010
did you try  'SPEC-OF  ?


I am currently clueless as to R3 gobs, but its another test you might 
do while you're at it.
PeterWood:
5-May-2010
Thanks again Rebolek - I hadn't worked that out as the probe results 
led me to believe that the append had an implicit copy as it seems 
to do for blocks:

>> a: []      

== []


>> b: [1 2 3] 

== [1 2 3]


>> append a b 

== [1 2 3]


>> a

== [1 2 3]


>> b/1: 4

== 4


>> a

== [1 2 3]
Ladislav:
5-May-2010
Actual storage

 versus "network order" - do you like the current conversion from 
 integer to binary (network order), or would you like the conversion 
 as in R2 structs, where the endianness was not suppressed?
BrianH:
5-May-2010
The advantage to having a spec block is that you can return it from 
a function; you can't do that with refinements.
PeterWood:
5-May-2010
There doesn't seem much to chose between foreach and forall in terms 
of speed:

>> dt [loop 100000 [foreach gob d/pane [x: gob]]] 

== 0:00:00.125035

>> dt [loop 100000 [gobs: d/pane forall gobs [x: first gobs]]] 

== 0:00:00.133837


Using a do-it-yourself repeat loop courtesy of Rebolek  seems a little, 
but not much faster :

>> dt [loop 100000 [repeat i length? d[x: d/:i]]] 
== 0:00:00.115478
BrianH:
5-May-2010
REPEAT has the same BIND/copy overhead, but REPEAT w number! has 
less work to do, so it's faster. I wouldn't be surprised if REPEAT 
w series! is comparable to FORALL.
Graham:
6-May-2010
We should do a poll of what OS everyone is using.  Seems to me odd 
to release two OSX builds and no Linux
Graham:
6-May-2010
Has anyone done this?


If your embedded module consists entirely of REBOL code (no native 
commands), it's not required that you embed it in the way described 
here. Instead, you can add it to the host bundled source code which 
initialized in the host in the line:

Reb_Do_Binary(Reb_Init_Code, REB_INIT_SIZE, 0, 0);

More on this is described in the host-kit documentation.
BrianH:
7-May-2010
The baseline:
>> dp []
== make object! [
    timer: 0:00:00.000011
    evals: 8
    eval-natives: 3
    eval-functions: 1
    series-made: 1
    series-freed: 0
    series-expanded: 0
    series-bytes: 432
    series-recycled: 0
    made-blocks: 1
    made-objects: 0
    recycles: 0
]

Example code:
>> dp [change #{00} #{02}]
== make object! [
    timer: 0:00:00.00001
    evals: 11
    eval-natives: 4
    eval-functions: 1
    series-made: 1
    series-freed: 0
    series-expanded: 0
    series-bytes: 432
    series-recycled: 0
    made-blocks: 1
    made-objects: 0
    recycles: 0
]
>> dp [change #{00} 2]
== make object! [
    timer: 0:00:00.00001
    evals: 11
    eval-natives: 4
    eval-functions: 1
    series-made: 2
    series-freed: 0
    series-expanded: 0
    series-bytes: 436
    series-recycled: 0
    made-blocks: 1
    made-objects: 0
    recycles: 0
]
>> dp [change #{00} [2]]
== make object! [
    timer: 0:00:00.000009
    evals: 11
    eval-natives: 4
    eval-functions: 1
    series-made: 1
    series-freed: 0
    series-expanded: 0
    series-bytes: 432
    series-recycled: 0
    made-blocks: 1
    made-objects: 0
    recycles: 0
]


Clearly APPEND, INSERT and CHANGE convert regular values to binary! 
first now (creating a series), then do their inserts. And they don't 
convert first if you use the new block mode. Good to know :)
Steeve:
7-May-2010
what are you saying BrianH ? we don't need to do a conversion to 
add a 8-bit integer at first.

>> x: #{00}
== #{00}

>> x/1: 2 x
== #{02}

or 
pick x 1 2

I just think that 'change block uses that neater way in a loop
BrianH:
7-May-2010
Steeve, for a native operation the only way that the stats can be 
recorded is if the native reports them; it's not like with REBOL 
code. So if DP doesn't report something, it's either because it didn't 
happen or because the code didn't say it happened. I wouldn't be 
surprised if the allocator has stats collection hooks, but who knows 
how CHANGE binary! block! is allocating its stuff. But it would *have* 
to do a binary conversion in order to insert a non-binary value, 
so there is no question that there is some kind of binary conversion 
going on.
Steeve:
7-May-2010
I just proved that you can do it whithout the need to create an intermediate 
binary serie, are you tired ?
BrianH:
7-May-2010
PICK and POKE may also do their own conversions using their own buffer 
(it's just a byte). Apparently since CHANGE binary! value has to 
support full TO binary! support, the easiest way would be to actually 
call TO binary!, which would allocate something. Since CHANGE binary! 
block! doesn't need to support full TO binary! support, maybe it 
has its own internal conversion routines that don't call TO binary!, 
and thus don't *report* any temporary series it creates.
Steeve:
7-May-2010
maybe for string to binary conversion a buffer is requested but i 
can bet that it's not neccessary for integers. It can be poked in 
place.

It's like I would do in asm or in C. casting of the 64 bits integer 
into a char (take the low byte) and poke it inside the binary serie, 
that's all I have to do.
9401 / 1157812345...9394[95] 9697...112113114115116