World: r3wp
[Core] Discuss core issues
older newer | first last |
Gabriele 16-Aug-2011 [2136x2] | MOLD missing words context: where did I ever say this was a feature? As Ladislav said, this is just a non-trivial problem, because to solve it you may have to save the whole interpreter state. (One of your X there is bound to system/words, if you save that you basically save everything.) |
So the block should define the binding, not each word. - that kills dialecting. Geomol, really, have a look at Scheme. It works exactly like you want... REBOL works differently for a reason. | |
Geomol 16-Aug-2011 [2138] | Ladislav, if you try follow my thoughts, you can figure that out yourself. Steeve, maybe that law is a design flaw, that causes many problems? Like the example returning "bug", which started much of this conversation. Gabriele, ... Gabriele, you strengten my tolerance, and thank you for that. "that kills dialecting" I've seen you writing that before, and it puzzles me every time. (Well, probably different understanding again.) Thank you for suggesting Scheme, but I don't have time to dig into a new language right now. Should we let it rest? |
Ladislav 16-Aug-2011 [2139] | Ladislav, if you try follow my thoughts, you can figure that out yourself. I cannot, but nevermind |
Geomol 16-Aug-2011 [2140] | Gabriele, it hard to have a conversation, when you go to extremes like in the following: I don't understand where the complication is. Should writing a: [...] also do a copy? Should everything do a copy? You're arguing that sometimes REBOL should copy things, sometimes not. *That* is a list of complicated rules. Do REBOL copy things sometimes today? Like in function definitions: make function! spec body Maybe REBOL should copy in the example, we discuss, maybe it's a bad idea. The complication (for me and most likely others) in the above example is, when I read it, I would expect some output from my intuition. The actual output is different, and it's really hard to see, why that output is intentional. |
BrianH 16-Aug-2011 [2141x2] | MAKE function! doesn't copy its arguments. The wrappers for it in R3 copy their arguments explicitly, but the MAKE operation doesn't, for efficiency and flexibility. The same goes for MAKE closure! vs. CLOSURE, and MAKE module! vs. MODULE (for unbinding, not copying). |
None of these copy by default for three reasons: - You can't uncopy something that's been copied, but you can copy something that hasn't been copied yet. - MAKE doesn't take options that can't fit in its argument(s), so optional behavior can only happen if the spec says so. - Efficiency means avoiding copying, particularly in a non-compiled language. That's why a so many functions are modifying. | |
Ladislav 16-Aug-2011 [2143] | Yes, and there is no reason, why such a rule could not be held for e.g. CONTEXT, to follow the suit as well |
BrianH 16-Aug-2011 [2144x2] | Yup. The reason that CONTEXT currently doesn't copy is the same as why MODULE doesn't copy: They are generally used for one-off creations, based on large specs that are rarely reused, and inefficient to deep-copy. We could easily make them copy, but it would continue to be a bad idea for those reasons. |
The FUNC used to load the mezzanine functions at startup doesn't copy either, for the same efficiency reasons. | |
Ladislav 16-Aug-2011 [2146] | Hmm, I doubt it is needed |
BrianH 16-Aug-2011 [2147x2] | Doing it that way shrinks the startup time and memory quite a bit. There's a lot of the loading process that is dedicated to reducing code copying. |
This is also why that while most of the large mezzanine functions are written using FUNCT, the actual mezzanine build process converts those definitions to calls to the non-copying FUNC, with no preprocessing or copying needed at startup time. The user-level mezzanine FUNC is copying for safety reasons though. | |
Gregg 16-Aug-2011 [2149] | We all know you can make REBOL do just about anything. We also know there are a few things that trip people up (e.g. copying series values defined in funcs). My questions for John are: 1) Has this behavior ever been behind a bug in any of your REBOL code? If so, what was the context and what was the impact (e.g., how did you work around it)? 2) If you got your wish, what would the consequences be? i.e., how would it change REBOL? |
Geomol 17-Aug-2011 [2150x2] | More confusion? >> body: [a + b] == [a + b] >> f: make function! [a b] body >> pick :f 2 == [a + b] >> same? body pick :f 2 == false >> insert body '- == [a + b] >> body == [- a + b] >> pick :f 2 == [a + b] >> f 1 2 == 3 To me, MAKE function! seem to copy the body block. What are the arguments, that the body block isn't copied? |
Gregg, I get back to you, as answering your questions might take this into another direction. | |
Gabriele 17-Aug-2011 [2152] | Geomol, it's not make that copies the function body, it is pick. that was added for "security" reasons. blame Brian for this sort of things. :P |
Geomol 17-Aug-2011 [2153x2] | Gabriele, that can't be true. See: >> b: [a] == [a] >> blk: [] == [] >> insert/only blk b == [] >> blk == [[a]] >> same? b pick blk 1 == true |
(Notice this is the "Core" group, not the "!REBOL3" group, and I'm talking R2.) | |
Ladislav 17-Aug-2011 [2155] | Gregg: "1) Has this behavior ever been behind a bug in any of your REBOL code? If so, what was the context and what was the impact (e.g., how did you work around it)?" - you should not have asked this question, since the answer is already present above |
Gabriele 17-Aug-2011 [2156x4] | Geomol, I meant PICK when done on a function! value. |
ok, no, you're right and that was R3. R2 copies on make function!. to me, *this* is a bug. or rather, either make should always copy or it should never do it. having exceptions is silly. | |
(note, exceptions are added to make people happy wrt to "bugs" like the one you described above. the result is more confusion imho.) | |
(always copy would make sense only if rebol could do copy on write - which is a bit tricky. given the way rebol works "never copy" makes much more sense, then you add copy to helpers like FUNC etc. Then, we can discuss whether CONTEXT should have a copy, and imho it should not because this "bug" never happens in practice.) | |
Ladislav 17-Aug-2011 [2160x3] | 'this "bug" never happens in practice' - that is actually false |
Moreover, it is silly, that all helpers copy, but CONTEXT does not, isn't it? | |
;-) | |
Geomol 17-Aug-2011 [2163x7] | Ok, now we're getting somewhere. A question is raised, if MAKE should copy arguments given to it. This isn't the bug, as I see it, and I'll explain that a bit later. But first, if MAKE disn't copy the body block when making a function, then we would be able to change the function by changing the original block. Like: >> b: [] == [] >> f: make function! [] b >> f >> insert b 42 == [] >> f After the last call to f, we would get the result 42, if the body block wasn't copied. This is not desirable to me. Is it to you guys? |
Then the MAKE object! . The block given to make this time is also copied, as this shows: >> b: [a: 1] == [a: 1] >> o: make object! b >> third :o == [a: 1] >> same? b third :o == false >> append b [c: 2] == [a: 1 c: 2] >> third :o == [a: 1] So the block is copied, and then that's not the reason, the example from Ladislav's Bindology returns "bug". | |
Let's look at the example again. My version of the example is this: f: func [x] [ get in make object! [ a: "ok" if x = 1 [ a: "bug!" f 2 a: "ok" ] ] 'a ] I can pick the inner-most block this way: >> b1: pick pick pick :f 2 5 7 == [ a: "bug!" f 2 a: "ok" ] Now I run the example and pick the block again: >> b2: pick pick pick :f 2 5 7 == [ a: "bug!" f 2 a: "ok" ] >> same? b1 b2 == true It's the same block. | |
I ran the example before b2 was picked with: >> f 1 == "bug!" So, running the example, which makes the object doesn't change the block (other than binding) and MAKE object! makes a copy of the block. The conclution to me is, that MAKE rebinds the block before copying it, where it should do that after making its copy, andt that is a bug. | |
Sorry for a couple of long posts, but this takes room to explain. | |
Also, if MAKE object! didn't copy the block argument, then the code in the block would still be in the object, and this is not desirable. That is, the object would hold all this information: [ a: "ok" if x = 1 [ a: "bug!" f 2 a: "ok" ] ] Instead of just [a: 1]. | |
Sorry, instead of just [a: "ok"]. | |
Ladislav 17-Aug-2011 [2170x4] | MAKE object! makes a copy of the block I gave a proof it does not make a copy. Interesting, how much you try to reinvent the wheel, taking into account, that the correct explanation to your results is available from public sources. |
A copy of the MAKE OBJECT! block is actually never made, as this example shows: b: [a: 1 "this is the block"] o: make object! b third o good luck with reinventing the wheel instead of reading publicly availalbe sources that explain what is going on | |
The fact is, that the object does not "store" any block, only the THIRD function tries to "create" something like that | |
That can be easily proven by examining: same? third o third o | |
Geomol 18-Aug-2011 [2174x4] | Cool, thanks! This is complicated! :) |
So we're back to, it isn't a bug, that MAKE doesn't copy the block, when making objects. It's intended behaviour. And MAKE does copy the block, when making functions, and that is intended behaviour too. And the SECOND function doesn't try to create a block, when used on functions: >> f: does [] >> same? second :f second :f == true while THIRD does do that, when used on objects. | |
Gregg, about your questions. 1) Has this behavior ever been behind a bug in any of your REBOL code? If so, what was the context and what was the impact (e.g., how did you work around it)? I guess, you mean series inside functions. I'm not for everything should do a copy, as Gabriele imply. The problem with series in functions is only a problem, because functions in REBOL isn't functions in the traditional understanding. They are semi-closures. If they were functions, the local values would just be on the stack. Because the locals live on, this was a problem for me years ago. First I solved it by putting COPY in series definitions, then I in many cases changed to just do a CLEAR, like in: local-block: clear [] Now with the discovered behaviour regarding objects, I find the binding rules so complicated, that I would forget, how it works in two weeks. I will remember, that I have to be very careful, when making objects inside functions, especially if it's recursive functions. The consequence for me is, that I will probably put COPY/DEEP in, when making objects. As I won't start new big projects in REBOL, I will probably not do this a lot in practice. | |
The second question was: 2) If you got your wish, what would the consequences be? i.e., how would it change REBOL? When making an object in REBOL, I think of it as making a context. When making a function, I also assiciate this with making a context. If the rules were somehow similar regarding the two different contexts, it would be easier or more "simple", as I see it. If your question was about binding, that I suggest blocks should define the binding and not each word, then that's a change, I find interesting but can't see the full consequences of. I think, it would work, and work well. | |
Ladislav 18-Aug-2011 [2178x5] | And MAKE does copy the block, when making functions, and that is intended behaviour too. - not exactly, in R3 it does not |
And the SECOND function doesn't try to create a block, when used on functions: - again, not exactly, in R3 this has changed | |
On the other hand, it is not hard to understand why the THIRD function creates the block: there is no other option, since the block is not available from anywhere, so it *has to* create it | |
...Because the locals live on, this was a problem for me years ago. First I solved it by putting COPY in series definitions... - sorry to chime in, but I simply have to. The issues you mention (series in functions, extent of function locals) are not related. For example, the extent of function locals has changed a bit in R3, while the issue with series remains unchanged. | |
I can easily prove, that the extent of function locals is immaterial, when the behaviour of series in functions is examined. | |
Gabriele 18-Aug-2011 [2183x2] | that all helpers copy - in R3? Yeah, maybe the all should, though I still prefer to be practical here. i've never had to copy the block passed to context for eg. |
So the block is copied - your conclusion is wrong. the object does not "keep" the block it is made from. THIRD simply generates its output each time. | |
Geomol 18-Aug-2011 [2185] | Yeah, I discovered that. Confusing, I think. |
older newer | first last |