Hi Brian.

----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, July 03, 2000 8:35 AM
Subject: [REBOL] Fun with literals (was Parser seems to have bug...)


> Hi Brett!
>
> While you're reassembling, think of the advantages that this
> trick can give you. This kind of assignment can be useful for
> implementing what the C world calls static local variables.
>
> You can set a word to a literal string value, then append to
> that string to create a string accumulator. This allows you
> to build a string incrementally.

Yep, can certainly vouch for that. :)

>
> You can set a word to a literal block and store values in it.
> This allows you to use a function like a Scheme closure, a
> function with values bundled in it, like OOP in reverse. This
> technique allows OOP-like programming with better control of
> your data because it is hidden inside the function. Look at
> http://www.bigfoot.com/~brian.hawley/rebol/require.r for an
> example of how this technique can make for bulletproof code.
>

Gunna need a little time with this one...

> The most fun with this technique comes when you use compose
> to create your code blocks. For example, consider this:
>
>      f: func [key] [
>          table: make hash! [a "a" b "b"] table/:key
>      ]
>
> Trivial, true, but imagine that pattern with a much larger
> hash table, or a large binary value, or a dozen charsets for
> a parse process. You can't directly represent those values
> as literals - they get recreated every time. Do that in a
> function and the function gets really slow. But do this:
>
>      f: func [key] compose [
>          table: (make hash! [a "a" b "b"]) table/:key
>      ]
>
> and the hash table is only created once, right before the
> function is created. All calls to f then reference the now
> literal hash table, making for a very fast, memory efficient
> function.

This really helps with my "mind reassembling". I won't look at my functions
the same way again...
I also didn't realise that one could use path access on the hash like that.
I'd being using SELECT before.


>
> If you can use literal hash tables in a function, you can do
> one of the coolest tricks from the functional-language world,
> memoization. When you memoize a function, it remembers the
> results of the calls to the function, so that later calls of
> that value don't have to recalculate the result. You can even
> do this from the outside with a separate function, although
> REBOL's flexible args make the general case of that rather
> tricky (I'll work on it). Here's a one-arg memoize function:
>
> memoize: func ["One-arg memoize, kinda weak :(" 'f [word!]] [
>      set f func [x /local f saved res] compose [
>          f: (get f) saved: (make hash! [])
>          either res: select saved :x [first res] [
>              res: f x
>              append saved reduce [:x reduce [res]]
>              res
>          ]
>      ]
> ]
>
> I know, it looks awkward, but this can speed up functions
> that have to go through even worse trouble to calculate
> their values in the first place. It also helps with those
> that use deep self-recursion to calculate their values, as
> REBOL's stack space is quite limited.
>

I couldn't get the memoize to work. But I can see what you are doing and
that is quite a gem.


> Fun stuff?
>
Very. Thanks very much for making those points. I'm gradually training
myself into a better understanding of Rebol rather than automatically
assuming I know what is happening based on other language experience.

Brett.

Reply via email to