unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Kjetil Matheussen <k.s.matheussen@gmail.com>
To: guile-user@gnu.org
Subject: Re: guile studio
Date: Sat, 19 Jun 2021 14:13:57 +0200	[thread overview]
Message-ID: <CAC6niE+R+hYFzF0z1QAMZjJHta7=AC30RDyjL_Hvp4mBP3-1KA@mail.gmail.com> (raw)
In-Reply-To: <mailman.533.1624102324.10239.guile-user@gnu.org>

> From: jerry <jdinardo@nycap.rr.com>
>
> I am fairly new to guile and scheme. People tell me that I should use a
> functional style.
>
> I have 3 solutions for project euler problem #1. The first is
> functional, the second is imperative and the third is written in "Little
> Schemer" style.
>
> I was hoping other guile users would comment on preferences or the
> "correct way". Sorry in advance for any wrapping problems that may occur.
>
> #!/usr/local/bin/guile  -s
> !#
> (use-modules (srfi srfi-1) (jpd stdio)) ;; for folds
> (define N 1000)
>
> (define ans
>    (fold + 0
>      (filter
>        (lambda (x) (or (= 0 (modulo x 3)) (= 0 (modulo x 5))))
>        (iota N))))
> (print ans)
>

For minor calculations, I would say this is fine. It's not hard to
understand what this function does. However, the more complicated a
function is, the harder this style will be to read, compared to a
recursive style (example 3). So in general I would recommend never to
use fold, but that's probably somewhat a matter of taste. Personally I
never use fold.


> (define ans 0)
> (for i N
>    (if (or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (set! ans (+ ans i))))
> (print ans)
>

Same here. For minor calculations, this is fine. In fact, this way is
probably much easier to read than the first example. However, if you
start using 'set!' on more than one variable, things can get very
messy. Regarding performance, this might be both faster or slower
depending on the scheme implementation.


> (define ans
>    (let loop ((i 1) (ans 0))
>      (cond
>        ((>= i N) ans)
>        ((or (= 0 (modulo i 3)) (= 0 (modulo i 5))) (loop (1+ i) (+ ans i)))
>        (else (loop (1+ i) ans)) )))
>

Please note that this way is also functional. This way is also more
efficient than example #1 since the program can do tail call
optimization and doesn't have to allocate lists. In addition, if you
had formatted this version properly I would have consider this version
to be easier to read than example #1.

Also note that if N is not too big (so that tail call optimization
doesn't matter), the following version would be even simpler:

(define ans
  (let loop ((i 1))
    (cond ((>= i N)
           0)
          ((or (= 0 (modulo i 3))
               (= 0 (modulo i 5)))
           (+ i
              (loop (1+ i))))
          (else
           (loop (1+ i))))))

Training yourself to read and write functions this way is probably a
good exercise. After a while you are able to easily make very advanced
functions by using recursive functions. Also note that using less
number of lines in a function does not make the function easier to
read.



       reply	other threads:[~2021-06-19 12:13 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <mailman.533.1624102324.10239.guile-user@gnu.org>
2021-06-19 12:13 ` Kjetil Matheussen [this message]
2021-05-27 11:53 guile studio Adriano Peluso
2021-05-27 11:57 ` Adriano Peluso
2021-05-29 19:45 ` Ricardo Wurmus
2021-05-29 20:23   ` Ricardo Wurmus
2021-05-30  6:04     ` Adriano Peluso
2021-05-30 16:56       ` Adriano Peluso
2021-05-31  9:45         ` Ricardo Wurmus
2021-06-02  9:10           ` Adriano Peluso
2021-06-02 10:40             ` Ricardo Wurmus
2021-06-04 11:50               ` Adriano Peluso
2021-06-04 11:55                 ` Ricardo Wurmus

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='CAC6niE+R+hYFzF0z1QAMZjJHta7=AC30RDyjL_Hvp4mBP3-1KA@mail.gmail.com' \
    --to=k.s.matheussen@gmail.com \
    --cc=guile-user@gnu.org \
    --cc=k.s.matheussen@notam02.no \
    /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).