r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3]

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
[8911x2]
it also works on R3 pairs:

>> 3x1 / 3
== 1x0.3333333
But:

>> a: 3x1 / 3
== 1x0.3333333

>> a/1
== 1.0
Geomol
26-May-2011
[8913x4]
Hah! :)
Ah, pairs are always decimals.

>> first 1x1
== 1.0
So he does in pairs in R3, kinda the same thing Lua does with its 
numbers. They're always reals internal, but is presented as integers, 
if they can.
Why was REFLECT introduced? Couldn't SELECT be used? Did Carl write 
about REFLECT anywhere? (I tried search the blogs.)
onetom
26-May-2011
[8917]
i just discovered reflect by looking at the source of body-of  spec-of 
and stuff.
can't recall reading about it anywhere else
Henrik
26-May-2011
[8918]
Geomol, objects have series abilities now, so SELECT wouldn't work.
Geomol
26-May-2011
[8919x2]
ah, I see. (I even think, this was discussed somewhere.) Hm, not 
an easy call.
so you are saying, that it does not matter whether you get a #[none!] 
or a block?


If natives and actions were called functions (datatype function!), 
then getting their bodies could also just return an empty block instead 
of none (if that's a problem from a language technical view). But 
it can't be a big problem, as so many functions in REBOL return a 
value different from none, if success, else none. Like PICK, SELECT, 
...
Ladislav
26-May-2011
[8921x2]
...it can't be a big problem...

 - this is not about any "big problem". This is "only" a problem of 
 a definition. You seem to be saying, that, formally, you can get 
 the "body" of a native. Of course, you can define the BODY-OF function 
 however you want. But, that is a "super-formal" approach, since, 
 in fact, you are unable to get the body of a native no matter how 
 much you pretend "it is not a big problem". In the same "super-formal" 
 way you can evaluate BODY-OF 1 and say, that it (formally) is possible 
 too, "yielding" a "triggered error". What I am trying to note is, 
 that a part of the definition should be when we can we reasonably 
 "can get the body" and when not.
Reasonable definitions are of advantage over some non-reasonable 
I would say.
BrianH
26-May-2011
[8923x4]
Geomol: "Why bother?"

The reason that this kind of question is asked is because a lot of 
people seem to forget that REBOL is any more than its built-in dialects. 
I have to answer to remind people that the point of these syntax 
types is for users to use when creating their own dialects. Given 
that, a feature being useless for the built-in dialects is not a 
suffcient reason to restrict it. In order to justify restrictions 
the feature has to be actively harmful, as opposed to just passively 
unused, because it could be useful to user-level dialects.
Ladislav, thanks for looking up the /local blog and getting the actual 
numbers - I didn't have the time. I think that the only votes against 
the change were by gurus, while the rest of the responding gurus 
abstained like me.
Geomol, about native-op!, native-closure! and native-action!, these 
won't be necessary. Functions of the native! type don't need to bind 
their bodies to contexts, so they don't need the feature that makes 
closures closures. Ops and actions both redirect to the actual implementing 
function, which in the case of actions is an internal native associated 
with the type of the first argument, and in the case of op is a (at 
the moment only native) function provided at op creation time. If 
you wanted to allow the creation of user-defined datatypes with function!, 
closure! or command! implementations of the type's actions, the regular 
action! functions would still redirect to these implementations. 
Similarly, the regular op! type could be extended to support redirecting 
to other function types without needing the creation of a new function 
type.
Why was REFLECT introduced?

 - REFLECT was my idea, as a way to get metadata about a type without 
 overloading the ordinal functions. This was a security measure so 
 that you could make the ordinal functions available to untrusted 
 code safely, and not make REFLECT and the *-OF functions available, 
 which would make untrusted code potentially more useful.

Couldn't SELECT be used?
>> select context [body: 1] 'body
== 1
>> reflect context [body: 1] 'body
== [
    body: 1
]
Geomol
26-May-2011
[8927]
Aha, so that's how it got in there ... and for security reasons! 
So you're the one, we should beat up, when times come. ;)
Ladislav
26-May-2011
[8928x3]
I think that the only votes against the change were by gurus, while 
the rest of the responding gurus abstained like me.
 - that *very much* depends on who you consider gurus
Functions of the native! type don't need to bind their bodies to 
contexts

 - in that sense, natives behave both as functions and as closures 
 at the same time. That is not as a big of an exception, as it may 
 look, e.g.:

    f: func [][]

behaves as a closure, similarly as

   g: func [x y][add :x :y]


, simply because in such simple cases it is not discernible whether 
the given "function" is a function or a closure
(although the last case may be made function/closure sensitive, if 
we redefine ADD and make it "sufficiently complicated")
Maxim
26-May-2011
[8931]
where was the /local discussion ?  I'd like to review it  :-)
Geomol
26-May-2011
[8932]
There is some in Core group 12-May.
Maxim
26-May-2011
[8933]
wrt to the /local, its strange as I recall it being dependent on 
the way it was implemented and what it would actually prevent and 
why.  most people don't really care in the sense that it wont really 
change any of their code.  but I think added security by disallowing 
/local being given would be nice.  


Right now, we can easily inject code within functions by giving function! 
types as /local parameters.
Geomol
26-May-2011
[8934x3]
And http://www.rebol.net/cgi-bin/r3blog.r?view=0341#comments
I'm not sure, and maybe it's a gray area. Are you familar with contracting 
between caller and function as described by Bertrand Meyer?


If you promise to call *r* with *pre* satisfied then I, in return, 
promise to deliver a final state in which *post* is satisfied.

*r* is a routine in his words.
In other words: "If you f*** my function up by giving strange arguments, 
then you're on your own."

And I guess, /local arguments to functions can be used for something 
good in some cases.
Kaj
26-May-2011
[8937]
The ability to do that is limited for an interpreter until it becomes 
too slow
Maxim
26-May-2011
[8938]
the blog discussion attacks the use of /local in a myriad of ways, 
but few actually talk about  making /local or what they would accept 
or not if it were a "reserved"/uncallable refinement.
Geomol
26-May-2011
[8939]
See /local as any other refinement! You can inject code just the 
same using any refinement and additional arguments.