World: r3wp
[!REBOL3]
older newer | first last |
Geomol 24-May-2011 [8862] | Same can be said with refinements: >> /1a == /1a which looks to me like an error. |
Endo 24-May-2011 [8863] | it is because of lit-words cannot start with a number but refinements and issues can. |
Geomol 24-May-2011 [8864] | Yes, but what benefit do you have from refinements starting with a number? |
Endo 24-May-2011 [8865] | actually nothing :) it is useless because you can create a function like below, but you cannot use it: >> f: func [/1a] [] >> f/1a ** Syntax Error: Invalid integer -- 1a |
Maxim 24-May-2011 [8866] | IIRC it was discussed that numeral refinements should be removed from R3. |
Jerry 25-May-2011 [8867] | in the source code of load-module, the first line is ASSERT/TYPE [LOCAL NONE!] ... Why? |
BrianH 25-May-2011 [8868x4] | Geomol, refinements are not just for translating to paths. You can use a subset of the possible refinements for that purpose, but rest can be used for whatever reason you like in other dialects. REBOL is not just the DO dialect, remember. (This is the official answer; I am just writing it out again, for the 4th time this year.) |
Maxim, it was discussed and that proposal was rejected. | |
Jerry, the /local refinement is just another function option. If you provide that option when you call that function, you can provide initial values for the "local variables". In the case of sys/load-module, the security and control flow of that function depends on the local variables being initialized with the none value, so we want to avoid the /local option being used when the function is called. When a function refinement is not used its value is none, so if you want to ensure that it is none and trigger an error if it isn't, ASSERT/type [option none!] is the most efficient way to do this in R3. | |
After Carl asked me that question, Jerry, and got that answer, he wrote a blog where he suggested making /local special in functions. While most people are in favor of that (not half of the gurus), this proposed change to /local hasn't been done yet and we don't know if it will ever be done. | |
Jerry 26-May-2011 [8872] | Thanks very very much, BrianH. |
Geomol 26-May-2011 [8873] | (This is the official answer; I am just writing it out again, for the 4th time this year.) Why bother? No matter how many times you write it, this still is bad design. Or lack of design and bad implementation. It's like having integers, you can only use for the PICK function, but can't make arithmetic with. |
Ladislav 26-May-2011 [8874x3] | After Carl asked me that question, Jerry, and got that answer, he wrote a blog where he suggested making /local special in functions. While most people are in favor of that (not half of the gurus) - then I must have a problem with reading comprehension. I rechecked the discussion of this twice and came to a completely different conclusion |
My numbers as seen from the discussion: discussing: 11 for the change: 0 against the change: 2 neither for nor against the change: 9 | |
I did not try to categorize the votes futher to guru/non-guru, btw | |
Geomol 26-May-2011 [8877] | I'm looking at what kind of functions, R3 has: >> ? any-function! ANY-FUNCTION! is a typeset of value: make typeset! [native! action! rebcode! command! op! closure! function!] And then I come to think, if it's a problem having both native!, action! and function!. Should all 3 be seen as function! ? Having them all and now with the addition of closure, what if a native act like a closure? Should it then be a native-closure! ? Same with action! . And what if it's possible one day to make operators, should we then call the current operators for nop! (or native-op!)? I guess, these types originated, because they're dealt with differently internally, but should the users have to deal with the differences? |
Ladislav 26-May-2011 [8878] | I think, that the answers to your questions are simple. Closures and functions (while being nonnative) are so different, that it is more convenient to have them as different datatypes. what if a native act like a closure? - can you name any native that does not? As you mention, the current datatypes are likely the most convenient for the implementation. |
Geomol 26-May-2011 [8879] | I agree on distinguish between closures and functions, but maybe those whould be the only two, and then skip native and action. I remember being a bit confused about especially action! types, when I started on REBOL. |
Ladislav 26-May-2011 [8880] | How can that "confuse" anybody? Something may confuse you only if it suggests something that proves wrong later, which is not the case of two datatypes being used instead of just one you seem to prefer. |
Geomol 26-May-2011 [8881] | It confused me, because they are called differently, so as a programmer, I think "ok, this is two different things, so I have to use time to learn the differences between e.g. functions and natives, or natives and actions, and how to use them correctly". And in fact, as a programmer I can very well ignore the differences, because the 3 types works exactly the same in my programs. |
Ladislav 26-May-2011 [8882] | But the difference between functions and natives is obvious - speed |
Geomol 26-May-2011 [8883] | :) I badly written native might be slower than a well written function. |
Ladislav 26-May-2011 [8884] | You can certainly invent any number of generalizations, but you will not be able to find any example, I bet |
Geomol 26-May-2011 [8885] | I think, it was Bertrand Meyer, who wrote, that a datatype is recognized by the methods, you can use on it. In REBOL terms, what you can do with a datatype specify it. If you can do the same with a native! and a function!, they're the same datatype. |
Ladislav 26-May-2011 [8886x2] | OK, then, how do you get the body of a native? |
But, the fact is, that, seen from the Meyer's perspective, there should not be any distinction between actions and natives... | |
Geomol 26-May-2011 [8888x2] | That is up to the implementor/designer to deside. :-) Maybe it should be a number, like actions returns in R2, or none as R3 do. |
We can still try to get the body of a native and action, like we can with functions. So we can use them exactly the same way. | |
Ladislav 26-May-2011 [8890] | There is not "body of a native" you get. Both in R2 as well as in R3 you get just a "replacement value" |
Geomol 26-May-2011 [8891] | Correct! But that doesn't remove the fact, that I can use the method to get bodies on natives and actions, just like I can on functions. The methods define the datatype. |
Ladislav 26-May-2011 [8892x5] | Aha, so you are saying, that it does not matter whether you get a #[none!] or a block? |
I see it as a huge difference. | |
It is actually the same difference as a difference between causing an error or obtaining a block. | |
(a "caused error" can be considered a "special value" as well) | |
...and that is not my invention, you can find that principle in descriptions of many programming languages | |
Geomol 26-May-2011 [8897x2] | Good point. |
>> type? 10 / 2 == integer! >> type? 10 / 3 == decimal! I guess, that's two different divide operators in use then? :) | |
Ladislav 26-May-2011 [8899] | Actually, the above behaviour is unacceptable for many programming language designers (or users). |
Henrik 26-May-2011 [8900] | I wonder what happens in there. I would assume it would be slower to divide, if you have to make a check afterwards that it can be converted to integer, or is there something else fancy going on? |
Ladislav 26-May-2011 [8901] | Yes, certainly it is slower. |
Geomol 26-May-2011 [8902x2] | You need to something like: case INTEGER_T: { double r1 = (double) rb->value.i / (double) rc->value.i; int64_t i1 = (int64_t) r1; if (i1 == r1) { ra->value.i = i1; ra->type = INTEGER_T; } else { ra->value.r = r1; ra->type = REAL_T; } break; } |
But I guess, it's convenient, it works this way, as we think this way as humans. 10 / 2 is an integer, 10 / 3 is a real. | |
Ladislav 26-May-2011 [8904x2] | >> i: to integer! #{8000000000000000} == -9223372036854775808 >> i / -1 ** Math error: math or number overflow ** Where: / ** Near: / -1 |
is that consistent? And, if yes, why? | |
Geomol 26-May-2011 [8906x3] | My code works this way with your example: w> i: -9223372036854775808 == -9223372036854775808 w> i / -1 == 9.22337203685478e+18 |
So it returns a real. | |
Is it crazy to make the rule, that DIVIDE always returns a decimal! ? POWER always returns a decimal!, even if the inputs are integers and the output could be an integer. It would make DIVIDE faster. | |
Henrik 26-May-2011 [8909] | perhaps it is somewhat convenient for integer based datatypes, like pair or tuple, but consistency overrules it. |
Geomol 26-May-2011 [8910] | Hm, I may take that back. It may be compiler optimization, but always giving a real as output seem to be slower in my test. Or it could be, that giving the result involve slower cpu circuity, when it's a real compared to an integer. |
Henrik 26-May-2011 [8911] | it also works on R3 pairs: >> 3x1 / 3 == 1x0.3333333 |
older newer | first last |