unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Ken Raeburn <raeburn@raeburn.org>
To: Michael Lucy <MichaelGLucy@Gmail.com>
Cc: guile-devel@gnu.org
Subject: Re: expression
Date: Thu, 24 Jun 2010 02:55:59 -0400	[thread overview]
Message-ID: <867048CD-FB59-4D61-A944-03E4BE4D2960@raeburn.org> (raw)
In-Reply-To: <AANLkTimRTEQhq1umxlzDizFxkgrSXyRtqj2zi34_iqFk@mail.gmail.com>

On Jun 23, 2010, at 17:09, Michael Lucy wrote:
> Is there any scheme expression that will just get ignored when the
> scheme code is compiled?
> 
> I'm generating some code with a function like:
> 
> (define (gen-update-ab updatea updateb)
>  `(begin
>     ,(if updatea `(set! a (+ a 1)) `(donothing))
>     ,(if updateb `(set! b (+ b 1)) `(donothing))))
> 
> And ideally I could replace the donothing function with something that
> will get discarded during compilation.

A simple constant like #f or '() or 42 shouldn't cause any evaluation to happen, unless it's the last expression and thus the value to be returned (in which case you'd just be returning a simple constant).

I don't know if there's a canonical efficient way to generate it, but it looks like "(if #f #f)" will be optimized by the current compiler into just pushing the magic "undefined value" onto the stack.  Getting rid of the push altogether *IF* the result of the expression is unused is up to the optimizer; you shouldn't be jumping through hoops in the code you generate to make that happen.  But it appears that it does happen at least in simple cases:

scheme@(guile-user)> ,c (begin (if #f #f) (if #f #f) 42)
Disassembly of #<objcode 101678308>:

   0    (assert-nargs-ee/locals 0)      
   2    (make-int8 42)                  ;; 42
   4    (return)                        

Hmm... here's another way, though I've no idea if RnRS lets you not have any expressions in here:

scheme@(guile-user)> ,c (begin)                            
Disassembly of #<objcode 10163f848>:

   0    (assert-nargs-ee/locals 0)      
   2    (void)                          
   3    (return)              

scheme@(guile-user)> ,c (begin (begin) (begin) 42)
Disassembly of #<objcode 1016782a8>:

   0    (assert-nargs-ee/locals 0)      
   2    (make-int8 42)                  ;; 42
   4    (return)                        


> There are alternatives, but they're pretty ugly (significantly moreso
> in my actual code than they look below):

Depends how you define ugliness. :-)

Your approach expands each possible update into one S-expression.  So you need *something* there for each one, even if it's just a constant, or an empty "begin".

The alternative, I think, is rearranging your code so that no expression gets added to the list when there's nothing to do; one way to do that, off the top of my head, would be to generate a possibly-empty list of expressions rather than exactly one for each possible update, and then merge the lists together.  Or start with an empty list, and tack S-expressions on the front for updates that are needed, then add the "begin" and return the result.

But in terms of the generated byte code, the constants should just go away if they're not actually used, and nested "begin" lists should get flattened, so I don't think it should matter much either way.

If you want the macro expansion to be human-readable for debugging purposes, you could also consider putting in some kind of no-op annotation that shouldn't generate code, for example a let loop with a meaningful label name and no useful body, or wrapping code that actually has effects but doesn't use the label:

scheme@(guile-user)> ,c (begin (let no-update-needed-for-a () #f) 42)
Disassembly of #<objcode 1030dc468>:

   0    (assert-nargs-ee/locals 0)      
   2    (br :L171)                      ;; -> 10
   6    (br :L172)                      ;; -> 14
  10    (br :L173)                      ;; -> 6
  14    (make-int8 42)                  ;; 42
  16    (return)                        

Ehh... okay, maybe there's a little work to be done for that one. :-)

Ken


  parent reply	other threads:[~2010-06-24  6:55 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-23 21:09 expression Michael Lucy
2010-06-23 23:14 ` expression No Itisnt
2010-06-23 23:23   ` expression Michael Lucy
2010-06-24 13:01     ` expression Andy Wingo
2010-06-24  6:55 ` Ken Raeburn [this message]
2010-06-24  7:27   ` expression Thien-Thi Nguyen
2010-06-24  7:52   ` expression Michael Lucy
2010-06-24 13:05     ` expression Andy Wingo
2010-06-24 13:03   ` expression Andy Wingo
2010-06-24 14:40     ` expression Ken Raeburn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=867048CD-FB59-4D61-A944-03E4BE4D2960@raeburn.org \
    --to=raeburn@raeburn.org \
    --cc=MichaelGLucy@Gmail.com \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).