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

World: r3wp

[Core] Discuss core issues

GrahamC
28-Jul-2011
[1994]
this works to a point whereupon you start getting overflow
Sunanda
28-Jul-2011
[1995]
Overflow happens on dates around 68 years apart -- so probably safe 
for Petr's intended usage.
Maxim
28-Jul-2011
[1996]
68.04 years to be precise  ;-)  the seconds resolution in 31 bits

(power 2 31) / 60 / 60 / 24 / 365.25
Pekr
29-Jul-2011
[1997]
Max - thanks :-) I wonder why there is a difference between the 'difference 
and substraction ....
Geomol
29-Jul-2011
[1998x3]
You were subtracting 23 hours and 52 minutes from zero hours and 
2 minutes. That's -23:50.

With difference, the whole date plus time was given, then the difference 
is positive in this example.
Subtract on dates give you number of days. Subtract on times give 
you number of hours, minutes and seconds. Difference on dates (incl 
times) give you number of hours, minutes and seconds.
Maybe subtract on dates should only give days, if time is not given, 
else work as difference?
Henrik
4-Aug-2011
[2001]
I have a COPY/DEEP question:


When doing a COPY/DEEP, the first level requires that the argument 
must be a series!, port! or bitset! But when doing a /DEEP, I imagine 
that COPY traverses a series for elements and uses a different process 
than for the first level to determine whether the element can be 
copied. If it can't, it silently passes the value through.

Why can't we do that on the first level as well?
Gregg
4-Aug-2011
[2002]
Just so you can puT COPY everywhere, without caring about the type?
Henrik
4-Aug-2011
[2003]
I'm not really sure I want to, but I think it's interesting that 
there is a difference between the first level and other levels.
Gregg
4-Aug-2011
[2004]
It makes sense to me. Copy what can be copied. I like having the 
type check at the top level.
Henrik
4-Aug-2011
[2005]
I do dislike having to do:

either series? var [copy/deep var][var]


thing. Generally the programming needed for absolutely deep copy 
a value is too elaborate.
Gregg
4-Aug-2011
[2006]
I don't do that very often. If I did, I would just wrap it.
Geomol
4-Aug-2011
[2007x2]
I try to think of situations, where I would need to do that. I also 
don't think, I do it often. But it's an interesting idea. I try to 
come up with some situations, where I need to copy a value, that 
can sometimes be a series, sometimes not. Hmm...
Let's see: I need to copy a value, and it can be any value, so copy 
should work on any value. I don't see a flaw in that. I wonder, if 
it has come up before?
Steeve
4-Aug-2011
[2009x2]
Well I'm not against that, for sure. It's an,old debate.
I dislike annoying type checking errors messages. 

My point is that if a primitive function can't deal with a data type, 
the data should just pass thru silently.

But other peoples will object that error messages are favored for 
educationnal purposes... Uh !?

But year after year, I see that more and more functions have been 
corrected to be tolerant.
A good example is REDUCE
And yeah Geomol, COPY should act just like REDUCE.
if the input  is not a serie, it should just return it.
It would save lot of useless checking code in our script.
And lot of others functions should behave like that
Geomol
4-Aug-2011
[2011]
There is a lot of type checking in REBOL. I feel too much sometimes. 
Calling many functions involve two types of type checking, as I see 
it. Take ADD. Values can be: number pair char money date time tuple
If I try call ADD with some other type, I get an error:

>> add "a" 1

** Script Error: add expected value1 argument of type: number pair 
char money date time tuple

I can e.g. add pairs:

>> add 1x1 1x2    
== 2x3

and issues:

>> add 1.1.1 1.2.3
== 2.3.4

But I can't add a pair and an issue:

>> add 1x1 1.2.3
** Script Error: Expected one of: pair! - not: tuple!


So that's kinda two different type checking. First what the function 
takes as arguments, then what actually makes sense. If the user also 
need to make type checking, three checks are then involved. It could 
be, the first kind isn't done explicit for natives, and that it's 
kinda built in with the second kind. But for non-native functions, 
the first type checking is done:

>> f: func [v [integer!]] [v]
>> f "a"
** Script Error: f expected v argument of type: integer
Geomol
8-Aug-2011
[2012]
Does anybody know the reason, BACK was called that and not PREV?
Gregg
8-Aug-2011
[2013]
Perhaps because it's a complete word, rather than an abbreviation?
Geomol
8-Aug-2011
[2014x2]
Yeah, probably that. As not having english as my first language, 
I'm not sure, but isn't previous opposite of next and back opposite 
of forward? Or can back be opposite of next?
(Or maybe backward is opposite of forward to be real correct?)
Sunanda
8-Aug-2011
[2016]
English is probably too lenient. to say for sure :)
If you do a websearch for....
  "next back" button

....You'll see next and back are a common choice of names for navigating.
Gregg
8-Aug-2011
[2017]
'Previous is more formal, but depends on usage. e.g. "Go to the previous 
slide" versus "Go back one slide".
Geomol
8-Aug-2011
[2018]
Thanks!
Geomol
11-Aug-2011
[2019x2]
I came across a funny thing with binding. We've learnt, that the 
binding of words in a block is done, when the words are put into 
the block. This little example with two functions illustrate that:

blk: []

f: func [
	v
][
	insert blk 'v
	g v
]

g: func [
	v
][
	if v = 3 [exit]
	print ["v:" v]
	probe reduce blk
	g v + 1
]


F puts the word V into the block, then calls G, that has its own 
V. When G reduce the block, we see the original value of V from F, 
even if Gs V is changed:

>> f 1
v: 1
[1]
v: 2
[1]


Then I tried this next function, which puts V in the block in the 
start, then call itself with changed V value:

f: func [
	v
][
	if v = 3 [exit]
	if v = 1 [insert blk 'v]
	print ["v:" v]
	probe reduce blk
	f v + 1
]

>> clear blk
== []
>> f 1
v: 1
[1]
v: 2
[2]


This time, we see the latest version of V. The first V, which has 
the value 1, was put in the block, and it's still there somewhere 
in the system, but we get the V value from the latest F.

Is this a problem or a benefit, or is it just a bit strange?
Same behaviour in R2 and R3 btw.
Dockimbel
11-Aug-2011
[2021]
Nothing strange there. The local context indefinite extent is sometimes 
handy when deferred evaluation is required, but dangerous if side-effects 
are not controlled strictly. For example, it's handy for creating 
generators:

>> count: use [c][c: 0 does [c: c + 1]]
>> count
== 1
>> count
== 2
>> count
== 3
>> count
== 4
>> count
== 5
>> probe :count
func [][c: c + 1]
Cyphre
11-Aug-2011
[2022x2]
the binding of words in a block is done, when the words are put into 
the block
 I don't think this is true. See:
x: 10
blk: []
o: context [x: 20]
insert blk 'x
insert blk in o 'x
reduce blk
== [20 10]
So your examples works properly logical. In the first case (F and 
G usage) the 'v words are bound to particular functions (either F 
or G). In the case of second F all 'v words are bound only to the 
F fucntion.
Ladislav
11-Aug-2011
[2024x2]
the binding of words in a block is done, when the words are put into 
the block
 - that certainly is false
The first V, which has the value 1, was put in the block, and it's 
still there somewhere in the system, but we get the V value from 
the latest F.

 - this is again false, you should read the bindology article, where 
 the behaviour is analyzed, modelled and explained
Geomol
12-Aug-2011
[2026x7]
I guess, I was misunderstood. :/
Cyphre, in your example, when you insert the first x in the block, 
it's the x holding the value 10. To me, the x in the block is bound 
to the outher x at the time, you insert it into the block. The next 
x, you insert in the block, is the x from the context o. So at the 
time, you insert it into the block, that x in the block is bound 
to the x in o.


So the block holds two different x, and they're bound at the time 
of insertion. That's what I meant, when I said "the binding of words 
in a block is done, when the words are put into the block".


(Words can be rebound at a later time using e.g. BIND, but I'm not 
looking at that in these examples.) I don't have time and energy 
to argue with Ladislav right now. :)
outher x = outer x
(The x holding the value 10.)
Ladislav, I took a quick review of your "Bindology". What I mean 
correspond well with what you write in:
http://www.rebol.net/wiki/Bindology#Scope

The bug illustrated at the end of
http://www.rebol.net/wiki/Bindology#MAKE_OBJECT.21
is interesting! :)
That bug is really weird! I put in some prints to show, what's going 
on:

f: func [x] [
    get in make object! [
        a: "ok"
        if x = 1 [
            a: "bug!"
            print ["f 2 :" f 2]
            a: "ok"
        ]
		print ["a:" a "x:" x]
    ] 'a
]

When I run it, I get:

>> f 1      
a: ok x: 2
f 2 : ok
a: ok x: 1
== "bug!"

I can't get my head around, what's going on internally.
It's same result in R3.
Doc, I think, you miss my point about recursion. See:

>> f: func [v][if v = 4 [exit] print v f v + 1 print v]
>> f 1
1
2
3
3
2
1


There are several versions of V, one for each call to F. In my original 
examples, I put the first version of V in the block, but I see the 
latest version.
Dockimbel
12-Aug-2011
[2033x2]
You're right, I missed your point about recursion. As I understand 
it, the behavior you're observing is caused by function context values 
being pushed on stack on recursive calls, as showed by Ladislav's 
simulation (http://www.rebol.net/wiki/Bindology#Model_of_function_evaluation
). So the value of 'v word bound to 'f context, inserted in a block 
and evaluated later, depends on the "current" level of 'f function 
recursion.
as showed
 => "as shown"
Geomol
12-Aug-2011
[2035]
Yes, you got it. Thanks!

I'm not saying, this is a bug, I'm just wondering about the behaviour. 
It might actaully be seen as a benefit, as this gives us 2 different 
behaviours depending on, if we use recursive calls or call another 
function (which can then be recursive), like the G function in my 
original examples.
Dockimbel
12-Aug-2011
[2036]
It looks like a side-efffect of the implementation, I do not think 
that this behavior was planned as a feature. I guess some recursive 
algorithms could benefit from it, but I fear it can quickly lead 
to code that is hard to maintain.
Geomol
12-Aug-2011
[2037x2]
Yeah, that's also my concern.
Are there other high level languages (or maybe interpreted languages), 
that can put references to variables into tables? I took a look at 
Python and Lua, but I don't think, they can.
Dockimbel
12-Aug-2011
[2039]
I don't remember seeing such property in another language. What about 
io or self?
Ladislav
12-Aug-2011
[2040x4]
I can't get my head around, what's going on internally.

 - I do not know if you already got your head around or not, but the 
 behaviour is exaplained by the simulation.
Anyway, the explanation is as follows: since the function F is called 
twice, it creates two objects having the attribute A. While the first 
object has got the attribute A set to "ok" initially, it ends up 
having the attribute A set to the "bug!" string before the F is called 
for the second time. After the second call to the function F occurs, 
the function does not "see" the first object's A attribute when setting 
the A using the a: "ok" expression.
Regarding "There are several versions of V, one for each call to 
F" - the fact is, that there is only one version of the word 'V, 
not "several". If you wanted to have "several versions of V" you 
could have used a closure, as is demonstrated later.
http://www.rebol.net/wiki/Bindology#Computed_binding_functions_.28Closures.29