To answer my own question, it appears doable with a very simply macro, then:
(define (bar x) (format #t "Called bar with ~A\n" x) (+ x 1)) (define (memoize FUNC) " memoize a function FUNC which takes a single int as argument " (define cache (make-hash-table)) (define (int-hash INT SZ) (modulo INT SZ)) (define (int-assoc INT ILIST) (find (lambda (pr) (equal? INT (car pr))) ILIST)) (lambda (ITEM) (define val (hashx-ref int-hash int-assoc cache ITEM)) (if val val (let ((fv (FUNC ITEM))) (hashx-set! int-hash int-assoc cache ITEM fv) fv))) ) (define bar-memo (memoize bar)) (define-syntax foo (syntax-rules () ((foo exp) (if (symbol? (quote exp)) (begin (display "its a symb\n") (bar exp)) (begin (display "no its not\n") (bar-memo exp)))))) scheme@(guile-user)> (define x 66) scheme@(guile-user)> (foo x) its a symb Called bar with 66 $1 = 67 scheme@(guile-user)> (foo 42) no its not Called bar with 42 $2 = 43 scheme@(guile-user)> (foo 42) no its not $3 = 43 scheme@(guile-user)> (foo 42) no its not $4 = 43 scheme@(guile-user)> (foo 42) no its not $5 = 43 scheme@(guile-user)> (foo x) its a symb Called bar with 66 $6 = 67 scheme@(guile-user)> (foo 68) no its not Called bar with 68 $7 = 69 scheme@(guile-user)> (foo 68) no its not $8 = 69 So that works -- I can now memoize all constants, can pass all variables on to the c++ function. Now if I could just memoize-in-place, without the hash table ... --linas On Sat, Jan 11, 2020 at 12:52 PM Linas Vepstas <linasveps...@gmail.com> wrote: > Or, thinking aloud a bit: boxes and symbols.... > > So, for example, if I was able to tell apart calls (f 42) from calls (f x) > where x is a "symbol" (or "variable", *see below*) referencing an integer, > then, for the former case, I could create a new symbol (in guile) and > attach it to a box, fill that box with whatever (f 42) would have returned. > Thence-forward, any call site in the guile code that had (f 42) in it would > get replaced by the symbol (or the unboxed value)... > > At the moment, I don't know how to tell apart 42, the literal number, from > x, a symbol that references a number. (Somehow, I can't make symbol? work > ...) I also don't know how to "edit" the call site (the cell, the box?) > that has (f 42) as the call-target, and replace it by a constant (or a > boxed constant). > > But my naive thinking fails: > (define x 0) > (symbol? x) => #f > (variable? x) => #f > > So I guess that x is not a symbol, from the guile point of view!? This is > .. confusing. What is x, then, if not a symbol? > > (define (foo x) (format #t "its ~A ~A\n" (symbol? x) (variable? x)) (+ x > 1)) > (foo 42) > its #f #f > (define y 66) > (foo y) > its #f #f > > How can I tell apart "42" from "y" ? > > -- Linas > > > > On Sat, Jan 11, 2020 at 12:11 PM Linas Vepstas <linasveps...@gmail.com> > wrote: > >> Hmm Thanks. Perhaps I should have been more clear. I'm talking about a >> handful of values that behave like constants, and NOT about memoization. >> >> So here's a bit more detail. The only thing the C++ code is doing is >> stuffing the values into a giant hash table... in C++. So its already very >> fast. The return value is a pointer into that hash table. Replicating that >> hash table a second time, in guile is ... well ... it has tens/hundreds of >> millions of entries, it would blow out RAM. (And the other functions, >> those that are actually CPU-intensive, already got the Grand Wazoo >> treatment for memization; some in guile, some in C++) >> >> For this particular issue, I'm thinking I need to understand macros, >> somehow. The point being that there is just a tiny handful of values -- >> some dozens, maybe hundreds, that some human has written into the code, and >> are being treated as if they were literal constants (because, in the C++ >> code, they *are* constants -- they're really just fixed entries in a symbol >> table) and so I want to automatically replace these by the actual constant >> value (the location in the c++ table). To recap: a macro that would >> convert >> >> (define (foo x) (g (f 42) (f x) (f 43)) >> >> into >> >> (define c42 (f 42)) >> (define c43 (f 43)) >> (define (foo x) (g c42 (f x) c43)) >> >> so that guild can treat c42 and c43 as constants (boxes, I guess). >> >> -- Linas >> >> >> On Sat, Jan 11, 2020 at 8:39 AM Matt Wette <matt.we...@gmail.com> wrote: >> >>> On 1/10/20 2:36 PM, Linas Vepstas wrote: >>> > So, I've got lots of C code wrapped up in guile, and I'd like to >>> declare >>> > many of these functions to be pure functions, side-effect-free, thus >>> > hopefully garnering some optimizations. Is this possible? How would I >>> do >>> > it? A cursory google-search reveals no clues. >>> > >>> > To recap, I've got functions f and g that call into c++, but are pure >>> (i.e. >>> > always return the same value for the same arguments). I've got >>> > user-written code that looks like this: >>> > >>> > (define (foo x) >>> > (g (f 42) (f x) (f 43)) >>> > >>> > and from what I can tell, `f` is getting called three times whenever >>> the >>> > user calls `foo`. I could tell the user to re-write their code to >>> cache, >>> > manually: viz: >>> > >>> > (define c42 (f 42)) >>> > (define c43 (f 43)) >>> > (define (foo x) (g c42 (f x) c43)) >>> > >>> > but asking the users to do this is .. cumbersome. And barely worth >>> it: `f` >>> > takes under maybe 10 microseconds to run; so most simple-minded caching >>> > stunts don't pay off. But since `foo` is called millions/billions of >>> times, >>> > I'm motivated to find something spiffy. >>> > >>> > Ideas? suggestions? >>> > >>> > -- Linas >>> >>> read this: http://community.schemewiki.org/?memoization >>> and look at https://docs.racket-lang.org/memoize/index.html >>> >>> >>> >>> >> >> -- >> cassette tapes - analog TV - film cameras - you >> > > > -- > cassette tapes - analog TV - film cameras - you > -- cassette tapes - analog TV - film cameras - you