unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: "Dr. Arne Babenhauserheide" <arne_bab@web.de>
To: "Jérémy Korwin-Zmijowski" <jeremy@korwin-zmijowski.fr>
Cc: guile-user@gnu.org
Subject: Re: How to gradually write a procedure using Guile?
Date: Fri, 03 May 2024 13:49:35 +0200	[thread overview]
Message-ID: <87h6ffyv1s.fsf@web.de> (raw)
In-Reply-To: <b7f83394-5546-42df-80a2-d2456bbde09f@korwin-zmijowski.fr> ("Jérémy Korwin-Zmijowski"'s message of "Fri, 3 May 2024 10:45:11 +0200")

[-- Attachment #1: Type: text/plain, Size: 4238 bytes --]

Hi Thomas,


I usually work by redefining the whole procedure and running it.


Typically I start with the minimal procedure

(define (hello) #f)


Then — for nicely testable procedures — I add a doctest and get it to
run:

(define (hello)
  "Say hello."
  #((tests
    ('answers
      (test-equal "Hello" (hello)))))
  "Hello")

Then I run the tests from Emacs:

;; eval in emacs: (progn (defun test-this-file () (interactive) (save-current-buffer) (async-shell-command "./hello.scm --test")) (local-set-key (kbd "<f9>") 'test-this-file))

(this relies on https://hg.sr.ht/~arnebab/wisp/browse/examples/doctests.scm)


For a game I work on with my kids, I made the module non-declarative,
so I could replace all bindings at runtime:

(define-module (hello)
  #:export (hello)
  #:declarative? #f)

Then I could start the kooperative repl server:

(import (system repl coop-server))
(define (update dt
   (poll-coop-repl-server repl)))

This relies on Chickadee. See https://notabug.org/ZelphirKaltstahl/guile-chickadee-examples/src/master/example-03-live-coding-repl/main.scm#L15

Then I could open that server, in the repl use ,m (hello) to enter the
module, and replace the procedure at runtime to see the effect.

I replace it by simply pasting the procedure code into the REPL.
(after ,m (hello))


Best wishes,
Arne


Jérémy Korwin-Zmijowski <jeremy@korwin-zmijowski.fr> writes:

> Hi Tomas !
>
> You have to make choices in the code weather you want to leverage the
> REPL or not. That's fine. I incentivize you to try different
> approaches and see how it feels while you work. So you can make your
> choices based on actual experience.
>
> What comes to my mind right now is pretty close to what you imagined.
>
> You could keep your code as is and on a new line evaluate `(foo)`
> every time you make a relevant progress inside the `foo` definition.
> Write the first step, see if you can get the right result here, then
> go on the next step or fix your code.… This is my go to approach
> (which I follow in a TDD manner).
>
> Or you could define `x` and `y` in the REPL as you suggested it and
> then write definitions of your steps, one at a time (the original
> question remains, how to write the step interactively?). Then, when
> all the steps are working, try to integrate them in a `foo` procedure
> and see how it goes…
>
> Jérémy
>
> Le 03/05/2024 à 02:24, Tomas Volf a écrit :
>> Hello,
>>
>> I am looking for a workflow advice.  I am using Emacs with Geiser.
>>
>> I am trying to write couple of procedures that are very imperative and I am not
>> sure how to do that nicely in REPL.  For example, let us assume I have a
>> procedure of following character:
>>
>>      (define (foo)
>>        (let* ((x (bar-x))
>>               (y (bar-y x)))
>>          (step1 x)
>>          (step2 y)
>>          (step3 x y)
>>          ...))
>>
>> Now, each step can be a procedure call, of just few expressions.  Now I would
>> like to write the additional steps while utilizing REPL somehow, but I am not
>> sure what is an efficient way.
>>
>> Can I somehow run just to the `...' and get a REPL there so that I could C-x C-e
>> the steps within the let* (for x and y)?  Should I just (temporarily)
>>
>>      (define x (bar-x))
>>      (define y (bar-y x))
>>
>> in the REPL so that I can use C-x C-e on the steps?  I expect that to get messy
>> once the lets start nesting for example.
>>
>> How do you do it?  Are there any resources (blog posts, toots, videos, ...)
>> regarding guile developer's workflow?  I did read few, and I (think I) know the
>> fundamentals of Geiser and the REPL, but I am straggling a bit in this case not
>> to fall back to the "normal" way of "write a function, run it whole against a
>> test".  Since this is Scheme, and I *can* evaluate single expressions in the
>> procedure body, I would like to use that to my advantage.  Somehow.
>>
>> I realize this is a very open-ended question/email.
>>
>> Have a nice day,
>> Tomas Volf
>>
>> --
>> There are only two hard things in Computer Science:
>> cache invalidation, naming things and off-by-one errors.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 1125 bytes --]

  reply	other threads:[~2024-05-03 11:49 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-03  0:24 How to gradually write a procedure using Guile? Tomas Volf
2024-05-03  8:45 ` Jérémy Korwin-Zmijowski
2024-05-03 11:49   ` Dr. Arne Babenhauserheide [this message]
2024-05-16 18:25     ` Tomas Volf

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=87h6ffyv1s.fsf@web.de \
    --to=arne_bab@web.de \
    --cc=guile-user@gnu.org \
    --cc=jeremy@korwin-zmijowski.fr \
    /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).