From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Zelphir Kaltstahl Newsgroups: gmane.lisp.guile.user Subject: Re: Contracts macro example Date: Sun, 24 Jul 2022 01:21:55 +0000 Message-ID: <4e89ed41-dcbe-a7f5-f4b3-314e325016a5@posteo.de> References: <40733751-fe8e-1e01-4a41-23b83a0c6e35@telenet.be> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="25870"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Guile User To: Maxime Devos Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Sun Jul 24 03:23:06 2022 Return-path: Envelope-to: guile-user@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 1oFQKn-0006Zj-W1 for guile-user@m.gmane-mx.org; Sun, 24 Jul 2022 03:23:05 +0200 Original-Received: from localhost ([::1]:55836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oFQKm-000753-LF for guile-user@m.gmane-mx.org; Sat, 23 Jul 2022 21:23:04 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:44836) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oFQJm-0005pj-Hv for guile-user@gnu.org; Sat, 23 Jul 2022 21:22:02 -0400 Original-Received: from mout01.posteo.de ([185.67.36.65]:37989) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oFQJj-0004lc-Py for guile-user@gnu.org; Sat, 23 Jul 2022 21:22:02 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 8EBC0240026 for ; Sun, 24 Jul 2022 03:21:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017; t=1658625716; bh=oK/8Gs5/STp+gmAGVbew8jRME2XlJEyZreyGTGBDklY=; h=Date:Subject:To:Cc:From:From; b=FDwmGLJC0N/sjfa/kHBpvo6489oq536VIJgcimFZ/e7+zOD0umWg1+IZCepHt5haV jkvCNqly/a8pu5X3srMi+QpZcfJSg5RGfnwyvjuAE544pa4Qi2Hmb+MjuPkwU1p6cU ut2glm3Ei8a9Z92ooui6ChcaSxYfiHImxAN/F4nF9t/x8aLgFXXq5w9Cq/Q3xDlzaY B1PXdLZ7qwnOKh/hIOtH/qcfKt8Og6YNsEXR9hj0uEG1a2HpIduY4HDWtbR153QGAC gD+S9JEsTApH2KMWV9/yqzEn2THPeaWuvWn9R/w2A8nZe0n+hmcEkwZ6OBPG4MI9Ar Bm6vziBC8/4eA== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Lr54M5C1jz6tmF; Sun, 24 Jul 2022 03:21:55 +0200 (CEST) Content-Language: en-US In-Reply-To: <40733751-fe8e-1e01-4a41-23b83a0c6e35@telenet.be> Received-SPF: pass client-ip=185.67.36.65; envelope-from=zelphirkaltstahl@posteo.de; helo=mout01.posteo.de X-Spam_score_int: -43 X-Spam_score: -4.4 X-Spam_bar: ---- X-Spam_report: (-4.4 / 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, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.io gmane.lisp.guile.user:18450 Archived-At: Hello Maxime! I needed some time to implement the things you explained/mentioned, but I think I've got it now: https://notabug.org/ZelphirKaltstahl/guile-examples/src/87304cc573086b5ef60c1d3aad25d4431fd5bca8/macros/contract.scm There is still one issue though: The placeholder of the ensure clauses is assumed to be at the top level. So I will have to rewrite the macro, which looks at the clauses and replaces the placeholder with the result of the function, so that it can replace the placeholder in an arbitrarily nested structure. Maybe it will be easy, maybe it will be difficult. Thanks for all your ideas! I don't understand the following thing or how it works yet: ~~~~ (define-syntax require (identifier-syntax (syntax-error "'require' can only be used as part of a contract construct"))) ~~~~ Can you explain how it works? Best regards, Zelphir On 7/20/22 10:55, Maxime Devos wrote: > > On 20-07-2022 10:39, Zelphir Kaltstahl wrote: > >>> It would also be nice to define a global 'require' and 'ensure' and >>> '' somewhere (e.g.: (define-syntax require (identifier-syntax >>> (syntax-error "'require' can only be used as part of a contract >>> construct")))), that way, require / ensure / can be renamed during >>> importing, so all contract things could be prefixed with, say, >>> contract:. >> >> I thought about implementing for the insertion location of the result in >> a predicate, but initially wanted to keep it simple and get a simple version >> to work. I think I have seen this for pipelining in an SRFI before … *checks* >> … Maybe in https://srfi.schemers.org/srfi-197/srfi-197.html, or >> https://srfi.schemers.org/srfi-26/srfi-26.html, or maybe in some other >> repository. >> >> Now that the basic version works, I can try to introduce the placeholder. >> >> The idea is to define these globally in the module, so that they can be >> exported separately, so that they can be renamed upon import, correct? > Yes. >> >> How could a macro check, whether it is used inside something else? If the >> pattern matching only looks at the form of the macro itself, how can I get >> the "context", in which it was used and check, whether that is inside a >> `define-with-contract`? I think I have not yet unlocked that knowledge yet : ) > > That's one way to implement things (syntax-parameterize sounds useful here), > but that sounds way more complicated than needs to be.  All you need to do is: > > * keep the original code > * Add: > (define "consider define-syntax+identifier-syntax+syntax-error for > better error messages but this will do for now) > * Export (at least, once your code is turned into a module, if the users > of define-with-contract are in the same module as define-with-contract > then exporting isn't required though harmless) > * Likewise for 'require' and 'ensure' > > By doing that, syntax-rules knows that its '', 'require' and 'ensure' is > not just the symbol '' 'require' and 'ensure', but the _identifier_ (which > keeps being the same identifier after renaming) '', 'require' and 'ensure'. > > (Note that as a consequence,  if you do that, (let ((require 0)) > (define-with-contract foo (require) (ensure) (lambda _ 0))) will be a syntax > error, because the 'require' in define-with-contract now refers to the > variable 'require' from the let, not the identifier from your RnRS module). > > That's all you need to do (untested)! > > > Greetings, > Maxime > -- repositories:https://notabug.org/ZelphirKaltstahl