World: r3wp
[Core] Discuss core issues
older newer | first last |
Anton 16-Oct-2008 [11119] | Geomol, when FUNC is evaluated, a new function is created, along with a new "function context", as we say. The words in the function body block are then bound to the new function context. There are only two words in the block, 'do and 'code. So those are the only words affected. This binding only happens *once*, at function creation time. It does not happen again automatically when the function is evaluated for the first time, or any time afterwards. Even if it did, it would not affect the block of words referred to by 'code, because, as I've said above, BIND does not evaluate words to check if they are a block so it can recurse into them. (If it did, that would have far reaching consequences.) Not having to rebind words each time the function is evaluated keeps it efficient. If we want 'foreign' code to be bound to a function's context so it can interact with the function's locals, then we have to do it ourselves; functions created by FUNC won't do it for us. |
Geomol 16-Oct-2008 [11120] | I see. If it's more efficient (faster) this way, then it's a good thing! :-) I (and others) just have to remember it and act accordingly. |
Anton 16-Oct-2008 [11121] | Actually, it would be quite annoying for functions to automatically bind code like that. Suppose we had a code block and we wanted to send it somewhere, and to get there it must pass through a few functions not authored by us. Will the code make it, retaining its meaning ? That depends on whether we accidentally used any words that happen to be the same name as locals of the functions involved. If we did use such a word, then it would be rebound to a function's context and change its meaning. That's not typically how functions are supposed to be used. Functions are supposed to hide their implementation details from the outside world, and have no side-effects. |
Geomol 16-Oct-2008 [11122x3] | I used to think, blocks of words didn't have any meaning, until they were e.g. evaluated. In one context, the words mean one thing, in another something else. When I program, I don't think alot about this, I just work with REBOL. Now I some cases, where I might not expect the output, I'm getting. Example: >> a: 1 == 1 >> f: func [a code] [do code] >> f 2 [print a] 1 Before doing this, I would have guessed, 2 was printed. Funny I haven't had such a problem, that I can remember. |
Now I *see* cases ... | |
Remembering some discussion about block pre-evaluation or something. So the interior of blocks are being giving meaning, when they are born. And you can't put anything in a block: >> blk: [a 7-] ** Syntax Error: Invalid date -- 7- | |
amacleod 16-Oct-2008 [11125] | I'm using tretbase to store formatted text but tretbase strips carriage returns. I've removed the trim/lines function from tretbase but teh retrieve functions and search functions etc. expect the data to be on one line. Carriage returns can be in the data file as long as they are on one line. |
Geomol 16-Oct-2008 [11126] | Maybe newlines are not stored as one character, but two? Like: >> str: {^^/} == "^^/" >> length? str == 2 |
Anton 16-Oct-2008 [11127] | Geomol, you're right, actually, the real meaning of a word is only ever actualised when it is evaluated. But you can think of a word's binding as its potential meaning. (Above, I wrote as if binding and meaning are the same, whereas they are not quite; they are close, but binding is one step back from meaning.) |
Gregg 16-Oct-2008 [11128] | Alan, have you tried this ('s being your string): replace/all s "^/" "^^/" |
amacleod 16-Oct-2008 [11129] | s: {a { ^-b { ^-^-c} == {a ^-b ^-^-c} replace/all s "^/" "^^/" == {a^^/^-b^^/^-^-c} >> print s a^/ b^/ c Not what I want. |
Anton 16-Oct-2008 [11130] | s2: copy s parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (change/part p "^^-" 1) skip | skip]] |
Gregg 16-Oct-2008 [11131] | Because of tabs? Just do the same replace for them. |
amacleod 16-Oct-2008 [11132] | THat was my next strp. I thought I was missing some simple conversion. |
Anton 16-Oct-2008 [11133] | That's simpler to write, but two passes. The parse I show above is more complex to write, but one pass. |
amacleod 16-Oct-2008 [11134x2] | s2: copy a parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (chang e/part p "^^-" 1) skip | skip]] == true >> s2 == {a^^/^^-b^^/^^-c} >> print s2 a^/^-b^/^-c Anton, It looks like what I want but if aI print it the newlines are not reconized??? |
But if I do it manually: >> z: {a^/^-b^/^-^-c} == {a ^-b ^-^-c} >> probe z {a ^-b ^-^-c} == {a ^-b ^-^-c} I do not get it. Are there hidden characters? | |
Gregg 16-Oct-2008 [11136] | By adding the secon ^, it escapes the ^ that marks the newline, so it is no longer a newline. When you write the string out, then it will write out as "a^/^-b^/^-c" which will convert to newlines again when loaded. If you're writing out and loading strings, you may have to convert the data back yourself when you load it, because REBOL won't parse into it to do so. e.g., if you mold an object spec to be on a single line like that, REBOL will convert them on load, but if you just read a file as a string, it won't. |
Anton 16-Oct-2008 [11137x4] | The confusing thing is, rebol molds short strings and longer strings differently. In short strings, the newlines are molded as ^^/ , but in longer strings (like yours above) the newlines are "evaluated" (moving the cursor to next line). |
Check it out: >> "a^/b" == "a^/b" >> "a^/^-b" == "a^/^-b" >> "a^/^-b^/" == "a^/^-b^/" >> "a^/^-b^/^-^-c" == {a ^-b ^-^-c} | |
boom! That last line is long enough that the newlines are "evaluated". | |
(It's more complicated than just string length, actually. Exact algorithm unknown.) | |
amacleod 16-Oct-2008 [11141] | Greg, I tried wrote it out ot a file and loaded it but it still does not print properly Is there a work around? |
Anton 16-Oct-2008 [11142x3] | amacleod, I think Greg and mine solution both work. They produce a string molded so that the two control characters (newline and tab) are escaped. You just need to ... ahh... here's where I was going to say "just LOAD it." but I get an error message. >> load "^^/" ** Syntax Error: Invalid path -- ^/ ** Near: (line 1) ^/ So maybe do this instead: s: "^/" ; <-- input string s: "^^/" ; <--- specially "molded" string as produced by PARSE or REPLACE above. load rejoin ["{" s "}"] ; <-- specially "loaded" string the result of which should be the same as the input. |
The longer example: | |
>> s: "a^/^-b^/^-^-c" == {a ^-b ^-^-c} >> s2: copy s parse/all s2 [some [p: "^/" (change/part p "^^/" 1) skip | "^-" (change/part p "^^-" 1) skip | skip]] == true >> s3: load rejoin ["{" s "}"] == {a ^-b ^-^-c} >> s = s3 == true | |
amacleod 16-Oct-2008 [11145] | Did you mean: s3: load rejoin ["{" s2"}"] ? with s2 in the rejoin and not s ? That seems to work and produce what I'm tring to get... A little awkward but only two lines for what I want... Thanks again, Anton. I can use this in the short time but I may need to just use SQLite or my own solution for storage as Paul is no longer developing Tretbase... |
Geomol 16-Oct-2008 [11146] | amacleod, can you use NicomDB? http://www.fys.ku.dk/~niclasen/nicomdb/index.html NicomDB is the result of an education, I took some years ago. More info: http://www.fys.ku.dk/~niclasen/nicomdb/thesis.pdf There's also a group about it here in the REBOL3 world. See group !NicomDB |
Anton 17-Oct-2008 [11147] | amacleod, ah yes, small typo there. |
Chris 17-Oct-2008 [11148x2] | On 'bind, I use 'with to make some bind situations more readable: other-context: context [ print: [statement][probe head reverse copy statement] ] with other-context [print "Text"] |
with: func [object [any-word! object! port!] block [any-block!] /only][ block: bind block object either only [block] :block ] | |
amacleod 17-Oct-2008 [11150x3] | I was looking into sqlite but reluctantly... |
Idid a quick glance through your paper and it had a lot of good iseas that might fit my needs. I'm going to play around with it. Are you still developing it? | |
iseas = ideas | |
Geomol 18-Oct-2008 [11153] | amacleod, I use NicomDB myself in different projects and is developing it further, when needs arise. |
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 | |
older newer | first last |