unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Vladimir Zhbanov <vzhbanov@gmail.com>
To: guile-user@gnu.org
Subject: Re: Weird Guile Scheme Behaviour
Date: Fri, 13 Sep 2019 20:22:59 +0300	[thread overview]
Message-ID: <20190913172259.GA6220@newvzh.lokolhoz> (raw)
In-Reply-To: <87pnk4v8et.fsf@bulbul>


Philip,

On Fri, Sep 13, 2019 at 11:43:06AM +0200, Philip K. wrote:
> 
> Hi,
> 
> I was reading a thread on an imageboard[0] the other day, then I came
> across a most peculiar "bug", if it even is one. Since the original
> example was a bit dense (it tried to solve a problem someone else had
> posted, that's not relevant here), I tried to construct a minimal
> working example to discuss here.
> 
> Compare
> 
>     (define (reverse-iota-1 max)
>       (let ((numbers '(start)))
>         (let loop ((val 0))
>           (append! numbers
>                    (if (< max val)
>                        '()
>                        (begin
>                          (loop (1+ val))
>                          (list val)))))
>         numbers))
> 
> and
> 
>     (define (reverse-iota-2 max)
>       (let ((numbers '(start)))
>         (let loop ((val 0))
>           (append! numbers
>                    (if (< max val)
>                        '()
>                        (begin
>                          (loop (1+ val))
>                          (list val)))))
>         (cdr numbers)))
> 
> (I know, the style is horrible, but that's not the point. Also, both
> have an internal state, so you have to re-eval the function every time
> before starting the function itself.)
> 
> The only difference is in the last line. The first function returns the
> entire list (with the start symbol), and the second tries to chop it
> off.
> 
> But what happens is that (reverse-iota-1 4) evals to '(start 3 2 1 0)
> while (reverse-iota-2 4) just returns '()!
> 
> This seems weird, since my intuition, and that of the poster above, was
> that all that should change in reverse-iota-2 is that the "start" symbol
> should fall away.
> 
> It's obvious that this has something to do with the destructive
> "append!", but I'm not quite sure what leads to this unexpected result.
> Is it maybe a optimisation error? Any opinions?


Well, if i understand the issue correctly, there are two issues :-)

1) The quotation from the Guile manual:

     ‘append’ doesn’t modify the given lists, but the return may share
     structure with the final OBJ.  ‘append!’ is permitted, but not
     required, to modify the given lists to form its return.


2) 'let' itself should return the last evaluated expression
(right?). The external 'let' does just so, and the internal 'let'
is irrelevant (apart from the issue with permission to 'append!',
shown above, to modify the value of its arguments) .

So, if you would use just 'append' instead of 'append!', you would
get just the value of 'numbers' (just '(start)) in the first case,
and the value of its 'cdr' in the second case (obviously, '()
:-)).  However, since 'append!' is used instead, it is
unpredictable for me (the behaviour of 'append!' is not
standardized), if it will change the value of 'numbers' itself, so
there are two cases you've got.

Well, dunno, which conditions force the Guile optimizer to choose
one of the strategies.  Seems, i would prefer internal 'let's in
both cases are thrown out.

-- 
  Vladimir

(λ)επτόν EDA — https://github.com/lepton-eda



  parent reply	other threads:[~2019-09-13 17:22 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-13  9:43 Weird Guile Scheme Behaviour Philip K.
2019-09-13 12:43 ` Neil Jerram
2019-09-13 17:22 ` Vladimir Zhbanov [this message]
2019-10-16  6:52 ` Mark H Weaver
2019-10-16  7:48   ` Philip K.

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=20190913172259.GA6220@newvzh.lokolhoz \
    --to=vzhbanov@gmail.com \
    --cc=guile-user@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).