From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Blake Shaw Newsgroups: gmane.lisp.guile.devel Subject: Re: [PATCH v3] docs/match: pattern matcher example makeover Date: Fri, 03 Feb 2023 21:14:40 +0700 Message-ID: <7z7cwylqja.fsf@reproduciblemedia.com> References: <20230201130930.6624-1-blake@reproduciblemedia.com> <9725d8d9-faf2-3306-94ae-209086aa5a82@telenet.be> <20230202144720.306d1bb3@aicha> <87ilgix3sf.fsf@jpoiret.xyz> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="22852"; mail-complaints-to="usenet@ciao.gmane.io" Cc: David Pirotte , Maxime Devos , guile-devel@gnu.org To: Josselin Poiret Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Fri Feb 03 16:27:08 2023 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 1pNxy0-0005hy-8M for guile-devel@m.gmane-mx.org; Fri, 03 Feb 2023 16:27:08 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pNxww-0000W5-C1; Fri, 03 Feb 2023 10:26:02 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNxwu-0000T4-Rr for guile-devel@gnu.org; Fri, 03 Feb 2023 10:26:01 -0500 Original-Received: from out-47.mta1.migadu.com ([95.215.58.47]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pNxws-0005yR-6B for guile-devel@gnu.org; Fri, 03 Feb 2023 10:26:00 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=reproduciblemedia.com; s=key1; t=1675437955; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Yf0cPI3iOWItJRoymDkoK85hiWlOoRS0brVXIfs5fdE=; b=I6uMBQ4szmJYFkokaVasnSaDKMu8BKXn66ag32wt1+42Gie5hFC1isZOqmeXvk0EF+gFgU l0pJDOqOlxUkzq0VFymj8w4wlhxuclPrYWUt9fQJNytoAHEBC9EvzizHuia3pVvKcbw/tF G2TpAlt4P5TL4vmdrn1ntEWfgHrCjDo= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. In-reply-to: <87ilgix3sf.fsf@jpoiret.xyz> X-Migadu-Flow: FLOW_OUT Received-SPF: pass client-ip=95.215.58.47; envelope-from=blake@reproduciblemedia.com; helo=out-47.mta1.migadu.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.29 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-bounces+guile-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.devel:21680 Archived-At: Josselin Poiret writes: > Hi Blake and David, > > We were talking about this very node of the documentation yesterday with > Ludovic and zimoun, so here are my two cents. Rewriting this > introduction is a very good idea, the current one is pretty hard to get > into for novices. > > David Pirotte writes: > >> Not at all - and quite annoying. imo. >> So i'd 'vote' not to use them anywhere in the guile reference manual > > I agree that it's not "idiomatic Guile" so should probably be left out. To avoid bikeshedding, I've reverted back to not use brackets. > > Regarding the examples, I think the first one is nice but the next one > is too involved, using a named let which a lot of users might not know. > I'd suggest demonstrating each feature without any extra prerequisite, > to make it as accessible as possible. > I agree that it escalates quickly. I was hoping to juxtapose the obvious with whats more involved in hopes of hitting a "sweet spot" where the total novice can go through the examples one-by-one and still comprehend them, while an experienced functional programmer without Scheme/Guile experience can jump straight in, review a few examples, catch the drift and keep working on what they are working on, without much reading. I wanted to go straight from an arbitrary example to one with recursion in order to show how to think "heads/tails" recursively with a Scheme matcher, because I personally found it initially intimidating to start doing recursive pattern matching in Scheme, and found few examples that do so in a highly simplified form, making it confusing to translate knowlege from other functional languages. >From my POV, named let seems like a pretty standard feature of Scheme, and its used throughout the docs (perhaps that isn't a good thing). What if I followed it with an equivalent conditional version, and used the more explicit "recur" or "lp" or "loop" as the let's name? smth like: ... =E2=89=A3 (let recur ((ns '(one two three four nine)) (total 0))=20 (if (equal? 1 (length ns)) (+ total (english-base-ten->number (car ns))) (recur (cdr ns) (+ total (english-base-ten->number (car ns)))))) > The third example, introducing the ellipsis, uses 2 of them directly, > with one nested! It also doesn't explain what the pattern variables are > bound to when an ellipsis is involved. just before the third example we have: -- `Patterns can be composed and nested. For instance, @code{...} (ellipsis) means that the previous pattern may be matched zero or more times in a list:`=20 -- How would you improve on this? Also it does explain what the pattern variables are bound to, but as the result rather than in writing, which I think makes for more digestible "reference" material. > Also, the example data you're > matching on looks too intimidating, which could scare novice readers. I think this one may look complicated from afar, but I added it to [V2] because it explicates something that can't be demonstrated from simpler data and I think is often missed: that ellipsis allow pattern variables to bind every for every instance of a pattern. I chose to show this immediately, followed by simpler examples, so that the reader is exposed this idea upfront. take a simpler example: (match '(a b (1 2 3 )) ((heads ... (tails ...)) (format #t "heads: ~a ~%tails: ~a ~%" heads tails))) =E2=87=92 heads: (a b)=20 tails: (1 2 3)=20 Psychologically, it is easy for the reader to not pickup on the fact that ellipsis allow you to match over nested patterns. This may cause readers to resort to using match with map when its unneccessary. The below contains two lists, (a.n b.n ((1.n 2.n 3.n) x.n y.n z.n)), where the the letters and numbers follow an obvious order, and the results show the effect of nesting patterns. (match '((a.0 b.0 c.0 ((1.0 2.0 3.0) x.0 y.0 z.0))=20 (a.1 b.1 c.1 ((1.1 2.1 3.1) x.1 y.1 z.1))) (((heads ... ((tails ...) . rest)) ...)=20 (begin=20 (format #t "heads: ~a ~%" heads) (format #t "tails: ~a ~%" tails) (format #t "rest: ~a ~%" rest)))) =E2=87=92 heads: ((a.0 b.0 c.0) (a.1 b.1 c.1))=20 tails: ((1.0 2.0 3.0) (1.1 2.1 3.1))=20 rest: ((x.0 y.0 z.0) (x.1 y.1 z.1))=20 I imagine the element names could be improved, and perhaps the data structure simplified while preserving the lesson that it contains, but I can't think of how that would be done, but I'm open to suggestions. But overall, I think showing nested patterns first off, followed by simpler examples that ellucidate previous ones, is preferable so as to cater both to the "reference" user as well as the total beginner.