• 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
r4wp4382
r3wp44224
total:48606

results window for this page: [start: 42401 end: 42500]

world-name: r3wp

Group: !REBOL3 GUI ... [web-public]
Pekr:
5-Jan-2010
BrianH: there are more changes planned, no? Like adding layers, etc. 
Henrik summed it up somewhere, maybe he can repost. And as far as 
I remember - the changes might influence your code, so I am not sure 
if it is good to do any GUI related work in recent VID state ...
Henrik:
5-Jan-2010
Something will happen here possibly in February to April, but I need 
to finish another project first. Things will be slightly different 
than originally, because I want to take advantage of some techniques 
used in the VID Extension Kit for face navigation, keyboard navigation, 
etc. Not doing work on the GUI has largely been because of announced 
changes not yet implemented, and also having lots of work elsewhere, 
fortunately almost all REBOL related.
Pekr:
6-Jan-2010
I just found Henrik's summary. I think it is the post I had in mind:
---------------------------------------------

Indeed VID3.4 is far from done. You can probably use it for a few 
things, like getting a name from a user in a text field or submit 
a very simple form, but not much more than that. To reiterate the 
state of the UI:

- No unicode yet in graphics (when Cyphre gets around to it).
- Resizing acts like a drunken sailor. (Carl)
- Skin is not published. (Me)
- Style tagging is not implemented. (Carl)
- Reasonable requesters are not yet implemented. (Carl or me)
- Layers are not yet implemented. (Carl)
- Guides are not yet implemented. (Carl)

- Better font rendering. We are not taking advantage of what AGG 
can do. (Cyphre again)
- Event system is from Gabriele's VID3. (Carl)
- Many features are untested, like drag&drop. (Me, I guess)
- Proper material management for skin. (Me).
- Many styles are not implemented, especially lists (Me).
- More elaborate animation engine (Carl or Me).
- Form dialect (Carl talked about this).
- More/better icon artwork (Me).


Plus, Maxim has some ideas for DRAW, to greatly speed up rendering, 
but I don't know if they can be implemented.


The overall design of the GUI engine is very good. Whenever a change 
or addition is made, you alter 3-5 lines of code in one place, and 
it works. I doubt the entire engine will be rewritten.


You won't see GUI bug reports in Curecode for a while. There could 
easily be 2-300 reports, once we get to that point.


My work regarding skins is rather big: I need to work out the basic 
styles first, so we have a reasonable way to build compound styles. 
These are being done using a very simple, but pixel accurate GUI 
using plain colored surfaces. This is easier for testing out, as 
draw blocks are small, but as Pekr likes to complain: They are not 
pretty to look at. Once the real skin goes into place, the draw blocks 
will grow a lot.


I would love to see a low-level GOB management dialect, like Gabriele's 
MakeGOB.
Pekr:
6-Jan-2010
Henrik and BrianH should agree upon what do we mean by "layers", 
as Henrik claims they need to be done, whereas BrianH claims we have 
them already :-)
Henrik:
6-Jan-2010
And they describe layers in a different way. The layer system may 
already be implemented, but unused.
Pekr:
6-Jan-2010
Can't wait for when we get back to GUI :-) Hopefully Carl is back 
to Host Kit soon, so that View will be adapted to command! interface, 
and its source released, in order for Cyphre to proceed ...
Pekr:
6-Jan-2010
yes, frames :-) Btw - how do frames and layers differ? Isn't it identical 
concept, after all?
GiuseppeC:
7-Jan-2010
Pekr, you forgot animated effects on every place of the GUI and 3D 
GUI ;-)
Pekr:
8-Jan-2010
Ah, Ashley and RebGUI 3.0 :-)
Pekr:
8-Jan-2010
I can post what Max said about his problem with gobs and draw in 
the past ...
Group: !REBOL3 Proposals ... For discussion of feature proposals [web-public]
BrianH:
9-Nov-2010
There, 3 and 4 have been tweaked to be a little better. 3 (and 4 
transitively) could use another couple disadvantages listed, but 
the ones there may be sufficient.
BrianH:
9-Nov-2010
Swapped 5 and 6 in the page, and reworded them accordingly. Now the 
differences between them are more clear. Swap "5" and "6" when reading 
back to the conversation above between Andreas and me. I now prefer 
5, though would accept 6.
Maxim:
10-Nov-2010
ok, I've read the whole exceptions document and a few (very old!) 
tickets at least 3 times now.


I'll start by being honest and saying that some of this is going 
a bit deep into some details and I'm pretty sure that I'm not graping 
all implications.  The background for all the discussion hasn't "sinked 
in" yet, so its a bit hard to be totally conclusive about my evaluation 
thus far.


this being said... when I arrived at 5, i.e. "Definitional return 
only, with an option to not redefine RETURN and EXIT", it suddently 
starts making sense overall.  6. seems to be redundant and maybe 
even harmfull if we keep THROW dynamic.  This is scaled with CC#1744 
"fixed" and a wider use of THROW, encouraged, since it now allows 
custom escape/exception modeling by non guru-level Rebolers (and 
by guru I mean one of 3-4 rebolers on the earth... maybe not even 
including Carl ;-).


this means, that return does one thing, throw does another.  they 
become two completely different things, clear and conscice in all 
code.


the only real issue I have is that we seem to loose return in parse, 
 but if we keep throw dynamic, then that is moot, and we can just 
use THROW instead.  In fact, woudn't that be preferable, since its 
more accurate?  we are pre-empting the parse return and providing 
our own... which is what throw should be doing ... its more consistent 
overall.


so go ahead rip my arguments appart... it will only help me understand 
this completely.  :-)
BrianH:
10-Nov-2010
You missed one thing: To make PARSE rules task-safe, we should be 
moving them into function blocks anyways. And recursion-safe, for 
some really obscure tricks that the new PARSE IF operation lets us 
do, but the task-safe thing will come up more often.
BrianH:
10-Nov-2010
Oh, and BREAK/return works in the parens in PARSE rules in R3 - it's 
a drop-in replacement for most uses of RETURN in those same parens.
Gregg:
11-Nov-2010
I made some notes here and there, but can't seem to make time to 
really think deeply about all this. Consider these thoughts lightly 
---


The FOREACH trick is clever, but it makes me wonder if things are 
a bit inverted. Should there be a core binding func that does that 
service *for* FOREACH and other funcs that need that behavior.

Even though it's temporary, should this:
    if set-word? first words
be this:
    if find words set-word!

(behavior alterations and 'values being modified ignored due to temp 
status of func)


TRY/EXCEPT doesn't read particularly well to me, because 'except 
sounds like you're leaving something out, rather than catching the 
error.
Maxim:
11-Nov-2010
I also think that Carl hesitates to give us lower-level constructs. 
 This has been the historic case, BUT, now that a lot of people are 
actively contributing and actually producing working concepts, ports, 
prototypes and stuff, Carl is slowly realizing how usefull it is 
for *him* to open up on the lower levels of REBOL.


the exception/return/throw discusission going on is a good example 
of this active participation of the community.  Obviously, not everyone 
is willing or able to participate, but in such deep discussions, 
there is rarelly a huge mass of people anyways.
Maxim:
11-Nov-2010
I really hope that brian, Ladislav and Carl will get together in 
a possibly heated discussion about all of this.  the difference in 
mindsets is a perfect setup to get the best overall solution.
Maxim:
11-Nov-2010
my only desire in all of this discussion is that trhow/catch is kept 
dynamic and that /name be implemented with context matching and that 
catch doesn't handle throw/name.
Ladislav:
11-Nov-2010
catch doesn't handle throw/name

 - you could always use catch/name [...] 'none versus throw/name 'none, 
 if you did not want to catch other throw/name calls, so this is still 
 just "cosmetic", and surely not serious in any sense I can imagine.
Maxim:
11-Nov-2010
yes that is interesting, but /name is usefull for some code patterns 
like named exceptions.


thing is that currently, catch  withouth /name does make that impossible 
afaik.  if we built a mezz which re-threw them, afaik, that would 
change the context and thus make context sensing impossible... though 
your skill in this type of low-level manipulations might (will? ;) 
prove me wrong.
Maxim:
11-Nov-2010
its just my bumbling appraisal so far, because it seems to me that 
you don't need to redefine and contextualize everything within your 
mezz code... but I do say I'm novice at this subject.  (I'm trying 
hard to completely "get" it/
Ladislav:
11-Nov-2010
Nevertheless, you can insert something like


if i = 0 [print mold block] to see the result, and compare that to 
the result in R2
Maxim:
11-Nov-2010
wow, I think you've just illustrated a big part of the issue and 
you should add the above to your exceptions page.
Maxim:
11-Nov-2010
yes, but the error document tries to illustrate it too, and I didn''t 
see it as plainly as I do now.
BrianH:
11-Nov-2010
I really need to fill in the Exceptions page with the real differences 
and advantages of dynamic and definitional scoping. There are advantages 
that either has that the other does not. It would be a real loss 
to not have both in different circumstances. The different circumstances 
being definitional for returns and dynamic for breaks and throws.
BrianH:
11-Nov-2010
And anyone who thinks definitional is always better needs to look 
at #1521.
Maxim:
11-Nov-2010
with the above example, I'm thinking about the past discussions and 
they are starting to make sense in a new light  :-)
Ladislav:
11-Nov-2010
Max, the errors page you mentioned tried to illustrate the difference 
between dynamic and definitional return, which looks more subtle, 
than the difference between dynamic and definitional variables...
Ladislav:
11-Nov-2010
A description of the difference between the definitional and dynamic 
return:


*the dynamic return returns to the dynamically closest function (i.e. 
to the function that was called as the last one)

*the definitional return returns to the definitionally closest function 
(i.e. to the function that was defined as the last one and contained 
the return in question)
BrianH:
11-Nov-2010
That's not all. Definitional also requires the affected functions 
to have (and in some cases fake) lexical scope. For R3 this means 
nested blocks.
BrianH:
11-Nov-2010
Fortunately, functions are built with nested blocks, though that 
is partly enhanced in R3 by tasking issues. And while loops are also 
build with nested blocks, BREAK also applies to PARSE, which relies 
on dynamic scope (and yes, I can point you to mathematical proofs 
of this, though there's no point), so we still need dynamic BREAK. 
Dynamic THROW is just a good idea because of all the capabilities 
that would give us.
BrianH:
11-Nov-2010
Definitional returns or escapes rely on lexical scope. If you don't 
have lexical scope, you don't have the ability to do definitional. 
So what PARSE needs is for the top-level BREAK to be dynamic. And 
if one level is dynamic, we are better off with all levels being 
dynamic, at least for the same escape function. Same goes for definitional.
BrianH:
11-Nov-2010
Yes there is: Definitional breaks redefine BREAK to a definitional 
function, and PARSE relies on BREAK being dynamic because PARSE is 
inherently and necessarily dynamic and doesn't rebind anything in 
the parens, nor should it. For that matter, PARSE rules can be reassigned 
in their productions, so PARSE can't even rely on the rules being 
the same thing the next time round.
BrianH:
11-Nov-2010
Which is not the same as PARSE [(return)], but PARSE doesn't pay 
attention to the bindings of the keywords in its rules, just those 
of the rule names. And in the productions (parens) PARSE can't do 
any rebinding at all because it can't assume that BREAK is referring 
to the same function.
BrianH:
11-Nov-2010
It is becoming abundantly clear that there is more and more need 
for a comparison section that shows the strengths of dynamic vs. 
definitional, because people seem to not understand that there are 
ceratin classes of code and algorithms (parsing, for instance) that 
can't be expressed with strict lexical scoping. You are giving up 
a lot when you go definitional, so that better stuff not be as important 
in the context where you do it.
BrianH:
11-Nov-2010
Yes, based on varying levels of information. My statement is objective. 
It is all a tradeoff, and I have not at any point tried to hide the 
upsides and downsides of both approaches.
BrianH:
11-Nov-2010
And I can use those same proofs to apply to other algorithms with 
similar characteristics, and *know* that you gain some abilities 
with definitional scope, and lose others. This is why I know that 
Ladislav's DO-ALL is a loop, and so not wanting BREAK to apply to 
it is more of an opinion than something inherent in its nature. But 
that doesn't mean that the need for that is less.
BrianH:
11-Nov-2010
And yes, I would be satisfied with THROW being dynamic and the rest 
not. But my *bare minimum* requirement for accepting that is to fix 
THROW so it actually works properly, and in many ways it doesn't 
at the moment (all with tickets), and in one way it could work better 
(also with a ticket).
Maxim:
11-Nov-2010
I've just reread a few things and I now truely understand the deeper 
intricasies of this whole discussion... (finally ;-)
Maxim:
11-Nov-2010
I think that the terms dynamic and definitional aren't making comprehension 
easy, especially dynamic.
BrianH:
11-Nov-2010
Please don't take my mentioning of downsides as being a statement 
of opinion or some kind of taking sides. I only mention them because 
they are real, and must be considered when picking a certain strategy. 
Both approaches have plusses and minuses. If you want to make a rational 
choice then you need to know the issues - otherwise you are just 
being a fanboy.


For instance, I picked the definitional side for returns, without 
the need for a fallback to dynamic, because of a rational evaluation 
of the algorithmic style of R3's functions. And it wasn't until I 
remembered that the tasking issues had already removed the advantages 
that dynamic scoping has over lexical scoping - we just can't do 
that stuff as much anymore, so it doesn't matter if we don't try. 
The same goes for loops, but to a lesser extent - loops aren't affected 
as much by tasking issues so we can still do code that would benefit 
from dynamic breaks, but it still might be a worthy tradeoff to avoid 
needing an option (since we have no such option). But for THROW, 
especially THROW/name, there are things that you can do with dynamic 
throw that you *can't* do with definitional, and those things would 
have great value, so it's a rational choice to make the tradeoff 
in favor of dynamic.
BrianH:
11-Nov-2010
Well it comes down to this: Functions are defined lexically. Though 
they are called dynamically, they aren't called until after they 
have already been bound, definitionally. But as a side effect of 
tasking, those bindings are stack-relative, and those stacks are 
task-local. But random blocks of code outside of functions are bound 
to object contexts, and those are *not* task-local. So that means 
that the old R2 practice of calling shared blocks of code is a really 
bad idea in R3 if any words are modified, unless there is some kind 
of locking or synchronization. This means that those blocks need 
to be moved into functions if their code is meant to be sharable, 
which means that at least as far as RETURN and EXIT are concerned, 
they can be considered lexically scoped. The advantage that we would 
get from being able to call a shared block of code and explicitly 
return in that block is moot, because we can't really do that much 
anymore. This means that we don't lose anything by switching to definitional 
code that we haven't already lost for other reasons. At least as 
far as functions are concerned, all task-safe code is definitional.


Loops are also defined lexically, more or less, and the rebinding 
ones are also task-safe because they are BIND/copy'd to a selfless 
object context that is only used for that one call and thrown away 
afterwards. And most calls to loops are task-safe anyways because 
they are contained in functions. However, the LOOP, FORALL, FORSKIP 
and WHILE loops do not rebind at the moment. We actually prefer to 
use those particular loops sometimes in R3 code because they can 
be more efficient than *EACH and REPEAT, because they don't have 
that BIND/copy overhead. Other times we prefer to use *EACH or REPEAT, 
in case particular loop fits better, or has high-enough repetitions 
and enough word references that the 27% overhead for stack-local 
word reference is enough to be more than the once-per-loop BIND/copy 
overhead. Since you don't have to move blocks into *loops* to make 
them task-safe, you can use blocks referred to by word to hold code 
that would be shared between different bits of code in the same function. 
This is called manual common subexpression elimination (CSE), and 
is a common optimization trick in advanced REBOL code, because we 
have to hand-optimize REBOL using tricks that the compiler would 
do for us if we were using a compiled language. Also, PARSE rules 
are often called from loops, and they are frequently (and in specific 
cases necessarily) referred to by word instead of lexically nested; 
most of the time these rules can be quite large, maximizing BIND/copy 
overhead, so you definitely don't want to put the extensive ones 
in a FOREACH or a closure.

Switching to definitional break would have three real downsides:

* Every loop would need to BIND/copy, every time the loop is called, 
including the loops that we were explicitly using because they *don't* 
BIND/copy.

* Code that is not nested in the main loop block would not be able 
to break from that loop. And code that is nested in the main loop 
would BIND/copy.

* We can in theory catch unwinds, run some recovery code, and send 
them on their way (hopefully only in native code, see #1521). Definitional 
escapes might be hard or impossible to catch in this way, depending 
on how they are implemented, and that would mean that you couldn't 
recover from breaks anymore.


The upside to definitional break would be that you could skip past 
a loop or two if you wanted to, something you currently can't do. 
Another way to accomplish that would be to add /name options to all 
the loop functions, and that wouldn't have the BIND/copy overhead. 
Or to use THROW or THROW/name.


The situation with THROW is similar to that of the non-binding loops, 
but more so, still task-safe because of functions. But CATCH and 
THROW are typically the most useful in two scenarios:

* Escaping through a lot of levels that would catch dynamic breaks 
or returns.

* Premade custom escape functions that might need to enforce specific 
semantics.


Both of these uses can cause a great deal of difficulty if we switched 
to definitional throw. In the first case, the code is often either 
broken into different functions (and thus not nested), or all dumped 
into a very large set of nested code that we wouldn't want to BIND/copy. 
Remember, the more levels we want to throw past, the more code that 
goes into implementing those levels. In the second case definitional 
throw would usually not work at all because the CATCH and the THROW 
would contained in different functions, and the code that calls the 
function wrapping the THROW would not be nested inside the CATCH. 
So you would either need to rebind every bit of code that called 
the THROW, or the definitional THROW would need to be passed to the 
code that wants to call it like a continuation (similar concept). 
Either way would be really awkward.


On the plus side of dynamic (whatever), at least it's easy to catch 
an unwind for debugging, testing or recovery purposes. For that matter, 
the main advantage of using THROW/name as the basic operation that 
developers can use to make custom dynamic escape functions is that 
we can build in a standard way to catch it and that will work for 
every custom escape that is built with it. The end to the arms race 
of break-through and catch.
BrianH:
11-Nov-2010
Yeah :) And I had another phone call.
BrianH:
11-Nov-2010
That is why I am in favor of definitional return, extremely skeptical 
of definitional break, and definitely opposed to definitional throw.
BrianH:
11-Nov-2010
Definitional (whatever) depends on a BIND to do its work, deep, usually 
BIND/copy. And that only works on words that are physically in the 
blocks that you bind, or in blocks that are nested in those blocks, 
etc. Another block that is outside the block you are binding and 
referred to by name won't be bound. That is the limit of the definitional 
approach.
Maxim:
11-Nov-2010
btw, for throw/catch, I agree 100%, even after I now, fully understanding 
the topic. 
   

If we lost dynamic throws, trying to make it work *as* a dynamic 
system is not pragmatic and AFAIK prone to many strange problems, 
especially if we try to create our own code patterns and would need 
to decipher cryptic mezzanine code which does some magic.


the way I see it, definitional throw/catch really doesn't scale well 
and doesn't work especially well in collaborative programming if 
there are multiple trap points with different catch setups.


I can see ways this can be a problem, especiallly when code IS NOT 
bound on purpose like in liquid which uses a class-based model, *specifically* 
because it allows me to scale a system by at least three orders of 
magnitude. 


liquid builds nodes on the fly and generally re-organizes processing 
on the fly.  one system might be building the setup, while another, 
later will execute it.  with definitional throw, this is impossible 
to make work.
Ladislav:
12-Nov-2010
Brian wrote: "BREAK also applies to PARSE, which relies on dynamic 
scope (and yes, I can point you to mathematical proofs of this, though 
there's no point)" - I *must* correct this! Parse break is:

- neither dynamic
- nor definitional

it is a third kind:

parse break is lexical

Here is why:


1) It is stated in the documentation, that "parse break is a keyword", 
i.e. it it lexically defined to be a keyword of the dialect

2) it is stated in the documentation, that it "breaks out from the 
nearest loop", which is true, but it the lexical sense again
BrianH:
12-Nov-2010
Except (break) and (break/return) were explicitly added to what PARSE 
supports. It was one of the better Parse Proposals, and it was accepted 
and implemented.
Ladislav:
12-Nov-2010
(and make no mistake, I mean the parse keyword, not the foreign (break) 
construct)
BrianH:
12-Nov-2010
You can not refer to structures by name in lexically scoped constructs, 
when those names are resolved at runtime. Well, you can, but then 
that becomes a dynamically scoped flow construct.
For instance:
a: [break]
b: [while a]


The word 'a is in the lexical scope of b, but the contents of a are 
in its dynamic scope only if b is used as a parse rule at runtime 
and a is still assigned that value. So even though the break is a 
keyword, the scope to which it breaks is the while, which is in b.
Ladislav:
12-Nov-2010
... I know that Ladislav's DO-ALL is a loop, and so not wanting BREAK 
to apply to it is more of an opinion than something inherent in its 
nature.

 - I was afraid, that the DO-ALL was not a fortunate choice! My original 
 problem with the property illustrated by DO-ALL occurred when I Implemented 
 my PIF (now called CASE for the newcomers), which was not meant to 
 catch any breaks, as is immediately obvious.
BrianH:
12-Nov-2010
It's cool. Your point was made, and the disadvantages of definitional 
break that you hadn't gotten around to adding to the page yet are 
stated above in that big message.
BrianH:
12-Nov-2010
Yup. But I was mostly referring to the standard way the loop functions 
are used. Most loops are mostly made up of nested blocks and such, 
with very little direct DO calls to other blocks by name.
BrianH:
12-Nov-2010
DO (or IF, or ALL, ...) of a block by name tends to only show up 
in advanced code. That code tends to be critical, and we usually 
can't afford to make it non-working, but not many people do that 
level of hand-optimization of their code, mostly because their code 
isn't that speed or size critical, or they don't know how (or they 
don't like that technique). On the other hand, PARSE rules called 
from loops are often referred to by name and are moved physically 
outside of the loops that call them for really good reasons, some 
of which I mentioned above.
Ladislav:
12-Nov-2010
{Ladislav, your definitional throw in the "Definitional CATCH/THROW 
mezzanine pair" section of your page isn't recursion-safe, because 
MAKE function! does a modifying BIND rahter than a non-modifying 
BIND/copy. } - I know that, but, since it is just an example, and,since 
it can be asily updated to copy, I wrote it this way. I can add copying, 
though
BrianH:
12-Nov-2010
Cool. It's a good hack, and it does a good job of illustrating the 
overhead of the definitional throw approach.
BrianH:
12-Nov-2010
The BIND/copy overhead is inherent in definitional scoping, except 
for function and closure creation where it is only a BIND, which 
was happening anyway. That is why definitional return is cost effective
Ladislav:
12-Nov-2010
(it breaks out from A, and there is nothing WHILE can do except A)
BrianH:
12-Nov-2010
Yeah, that break thing, I forgot: An interesting thing about PARSE 
was revealed during the course of implementing the parse proposals. 
It turns out that what most people (including me) thought about PARSE 
was wrong. ANY, SOME and WHILE aren't the only loops in PARSE for 
BREAK to break out of: Every rule is a loop. Even rules that don't 
have any iteration or repetition are effectively a LOOP 1. This means 
that while the *scope* of the BREAK operation in PARSE is definitely 
dynamic in its implementation (this also came out in discussions 
with Carl, though it doesn't use the unwind method), it is (afaik) 
impossible to construct a working example of BREAK that demonstrates 
this. I would love it if you could figure out how to write example 
code to prove this, Ladislav, since I've just been taking the author's 
word for it.
BrianH:
12-Nov-2010
It doesn't matter for R2 and R3's implementations of PARSE, but it 
might matter for someone who wants to make a compiler for the PARSE 
dialect (which is at least theoretically possible). That would be 
a really cool project :)
Ladislav:
12-Nov-2010
I guess, that it may be implemented dynamically, but, the way it 
is implemented, makes it indiscernible from lexical. And, finally, 
what matters most is not the implementation, but the behaviour.
BrianH:
12-Nov-2010
Dynamic scope and lexical scope have a lot of overlap. Being different 
in kind doesn't necessarily make them different in practice :)
BrianH:
12-Nov-2010
Of course, that is what makes it possible to consider changing to 
definitional return. If it was too different in practice, it wouldn't 
be an option, too much code would break and too much of the understanding 
of developers would break too.
Ladislav:
12-Nov-2010
...and, the biggest disadvantage of the dynamic return is the opposite 
- the fact, that knowing the lexically closest catching construct 
does not tell you, which construct will be the closest one at run 
time
BrianH:
12-Nov-2010
PARSE operates on dynamic scope, but many of its constructs are affected 
by the closest thing that REBOL has to real lexical scope: nested 
structures. Basically, the only real lexical scope in REBOL is the 
kind you can get from an unbound LOAD. The rest is faked using "definitional" 
processes. And the definitional process is itself dynamic (though 
it is a one-way process, so its scope isn't bounded).
Ladislav:
12-Nov-2010
Right, the main advantage of the definitional approach is, that it 
resembles the lexical case very well, where needed, and only in exceptional 
cases it looks differently
BrianH:
12-Nov-2010
That is true, but not enough - the dynamic transparency proposal 
also has that quality. The main advantage that only definitonal return 
has is that it can do things that dynamic return can't, even with 
transparency. And it does so with almost no added overhead, because 
the functions were getting bound anyway. That is why I support it.
BrianH:
12-Nov-2010
You don't lose anything that you haven't already lost for other reasons, 
and it is possible (in native code) to build in acceptable workarounds 
for its weaknesses, so there's no significant downside to definitional 
return (except the work Carl would have to do to implement it).
Ladislav:
12-Nov-2010
In the case of BREAK (I mean the one used in the DO dialect now), 
the situation is 50:50, since loops would be bound once, done many 
times anyway, making any slow-down % much smaller, and due to the 
fact, that some loops (as you mentioned earlier too), need to bind 
their bodies anyway
Ladislav:
12-Nov-2010
(and, that applies to the CONTINUE case as well)
BrianH:
12-Nov-2010
The binding time is *not* done anyway by all loops. It is only done 
by REPEAT and *EACH, and we now often avoid using those functions 
*because* they rebind. REPEAT and *EACH are mostly used for small 
loop code, because of that binding time *and memory use*, which is 
even more significant than time in a lot of cases.
BrianH:
12-Nov-2010
Code optimized to R3's characteristics is *much* more efficient in 
R3 than code optimized for R2. And it look better too (that was one 
of the reasons for a lot of the native changes).
BrianH:
12-Nov-2010
I've noticed that FOREACH, FORALL and MAP-EACH are used the most.
BrianH:
12-Nov-2010
Though FORSKIP is used a lot too. LOOP, REPEAT and WHILE aren't used 
much anymore, and I can't remember the last time I saw FOR used in 
real code, though I use it a lot in adhoc file management code.
BrianH:
12-Nov-2010
I like it. And yes, I forgot UNTIL. I haven't seen UNTIL used in 
R3 except in text and example code.
BrianH:
12-Nov-2010
I like your general cycle (except the name), and would use it in 
user code if it were available.
BrianH:
12-Nov-2010
Looks good to me. I don't like the word "cycle" for mezzanines, too 
academic (no offence, Ladislav :), and "general" is too long.
BrianH:
12-Nov-2010
Ladislav, Maxim, could you show some support for SELFLESS? Go to 
#1758 and leave comments. Carl changed it to "waiting".
BrianH:
12-Nov-2010
I did my best to argue for it by doing a thorough ticket and writing 
best-possible-without-it example code for LET and BIND-TO-NEW, to 
show how much it is needed.
Maxim:
12-Nov-2010
especially when you put GET and SET besides it... all of a sudden 
I wondered... well, shoudn't LET have been the very first function 
evaluator  :-D
Maxim:
12-Nov-2010
since self could be set to another context... it would be interesting 
since 

a  and  self/a  would effectively be different values  :-)
Maxim:
12-Nov-2010
and since we have full control over the self word, because we are 
supplying/setting it then our class builder could properly bind the 
class methods to our instance selfless context.
Maxim:
12-Nov-2010
the selfless object would be class and its self would point to the 
instance... something which is impossible with selfish contexts.
BrianH:
12-Nov-2010
Because that would be presumptuous and usually wrong :)
BrianH:
12-Nov-2010
You can add a self field to a selfless context and it can be used 
like any other field. That is the whole point to selfless contexts.
BrianH:
13-Nov-2010
If you like you can think of self as being a binding artifact in 
R3. At least it's not as much a keyword as 'export and 'hidden in 
module bodies :)
BrianH:
13-Nov-2010
And you might want to get into the habit of using CAUSE-ERROR, since 
it makes your code look simpler and hides the differences between 
R2 and R3 errors.
BrianH:
13-Nov-2010
I just realized something: You don't need word references to have 
the full power of PARSE, you can use circular direct references instead. 
Of course you can't specify those structures in loadable source, 
you have to construct them dynamically, and you can't BIND them so 
you stiff can't use definitional scope for its operations. But it 
is at least in theory possible to match the patterns that finite 
nested rules can't match by using circular structures.
BrianH:
13-Nov-2010
Really awkward to do so though, and you can't just see the structure 
in source so it is harder for many people to understand.
BrianH:
13-Nov-2010
Overall, the best and most efficient strategy for dealing with the 
problems of circular structures is to not use them, or to accept 
that they will have problems. Having *every* object have a circular 
reference in it was a bad idea because of that. Using word references 
instead of direct references is another way to deal with the problem 
though.
BrianH:
13-Nov-2010
Added a REBOL-code almost-equivalent to the SELFLESS ticket, based 
on your trick, and a couple minor bug fixed. Rewrote LET to use the 
same trick. Strangely enough, the LET version has less overhead than 
the SELFLESS version of the same trick, especially in the error handling 
code. The LET function is now efficient enough to be acceptable as 
a mezzanine function, though not yet efficient enough to be used 
to implement low-level mezzanine functions.
BrianH:
13-Nov-2010
We could really use a native LET or SELFLESS - either would do, actually, 
and could be used to implement the other.
BrianH:
13-Nov-2010
Other than that and a couple tweaks to fix similarly minor bugs here 
and there, it could be used in the ticket as-is.
Anton:
14-Nov-2010
Aha, full circle. I seem to remember SELF was added by user request, 
and now it might be removed to simplify things. If I could remember 
why the user(s) wanted it...
Ladislav:
14-Nov-2010
(and they *are* useful)
Henrik:
14-Nov-2010
Well, I think it would be clearer to see it applied in loops and 
using multiple values. As it is shown there, USE and DO FUNC are 
clearer to me. It may be very useful.
Ladislav:
14-Nov-2010
As far as the DO FUNC examples go, they are just equivalent to the 
LET examples, as is quite obvious. The distinctions are rather small, 
like the fact, that you do not need to create a function and then 
call DO
Ladislav:
14-Nov-2010
less overhead for the user (does not have to call DO), less overhead 
for the interpreter (does not have to create the function), and a 
couple more quirks like RETURN and EXIT handling
Maxim:
15-Nov-2010
on the question, why do we really need self:


self is very usefull when you use objects within code, because there 
can often be binding clashes.   self assures one that a parameter 
is always from the context and not from the function.

self.x: x


has occured pretty often for me.  its also very usefull when you 
need to return the context from which a function was bound.  
I also use it to do indirection: 

obj: self
context [
	parent: obj
]


remove self, and we can't say that REBOL has objects anymore.  many 
things will become really complicated for no reason.
42401 / 4860612345...423424[425] 426427...483484485486487