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

World: r3wp

[Core] Discuss core issues

Gregg
18-Oct-2008
[11154]
From !REBOL3 group, following MattAnton's fbionacci func.


Matt, it's a good func, but there are some things to watch out for 
in REBOL, which are different from many other languages.


1) Undeclared vars in func become global. Use the /local refinement 
to declare them.


2) Series values in funcs (e.g. your starting block of [0.0 1.0] 
maintain their value between calls if you don't use COPY. Run your 
function multiple times to see what happens. It may be that you wanted 
this to be a memoizing function, but then why UNSET 'fibonacci-block?.


I think you also mentioned that the challenge was to do it recursively, 
which this isn't. That's a case where you would definitely want to 
memoize. :-)


In any case, this is always fun stuff to think about.  Here's a modified 
version for you to play with. Look at some of the other REBOL funcs 
used, see if you find any bugs, or maybe it will give you ideas for 
other ways to solve the problem.

fibonacci: func [

    "Returns a list of fibonacci numbers, up to the specified count."
	count [integer!] "Number of iterations to run"
	/trace
	/local res n-1 n-2 incr step
] [
    incr: func [word] [set word 1 + get word]
    step: does [incr 'n-1  incr 'n-2]
	res: copy [0.0 1.0]
	set [n-1 n-2] [1 2]
	repeat i count [
		append res add pick res n-1 pick res n-2
		step
		if trace [print [i last res]]
    ]
    res
]
print mold fibonacci 3
print mold fibonacci 46
Dockimbel
18-Oct-2008
[11155x2]
>> print mold fibonacci 3
[0.0 1.0 1.0 2.0 3.0]

Doesn't it supposed to return : [0.0 1.0 1.0 2.0] ?
Here's my attempt with a caching and fully recursive version :

fibonacci: func [n /local f][
	f: [0.0 1.0]
	either f/(n + 1) [copy/part f n + 1][
		fibonacci n - 1
		append f f/:n + f/(n - 1)
	]
]

probe fibonacci 3	
probe fibonacci 46
probe fibonacci 8

Note that :


1) The last call with 8 value is just an extraction of the pre-computed 
cached sequence (cached values up to 46th by the previous call), 
so it executes in 0(1).


2) References to 'n (except fibonacci n - 1) are incremented by 1 
to account for REBOL series 1-based indexes. If we could switch to 
0-based indexes, the function source would be more readable (closer 
to the pure algorithm).
Robert
19-Oct-2008
[11157x3]
Can someone help me with this?

>> open tcp://:12345
>> open tcp://:12345
** Access Error: Error opening socket listen port
** Near: open tcp://:12345
>> a: 12345
== 12345
>> open tcp://:a
>> open tcp://:a
>>
How can I use 'a as a reference to port 12345 as well?
Seems to be handled differently.
Graham
19-Oct-2008
[11160]
>> a: 1234
== 1234
>> p: open join tcp://: a
>> close p
>> p: open join tcp://: a
>> p: open join tcp://: a
** Access Error: Error opening socket listen port
** Near: p: open join tcp://: a
>> close p
Robert
19-Oct-2008
[11161]
Ah, thanks. I was irritaded by the concatenation of : and 12345 So 
I can write tcp://: 12345 as well.
Graham
19-Oct-2008
[11162]
p: open tcp://::a
Graham
25-Oct-2008
[11163x2]
I need to form the date in UTC coordinates....  eg. 2008-10-25T08:33:0.4Z

Anyone got something more elegant than this?

form-utc: func [ d [date!]
    /local 
][
    ; convert to GMT
    d: d - d/5 
    rejoin [ 
        d/year "-" 
        either d/month < 10 [ join "0" d/month] [ d/month ] "-" 
        either d/day < 10 [ join "0" d/day ][ d/day ] "T"
        either d/time/1 < 10 [ join "0" d/time/1][ d/time/1 ] ":"
        either d/time/2 < 10 [ join "0" d/time/2][ d/time/2 ] ":"
        round/to d/time/3 .1 "Z"
    ]
]
perhaps we can get a /utc option for date types??
Anton
25-Oct-2008
[11165x4]
either d/month < 10 [join "0" d/month][d/month]
becomes
either d/month < 10 ["0"][""] d/month
d/5  ->  d/zone
etc.
'd is not specified local
Gregg
25-Oct-2008
[11169x4]
'd is the param name.
REBOL.org has a couple ISO date formatting funcs, though I think 
a lot of us roll our own, sometimes ad hoc. It depends, too, on how 
flexible--or accepting of various inputs--you want it to be.
as-utc: func [date] [
    if all [date/zone  0:00 <> date/zone] [
        date: add date negate date/zone
    ]
    date/zone: none
    if none? date/time [date/time: 0:0:0]
    date
]

to-ISO8601-date: func [
    "Converts a date! value to an ISO 8601 format string."
    date [date!] "The date to format"

    /T           {Use T to delimit time value, rather than a space}
    /no-zone     "Don't include the timezone"
    /local pad z
][
    pad: func [val /to len] [
        val: form val
        head insert/dup val #"0" ((any [len 2]) - length? val)
    ]

    rejoin [
        pad/to date/year 4 "-" pad date/month "-" pad date/day
        either T ["T"] [" "]

        either none? t: date/time ["00:00:00Z"] [   ;<< reusing 'T here!
            rejoin [

                pad t/hour ":" pad t/minute ":" pad round t/second
                either no-zone [""] [

                    either 0:00 = z: date/zone ["Z"] [  ;<< setting 'z here!
                        rejoin [
                            pick ["+" "-"] z/hour > 0
                            pad abs z/hour pad abs z/minute
                        ]
                    ]
                ]
            ]
        ]
    ]
]
>> to-ISO8601-date/T as-utc now
== "2008-10-25T18:41:13Z"
>> to-ISO8601-date/T as-utc now/date
== "2008-10-25T00:00:00Z"
Graham
25-Oct-2008
[11173x2]
format I have is SS.FZ
so pad here will not pad 5.2Z to 05.2Z
Gregg
25-Oct-2008
[11175x2]
I looked at some of my stuff but, for some reason, I don't seem to 
have one that does the 0.0 format for seconds. Even my FORMAT func 
doesn't work for that, though it would shorten the rejoins a bit. 
e.g.

form-as-utc: func [date] [
    format as-utc date "yyyy-mm-dd\Thhh:mm:ss\Z"
]


Just have to change that last part for the seconds. But I can't remember 
if I've published FORMAT.
Yeah, I've seen that format as a standard, which is why I don't know 
why I don't have that. Must not have needed it. :-\
Graham
25-Oct-2008
[11177x5]
I ended up just by factoring out my formatting to
format-10: func [ d [integer! decimal!]
][
    either d < 10 [ join "0" d ]
    [ form d ]
]

form-utc: func [ d [date!]
    /local 
][
    ; convert to GMT
    d: d - d/5 
    rejoin [ 
        d/year "-" 
        format-10 d/month "-" 
        format-10 d/day "T"
        format-10 d/time/1 ":"
        format-10 d/time/2  ":"
        format-10 round/to d/time/3 .1 "Z"
    ]
]
I can understand that one :)
why is your as-utc so complicated ? What case am I missing?
can date/zone be none?
Gregg
25-Oct-2008
[11182x2]
It can in cases where I use it. e.g., cascading calls that may mod 
the date to UTC more than once.
Partly legacy as well. I can't remember if REBOL used to set the 
zone to none, rather than 0:00, or if that was something I did originally.
Graham
25-Oct-2008
[11184]
better to be safe than sorry!
Oldes
25-Oct-2008
[11185]
Rebol zone can be none in some cases.
Graham
25-Oct-2008
[11186]
do you know which?
Oldes
25-Oct-2008
[11187x2]
I'm probably wrong.. it looks it should not be none. It returns 0:0 
instead of none in all cases (event if there is no zone)
>> d: 1-1-2006/1:0:0+0:0
== 1-Jan-2006/1:00
>> d/zone
== 0:00
>> d: 1-1-2006 d/zone
== 0:00
>> d: now d/zone: none d/zone
== 0:00
Graham
25-Oct-2008
[11189]
the problem with dates is that if zone is 0, then it does not display. 
 I wasn't aware of any 'none issue.
Chris
25-Oct-2008
[11190]
do http://www.rebol.org/download-a-script.r?script-name=form-date.r
form-date now "%Y-%m-%dT%H:%M:%SZ%Z"
form-date/gmt now "%Y-%m-%dT%H:%M:%s"
Graham
25-Oct-2008
[11191x4]
didn't know about that one ... but
>> form-date/gmt now "%Y-%m-%dT%H:%M:%s"
== "2008-10-25T20:27:11.000000"
whereas I need
2008-10-25T20:27:11.0Z
Chris
25-Oct-2008
[11195x3]
Yep, you'd have to modify Brian's 'pad-precise...
do http://www.rebol.org/download-a-script.r?script-name=form-date.r

pad-precise: func [s [number!]][
skip tail rejoin ["0" round/to s 
0.1] -4]
form-date now "%Y-%m-%dT%H:%M:%SZ%Z"
form-date/gmt now "%Y-%m-%dT%H:%M:%s"
(a hack -- 'pad-precise shouldn't be global)
Graham
25-Oct-2008
[11198x5]
anyone have a nice word that does this
string: copy/part string n
maybe 'cut ?
more traditionally 'left
I do this a lot to make sure there is no text overflow in database 
fields
Chris
25-Oct-2008
[11203]
'truncate, or just 'clip ?