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

World: r3wp

[Core] Discuss core issues

Gabriele
29-Feb-2008
[9355x2]
leap?: func [y] [2 = second to date! reduce [y 2 29]]
(probably not any better than the above)
[unknown: 5]
29-Feb-2008
[9357]
drop one character and change the to date! to to-date.  ;-)
Geomol
29-Feb-2008
[9358x2]
Nice one, Gabriele! It's a force in REBOL, that you can do things 
in many ways. So we often find a way, that suit us well. Of cource 
it can also be a little confusing and hard to find the 'best' way 
for you.
In most cases, we run circles around the other languages out there! 
:-)
Dockimbel
29-Feb-2008
[9360x6]
leap?: func [y][2 = second poke 29/02/2000 1 y]
A bit faster, but I'm not sure it would work correctly on big-endian 
platforms.
Alternative ways :
leap?: func [y /local c][c: 29/02/2000 c/year: y c/month = 2]

diy?: func [y][
    366 - to-integer to-logic any [
        positive? y // 4
        all [
            zero? y // 100
            positive? y // 400
        ]
    ]
]
(to-logic is useless here and should be removed)
Btw, using the =? operator instead of = for the ending test in 'leap? 
would make it more readable for non-rebolers.
[unknown: 5]
29-Feb-2008
[9366x4]
Could also use REBOL's error handling routines such as:
leap?: func [y][date? try [to-date join "29/2/" y ]
But that is not as efficient.
But it is short.
Gregg
29-Feb-2008
[9370x2]
So, if we had a built-in, or standard library implementation of LEAP-YEAR?, 
would you want it to be the shortest or fastest one? The easiest 
to understand? The most REBOLish? 


The various approaches people use in REBOL always makes me think 
about this, and how hard it is to choose sometimes. e.g. here's mine:

leap-year?: func [

 {Returns true if the specified year is a leap year; false otherwise.}
	year [date! integer!]
	/local div?
][
	either date? year [year: year/year] [

  if negative? year [throw make error! join [script invalid-arg] year]
	]
	; The key numbers are 4, 100, and 400, combined as follows:
	;   1) If the year is divisible by 4, it’s a leap year.

 ;   2) But, if the year is also divisible by 100, it’s not a leap 
 year.

 ;   3) Double but, if the year is also divisible by 400, it is a 
 leap year.
	div?: func [n] [zero? year // n]
	to logic! any [all [div? 4  not div? 100] div? 400]
]
Using REBOL to help figure it out, even with error trapping, seems 
very REBOLish. 


Also, My days-in-year func is based on leap-year?, rather than the 
other way around, and John did.
[unknown: 5]
29-Feb-2008
[9372]
Gregg, my preference is the one that offers the best performance.
BrianH
29-Feb-2008
[9373x2]
My priority for library functions goes like this:
1. Stable
2. Fast
3. Easy to use
4. Easy to understand the implementation


That last one is only for maintainability - otherwise it is not a 
priority at all for library code.
Error trapping has a lot of overhead, so the more you can avoid basing 
your library code on it, the better off you will be.
[unknown: 5]
5-Mar-2008
[9375]
anyone know what stats/types counters are reflecting?  i know when 
I add a block for example the counter remains the same value.
btiffin
5-Mar-2008
[9376]
How transient are the blocks?  REBOL seems to do a fair job of not 
over allocating.   a: copy [] a: copy [] will only change the count 
by an entry, not two.   a: copy [] insert/only a copy [] should change 
select stats/types 'block! by two or so.

afaik
[unknown: 5]
5-Mar-2008
[9377]
I figure if I created a block it would update the counter for each 
new block created as long as the older ones were still set as well.
btiffin
5-Mar-2008
[9378]
Well, yes, but it could well replace an unused slot etc etc ... (I'm 
GC clueless) etc etc.  Wrapped in recycle you should see the numbers 
change a little more sensibly.
[unknown: 5]
6-Mar-2008
[9379]
That's just it Brian.  All I did was open up the console and assigned 
a word a block value and check the stats/types for the block counter 
and it didn't change.  I added another one and still didn't change. 
 So I'm a bit perplexed.
btiffin
6-Mar-2008
[9380]
Yeah, even after boot there are reallocatable blocks.   Try recycle 
first thing in the console, then run the experiments.  Once again, 
this is only afaik, 'cause I don't.
Gregg
6-Mar-2008
[9381]
REBOL may allocate things in "pools" for efficiency. You shouldn't 
care Paul, except in extreme cases.
[unknown: 5]
6-Mar-2008
[9382]
Yeah but if I know how they work I might be able to utilize that 
functionality in the future ;-)
[unknown: 5]
7-Mar-2008
[9383x4]
Here is a total flatten function:
b: func [blk [block!]][to-block trim/with mold/only blk "[]"]
forgot to name it - here instead:
flatten: func [blk [block!]][to-block trim/with mold/only blk "[]"]
BrianH
7-Mar-2008
[9387]
That kills the bindings of the words - is that intentional?
[unknown: 5]
7-Mar-2008
[9388x5]
Yes it is intentional if someone wants to completely flatten a block.
I can't see where someone would want to keep context if they are 
deciding to flatten it to that extreme.
I have a more useful flatten function that encompasses that one that 
will be more useful for someone that wants to keep contexts of no 
so flattened blocks.
It could probably be a mezz as it is very useful
Brian, I'll see if I can whip up my comprehensive flatten function 
to include a context sensitive full flatten and post it here.
BrianH
7-Mar-2008
[9393]
Here's a version which modifies in place:

flatten: func [blk [block!] /local rule a b] [
	parse blk [some [a: set b block! (change/part a b 1) :a | skip]]
	blk
]
[unknown: 5]
7-Mar-2008
[9394]
Nice Brian
BrianH
7-Mar-2008
[9395]
I've had to do something like it before. It doesn't preallocate or 
copy, but what can you do.
[unknown: 5]
7-Mar-2008
[9396x2]
yeah true
Are they planning to put something like a flatten function in R3?
BrianH
7-Mar-2008
[9398]
You can copy/deep first if you like, though that has allocation overhead. 
A version was proposed in the R3 discussions, but hasn't made it 
through the screening process (not general-use enough I guess).
[unknown: 5]
7-Mar-2008
[9399]
to bad I can see why we need it.
BrianH
7-Mar-2008
[9400]
Here's the thing: How often are you going to use it?


We are modularizing REBOL so that you don't have to bundle the whole 
thing together. Functions like FLATTEN would make a great addon module, 
but if the core code doesn't need it, or it's usage would be uncommon, 
it doesn't make the cut.


For that matter, the functions in R3 that I am backporting to R2 
are only those that I have actually seen in regular use in R3 mezzanine 
code. There are some more advanced functions that just won't be making 
it because their design hasn't been settled yet.


Picking something to go into the core is an involved process. And 
you can always make code libraries.
[unknown: 5]
7-Mar-2008
[9401x4]
I agree with that.  keep it out and use it as a module.
>> help flatten
USAGE:
    FLATTEN blk /fine /semi /full

DESCRIPTION:
     Returns a new block with desired blocks flattened or removed
     FLATTEN is a function value.

ARGUMENTS:
     blk -- block to flatten (Type: block)

REFINEMENTS:
     /fine -- Flattens blocks to finest representation
     /semi -- Flattens to support 'select operations
     /full -- Flatten fully - ignored with other refinements
flatten: func [

    {Returns a new block with desired blocks flattened or removed}
    blk [block!] "block to flatten"
     /fine "Flattens blocks to finest representation"
     /semi "Flattens to support 'select operations"
     /full "Flatten fully - ignored with other refinements"
     /local blk2
    ][
    blk2: copy []
    fl: func [b][
        either parse b [block!][
            b: first b
            fl b
        ][
            either semi [
                insert tail blk2 b
            ][
                either full [

                    foreach val b [either block? val [fl val][insert tail blk2 val]]
                ][
                    insert/only tail blk2 b
                ]
            ]
        ]
    ]

    if fine [full: none while [parse blk [block!]][blk: first blk]]
    foreach item blk [
        either block? item [fl item][insert tail blk2 item]
    ]    
    blk2
]
>> test: [[1 ["select"]] [2 ["me"]]]
== [[1 ["select"]] [2 ["me"]]]
>> flatten/semi test
== [1 ["select"] 2 ["me"]]