From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Stefan Israelsson Tampe Newsgroups: gmane.lisp.guile.devel Subject: Fwd: Announcing the first stable release of guile-for-loops Date: Fri, 24 Jan 2020 13:13:08 +0100 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000e4dfdf059ce1ae48" Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="17934"; mail-complaints-to="usenet@ciao.gmane.io" To: guile-devel Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Fri Jan 24 13:13:40 2020 Return-path: Envelope-to: guile-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1iuxqF-0004a3-Qt for guile-devel@m.gmane-mx.org; Fri, 24 Jan 2020 13:13:39 +0100 Original-Received: from localhost ([::1]:41252 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iuxqE-00048l-QJ for guile-devel@m.gmane-mx.org; Fri, 24 Jan 2020 07:13:38 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:41484) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iuxq4-00048e-Rp for guile-devel@gnu.org; Fri, 24 Jan 2020 07:13:30 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iuxpy-0003zu-L0 for guile-devel@gnu.org; Fri, 24 Jan 2020 07:13:28 -0500 Original-Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]:53088) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iuxpy-0003wv-E2 for guile-devel@gnu.org; Fri, 24 Jan 2020 07:13:22 -0500 Original-Received: by mail-wm1-x32f.google.com with SMTP id p9so1467380wmc.2 for ; Fri, 24 Jan 2020 04:13:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=XMpwX/XL7IbRd/Ch3Cjk2Dih9w3SkukK1CKzJj3WXbA=; b=GNXdIG3BfL80gdZ+K0i01f24JG1ti21RYnqo8BB2Nn9d17e/Ox4pZFhUaMCD944AEr 2MV7O30HZFPg8J8GgSufcCkwXg1Xz0TF2QRMrPR5LiQPb/V5i48SLr1qsz9njkdD5rEg xgtZVA1JjHh/gIjOCmy3ftaUphUCC1ZjoQsaFJqXWNbrXbs4BzMj6Bn6ltquOPHl/2rC Bn062LLuVjM//NGcACbKzleeQcI0GxG9qP2uLqweEI8V215/GrGEWCIMFGzuRNiWiyD3 tVDUtPgdznlaBrOkmjl8p2z/Tz2nEfPP7ym5Lvjo/Bj7VHl1lunkwOOjHU3RtC9APfJJ xDaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=XMpwX/XL7IbRd/Ch3Cjk2Dih9w3SkukK1CKzJj3WXbA=; b=T8WnnfL1p5anxBRz21u/YfUlXw6nA5ufzhd79Ieujb7FBp/AJdchVMhxZ+maLFlxXm uJldbbufM3I+NPXfPnY/yJhDI4xKbDoBLuWzapCF0i6DJCamwWVeefLP7JHs5c0H94md s62/EUzqWX26n/R4fa9rq0VSFEA8lgFot7dLvVlPc9uFPwM3rxaNkikMYMF6CA2FicZZ SuXVSUvCDG3ndg5YnosBlCEpvc6tkCaPaiZMlMnp82UGcBc2ZGcK0ak01y1FLnTc4isY m6Voq370TWA76Cn9IsqUsnqsFVJprJbiokQvGPY/ssOce+9ePMV/m99kA/2vOIYH4z25 nMzA== X-Gm-Message-State: APjAAAVI8RNlHvyYeRW3E5/3D5DaB4D7Lr/B82qDJmp6V0MdeKxA+zfz fW7rPRsTTHa/N7/Sm8A7LAFD11o738AWT0vaQMmbPg== X-Google-Smtp-Source: APXvYqx0BJhSmFN5WEp6OxnNUSDWfbtL4Loz1b5wHupCZnC1kykUYa1Lg7yxr+PMNdE37Rmx95QmUTBfSFGtixCvZOo= X-Received: by 2002:a7b:cfc2:: with SMTP id f2mr3046617wmm.44.1579867999361; Fri, 24 Jan 2020 04:13:19 -0800 (PST) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::32f X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Original-Sender: "guile-devel" Xref: news.gmane.io gmane.lisp.guile.devel:20326 Archived-At: --000000000000e4dfdf059ce1ae48 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable ---------- Forwarded message --------- From: Stefan Israelsson Tampe Date: Fri, Jan 24, 2020 at 12:42 PM Subject: Re: Announcing the first stable release of guile-for-loops To: Linus Bj=C3=B6rnstam Would be cool to have those implemented in guile, that would make my guile-syntax-parse a bit leaner Regards Stefan On Thu, Jan 23, 2020 at 3:03 PM Linus Bj=C3=B6rnstam < linus.bjornstam@veryfast.biz> wrote: > Hiya everybody! > > I have spent some time implementing efficient for loops for guile, and > they are baked and ready to go. I have worked the last weeks at > implementing generalized support for non-tail-recursive loops and am happ= y > to announce for/foldr. It is a generic right fold, with support for > delaying it's arguments as either thunks or promises. > > The syntax is more or less the same as racket's loops, and they are > generally compatible. The code generated is for almost all cases as fast = as > hand-rolled code. They are all expressed as left or right folds, and are = as > such (apart from for/list, but read about that in the documentation) free > of mutation. They are all converted to named lets. > > Some examples: > > (for/list ((a (in-range 1 6))) > (* a a)) ;; =3D> (1 4 9 16 25) > > (for*/list ((a (in-string "ab")) (b (in-range 1 3))) > (list a b)) > ;; =3D> ((#\a 1) (#\a 2) (#\b 1) (#\b 2)) > > There are many more looping constructs, among others: > for/sum, for/vector, for/or, for/and, for/first, for/last and a > side-effecting simple for. > > Here is a sieve of erathostenes: > > (define (erathostenes n) > (define vec (make-vector n #t)) > (for/list ([i (in-range 2 n)] #:when (vector-ref vec i)) > (for ([j (in-range/incr (* 2 i) n i)]) > (vector-set! vec j #f)) > i)) > > The code and documentation is available here: > https://hg.sr.ht/~bjoli/guile-for-loops > > A web-friendly documentation can be found here: > https://man.sr.ht/%7Ebjoli/for-loops-docs/for-loops.md > > The thing I had been waiting for is right fold. That allows us to write > loops like guile's map: non-tail recursive: > (for/foldr ((identity '())) ((a (in-list '(1 2 3)))) > (cons (* a a) identity)) > > becomes equivalent to: > > (let loop ((random-identifier '(1 2 3))) > (if (null? random-identifier) > '() > (let ((a (car random-identifier))) > (cons (* a a) (loop (cdr random-identifier)))))) > > Happy hacking > Linus Bj=C3=B6rnstam > > --000000000000e4dfdf059ce1ae48 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


---------- Forwarded message ---------
From: Stefan Israelsson Tampe <stefan.itampe@= gmail.com>
Date: Fri, Jan 24, 2020 at 12:42 PM
Subject:= Re: Announcing the first stable release of guile-for-loops
To: Linus Bj= =C3=B6rnstam <linus.bjor= nstam@veryfast.biz>


Would be cool = to have those implemented=C2=A0in guile, that would make my guile-syntax-pa= rse a bit leaner

Regards
Stefan
On Thu, J= an 23, 2020 at 3:03 PM Linus Bj=C3=B6rnstam <linus.bjornstam@veryfast.biz>= wrote:
Hiya eve= rybody!

I have spent some time implementing efficient for loops for guile, and they= are baked and ready to go. I have worked the last weeks at implementing ge= neralized support for non-tail-recursive loops and am happy to announce for= /foldr. It is a generic right fold, with support for delaying it's argu= ments as either thunks or promises.

The syntax is more or less the same as racket's loops, and they are gen= erally compatible. The code generated is for almost all cases as fast as ha= nd-rolled code. They are all expressed as left or right folds, and are as s= uch (apart from for/list, but read about that in the documentation) free of= mutation. They are all converted to named lets.

Some examples:

(for/list ((a (in-range 1 6)))
=C2=A0 (* a a)) ;; =3D> (1 4 9 16 25)

(for*/list ((a (in-string "ab")) (b (in-range 1 3)))
=C2=A0 (list a b))
;; =3D> ((#\a 1) (#\a 2) (#\b 1) (#\b 2))

There are many more looping constructs, among others:
for/sum, for/vector, for/or, for/and, for/first, for/last and a side-effect= ing simple for.

Here is a sieve of erathostenes:

(define (erathostenes n)
=C2=A0 (define vec (make-vector n #t))
=C2=A0 (for/list ([i (in-range 2 n)] #:when (vector-ref vec i))
=C2=A0 =C2=A0 (for ([j (in-range/incr (* 2 i) n i)])
=C2=A0 =C2=A0 =C2=A0 (vector-set! vec j #f))
=C2=A0 =C2=A0 i))

The code and documentation is available here:
https://hg.sr.ht/~bjoli/guile-for-loops

A web-friendly documentation can be found here:
https://man.sr.ht/%7Ebjoli/for-loops-docs/for-= loops.md

The thing I had been waiting for is right fold. That allows us to write loo= ps like guile's map: non-tail recursive:
(for/foldr ((identity '())) ((a (in-list '(1 2 3))))
=C2=A0 (cons (* a a) identity))

becomes equivalent to:

(let loop ((random-identifier '(1 2 3)))
=C2=A0 (if (null? random-identifier)
=C2=A0 =C2=A0 =C2=A0 '()
=C2=A0 =C2=A0 =C2=A0 (let ((a (car random-identifier)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (cons (* a a) (loop (cdr random-identifier)))))= )

Happy hacking
Linus Bj=C3=B6rnstam

--000000000000e4dfdf059ce1ae48--