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: define-typed: checking values on proc entry and exit Date: Fri, 10 May 2024 22:49:45 +0000 Message-ID: <97402bb8-b4e9-44a1-9955-23e95eda6f5d@posteo.de> References: <871q6axg4s.fsf@web.de> 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="5615"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Guile User To: "Dr. Arne Babenhauserheide" Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Sat May 11 00:50:31 2024 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 1s5Z4R-0001Jt-Jb for guile-user@m.gmane-mx.org; Sat, 11 May 2024 00:50:31 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s5Z3u-0004mM-Tu; Fri, 10 May 2024 18:49:59 -0400 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 1s5Z3t-0004m9-RI for guile-user@gnu.org; Fri, 10 May 2024 18:49:57 -0400 Original-Received: from mout02.posteo.de ([185.67.36.66]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1s5Z3q-0004Rf-Bb for guile-user@gnu.org; Fri, 10 May 2024 18:49:57 -0400 Original-Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id E4A4A240101 for ; Sat, 11 May 2024 00:49:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=posteo.de; s=2017; t=1715381389; bh=Nmj9x3NT3Lqa7k49DJT+UYlQBXLlAoCUkmoMHN/hdMw=; h=Message-ID:Date:MIME-Version:Subject:To:From:Cc:Content-Type: Content-Transfer-Encoding:From; b=WDG4fQu2og5yv8ebggmGGXZjbsZ6zBLLMT9nkFz7uG25/wd9Wt3uNmxGbBs+4MSgF aW9//esN8uGCHOifm8NT0q829OZbH8S4Ta2ULaHnQTXUyScB0FTbHK1iYqk5E/M5gh cy6hAbBoiNW6hXZskPQhCKbAIOaR2DfTXfUt0kXVB+lB3byYg3oJcneiufriQ0vnaV YYqomDHiX3WrRtNgZKsioBnC7LQ3npU+MW0PLdhrZo2ttL80QjXQq5uV/6sCRg+Qc9 qiWR/gVXbdyRNLORiM++u/8VNzxLZvX9hoQM6kPQApUG6oZZb9rLvmlMLcpA3dOilB AZ6dHPS7uddxg== Original-Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4Vbkbc3w5Mz9rxD; Sat, 11 May 2024 00:49:48 +0200 (CEST) Content-Language: en-US In-Reply-To: <871q6axg4s.fsf@web.de> Received-SPF: pass client-ip=185.67.36.66; envelope-from=zelphirkaltstahl@posteo.de; helo=mout02.posteo.de X-Spam_score_int: -33 X-Spam_score: -3.4 X-Spam_bar: --- X-Spam_report: (-3.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, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URI_DOTEDU=1 autolearn=ham autolearn_force=no X-Spam_action: no action 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-bounces+guile-user=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.user:19626 Archived-At: On 10.05.24 15:47, Dr. Arne Babenhauserheide wrote: > Hi, > > in #guile on IRC¹, old talked about Typed Racket so I thought whether > that could be done with define-syntax-rule. So I created define-typed. > This is also on my website², but I wanted to share and discuss it here. > > I follow the format by [sph-sc], a Scheme to C compiler. It declares > types after the function definition like this: > > ┌──── > │ (define (hello typed-world) (string? string?) > │ typed-world) > └──── > > ┌──── > │ (define-syntax-rule (define-typed (procname args ...) (ret? types ...) body ...) > │ (begin > │ (define (procname args ...) > │ ;; define a helper pro > │ (define (helper) > │ body ...) > │ ;; use a typecheck prefix for the arguments > │ (map (λ (type? argument) > │ (unless (type? argument) > │ (error "type error ~a ~a" type? argument))) > │ (list types ...) (list args ...) ) > │ ;; get the result > │ (let ((res (helper))) > │ ;; typecheck the result > │ (unless (ret? res) > │ (error "type error: return value ~a does not match ~a" > │ res ret?)) > │ ;; return the result > │ res)) > │ ;; add procedure properties > │ (let ((helper (lambda (args ...) body ...))) > │ (set-procedure-properties! procname (procedure-properties helper)) > │ ;; preserve the name > │ (set-procedure-property! procname 'name 'procname)))) > └──── > > This supports most features of regular define like docstrings, procedure > properties, and so forth. > > ┌──── > │ (define-typed (hello typed-world) (string? string?) > │ typed-world) > │ (hello "typed") > │ ;; => "typed" > │ (hello 1337) > │ ;; => type error ~a ~a # 1337 > │ (define-typed (hello typed-world) (string? string?) > │ "typed" > │ #((props)) > │ typed-world) > │ (procedure-properties hello) > │ ;; => ((name . hello) (documentation . "typed") (props)) > └──── > > This should automate some of the guards of [Optimizing Guile Scheme], so > the compiler can optimize more (i.e. if you check for `real?') but keep > in mind that these checks are not free: only typecheck outside tight > loops. > > They provide a type boundary instead of forcing explicit static typing. > > Also you can do more advanced checks by providing your own test > procedures and validating your API more elegantly, but these then won’t > help the compiler produce faster code. > > But keep in mind that this does not actually provide static program > analysis like while-you-write type checks. It’s simply [syntactic sugar] > for a boundary through which only allowed values can pass. Thanks to > program flow analysis by the just-in-time compiler, it can make your > code faster, but that’s not guaranteed. It may be useful for your next > API definition. > > My question now: do you have an idea for a better name than > define-typed? > > > [sph-sc] > > [Optimizing Guile Scheme] > > > [syntactic sugar] > > > > ¹ https://web.libera.chat/?nick=Wisp|?#guile > ² https://www.draketo.de/software/guile-snippets#define-typed > > > Best wishes, > Arne Hello Arne, You might also be interested in my repository for function contracts using CK macros: https://codeberg.org/ZelphirKaltstahl/guile-examples/src/commit/0e231c289596cb4c445efb30168105914a8539a5/macros/contracts I hope I can check out your macro soon and hope to be able to understand it : ) Regards, Zelphir -- repositories: https://notabug.org/ZelphirKaltstahl