From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Taylan Kammer Newsgroups: gmane.lisp.guile.user Subject: Re: Pure (side-effect-free) calls into c/c++? Date: Sun, 12 Jan 2020 04:21:49 +0100 Message-ID: References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="7064"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.3.1 Cc: Guile User To: linasvepstas@gmail.com, Matt Wette Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Sun Jan 12 04:23:10 2020 Return-path: Envelope-to: guile-user@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1iqTpI-000v5p-Ie for guile-user@m.gmane-mx.org; Sun, 12 Jan 2020 04:22:08 +0100 Original-Received: from localhost ([::1]:34796 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iqTpG-00053z-Pd for guile-user@m.gmane-mx.org; Sat, 11 Jan 2020 22:22:06 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47073) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iqTp4-00053Q-Fd for guile-user@gnu.org; Sat, 11 Jan 2020 22:21:55 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iqTp2-0002mZ-Ut for guile-user@gnu.org; Sat, 11 Jan 2020 22:21:54 -0500 Original-Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]:43836) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iqTp2-0002hS-Jt for guile-user@gnu.org; Sat, 11 Jan 2020 22:21:52 -0500 Original-Received: by mail-wr1-x42c.google.com with SMTP id d16so5319896wre.10 for ; Sat, 11 Jan 2020 19:21:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=HZpAIC2v8nyvsCC0E2D3B8Azu6YBz/oue2kGQiIxVHw=; b=rbpGpyhU+nTXx74Vx9GLhBRSQF22g1lumOXC1nzJrIU+OoGnWkYpwtDXGmZnIAQtsi 4Vp58IdSJNB91RyCu/3pAvxwH0GVXL9SFZrUQuhG1RuXjra8x7AdUSCM65z/IRqeFIui zPNyddO9o2RCI/rO9DErqiag976O8D3w1QBvq2wjwapGnMT3c63in4aFKtGVlRiD0dSo 3fPZ71J7r7KQB36TMGfmxgAW0pxoelFLET69nf2reHaKZ5KOkv3R9DthHSUy5WtXNW/8 VFNuhzWuP98JGbDpN+B1e39Fj4osuOIr5hvy8cDYrvvHMxe1jWmL9lsy3S531jfT8OZA UbWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=HZpAIC2v8nyvsCC0E2D3B8Azu6YBz/oue2kGQiIxVHw=; b=JaMzqueIKSNwF+eXjONo4bgY9Jdbq1ImhJheUVOKboAwvP/fDm+gFE5BW7CDqhtl1p bE4h3iAZoSzmj6iJX/LKeThE9WmzXmqNNKUB2Loz1VzqV08oigCMTG50cl8Oo9nVAwFr CHFVj2qNqklK4azYw9QF1u+heUzbakup+JXIxaa2nRimbvs7vvu0zMljrqSm+u88BmFP RX/9GPE06dzRnyIw+cHIXva6XFJEFxsr1HLbVFl8IAxgpuNXS0tog1kQcGhfokWXKRqc LVGRpAA832gZtSbSYe3PoPIlpD9jv3UmsOV37Z9LMS3WkW10eh6uL/oNYhY1ISTgtclB HnZg== X-Gm-Message-State: APjAAAVOGrJ1ROUgGtNld2gb3Ef00gVehVx4a/HgWyiCXtuaQyYjH1vH MZW0bemwI5lJ429mEH7hHqbzGxd7 X-Google-Smtp-Source: APXvYqxoFOjRh6vw0Ni/63Z03bh71yujzGswfMg4hz2sixshOjkwmdgWQQpzWezSqwgn7M+ZssG9qg== X-Received: by 2002:adf:ea8a:: with SMTP id s10mr11161258wrm.278.1578799311144; Sat, 11 Jan 2020 19:21:51 -0800 (PST) Original-Received: from ?IPv6:2a02:908:c70:52c0:795c:7930:3d3d:e8cf? ([2a02:908:c70:52c0:795c:7930:3d3d:e8cf]) by smtp.gmail.com with ESMTPSA id 60sm9023950wrn.86.2020.01.11.19.21.50 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 11 Jan 2020 19:21:50 -0800 (PST) In-Reply-To: Content-Language: en-US X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::42c X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:16038 Archived-At: On 12.01.2020 03:12, Linas Vepstas wrote: > 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)))))) Using (quote exp) in the macro output to determine if the input was a symbol is... smart I guess! There's a problem in your approach though: the memoization and the lookup of the memoized value will happen at run-time, because your macro is merely emitting code that calls the function with the memoization cache. This also means, of course, that checking whether the argument was a symbol is useless. In your (lambda (ITEM) ...) definition, insert some (display ...) lines to print "was already memoized" or "will now be memoized" and you will see what I mean. Here's how calls to the function might then look: scheme> (define x 66) scheme> (bar-memo x) will now be memoized $1 = 67 scheme> (bar-memo x) was already memoized $2 = 67 scheme> (set! x 42) scheme> (bar-memo x) will now be memoized $3 = 43 scheme> (bar-memo x) was already memoized $4 = 43 It's important to understand that Scheme uses "pass-by-value" semantics in procedure calls. That means that a procedure doesn't know how the values it receives were computed -- whether they were constants, or variable references, or the result of another function call. Consider: (foo 42) (let ((x 42)) (foo x)) (foo (+ 21 21)) In all three cases, foo receives the same value, 42, and doesn't know how it arrived. I'm not sure if memoization is really what you want, since it's a run-time caching mechanism. It might be possible to create a sort of "compile-time memoization" but it would be quite complicated. For each constant value the macro receives, it would emit a global variable definition that will be bound to the call to the actual function at run-time, and then each call with the same constant would emit a reference to that variable. So the following: (display (f-memo 42)) (display (f-memo 66)) (display (f-memo 42)) (display (f-memo 66)) would magically emit code like: (define _x1 (f 42)) (define _x2 (f 66)) (display _x1) (display _x2) (display _x1) (display _x2) But I'm not sure how I'd write that hypothetical f-memo macro. You can't really make a macro-call deep within some code emit a top-level variable definition. All I can imagine are some pretty dirty methods that probably aren't worth the complexity. - Taylan