AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 4382 |
r3wp | 44224 |
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 / 48606 | 1 | 2 | 3 | 4 | 5 | ... | 423 | 424 | [425] | 426 | 427 | ... | 483 | 484 | 485 | 486 | 487 |