From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Damien Mattei Newsgroups: gmane.lisp.guile.user Subject: Re: return macro Date: Thu, 30 Sep 2021 10:46:06 +0200 Message-ID: References: <1142492b-16bf-7181-8d93-38bfc2d3c748@gmail.com> <84359060abff196e59ae99c28dda37f8ac4b56ae.camel@riseup.net> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="14406"; mail-complaints-to="usenet@ciao.gmane.io" Cc: guile-user To: adriano Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Thu Sep 30 10:46:49 2021 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 1mVriK-0003WF-0W for guile-user@m.gmane-mx.org; Thu, 30 Sep 2021 10:46:48 +0200 Original-Received: from localhost ([::1]:34844 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mVriI-0006vm-VJ for guile-user@m.gmane-mx.org; Thu, 30 Sep 2021 04:46:46 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:53190) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mVrhv-0006uY-9d for guile-user@gnu.org; Thu, 30 Sep 2021 04:46:24 -0400 Original-Received: from mail-il1-x12d.google.com ([2607:f8b0:4864:20::12d]:43869) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mVrhs-0003WM-CP for guile-user@gnu.org; Thu, 30 Sep 2021 04:46:23 -0400 Original-Received: by mail-il1-x12d.google.com with SMTP id p1so4749682ilg.10 for ; Thu, 30 Sep 2021 01:46:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=1pacLW/MiSzzqDamvu39A1P3UbOSD8f6rF+QyWHZhbE=; b=DfWXbyXIOWhIyR9OajIu8JiVFpwLt6yA2AEC0PsCRVN7q7P06Un3J9W3Uf3sxLwpZ8 CgoeOVqZEzz3DN/d4+fR74GxyROZ5Ntg1LHRzfiZwfLbAdhmJAphMDwH7JWBPnUJouJb 9HwlZ1NBvRa7c8WndhgCko/b8xS10OXHKMF/OEV6qZU9Yd1TwBzA++VHxBVwQzPq3nRz mtijiJN/U25lzonSjfwngRnx6rmqnZf/2tdpCZS6SnAwcV+U2FctecpNGlLEiLpsKiOO wHmZunVAJJy4MMgN5i5++66D2XCO7TptvWi47Bx5Yhwss0A1zcdQcnnQKmInVj97wIID CYRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=1pacLW/MiSzzqDamvu39A1P3UbOSD8f6rF+QyWHZhbE=; b=r7scmxwQ9SAVC8at4EdZWNymHQJFI5lr5D5DS760XdVJd/41J55CrJw2rQSiBS6yQg zxP5ETRI8KYCa8vgbOWxfuJyWmVHQrgptpHiGqRXBQKUsc0K2ryKbzP9q3SdeIT2z57f O03RPttswzhcaz+Alit3PDsKEeZyC8BsF8mbknZmKMncLOUNj08lR40Hq4YUbYe8AphW YjUGHQtNCbxn46KWbJb2Y1eAX0rMZhjEhfTQnigK8xGZliSHDFfKlbvIebghfRLKcKuV LS7Zg7OreG2WUFL/M3AvZgX5ubxmrZwEdZMLu0rnyvzEO84HyioUWKTU1OclPj/Vn4k0 DvKg== X-Gm-Message-State: AOAM533alcK1tJSVqrP0gmuWXbqEYQ0x5iqJmoFVqClQdv2tDS4xE5s2 9hk4oAZUQcAKU2ar9jVc5PTTTNo5ndr4xeGKdcs= X-Google-Smtp-Source: ABdhPJymiXXJkW98B0qBZkqVfFkjzgTWwmn67f4CEOH70hvNS5ua1O2Kq3vUczxFF/RkIiXz8qwysPb1ydf/fc1f7i8= X-Received: by 2002:a05:6e02:1be2:: with SMTP id y2mr2062751ilv.297.1632991577516; Thu, 30 Sep 2021 01:46:17 -0700 (PDT) In-Reply-To: <84359060abff196e59ae99c28dda37f8ac4b56ae.camel@riseup.net> Received-SPF: pass client-ip=2607:f8b0:4864:20::12d; envelope-from=damien.mattei@gmail.com; helo=mail-il1-x12d.google.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, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Content-Filtered-By: Mailman/MimeDel 2.1.23 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 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:17788 Archived-At: i do not remember well the technic of this commented code, in this case note that it is 'break' keyword that cause the current continuation being called and escaping from the loop to the continuing code... there is no 'return' here but 'break'. Damien On Thu, Sep 30, 2021 at 5:38 AM adriano wrote: > Il giorno lun, 28/06/2021 alle 03.15 +0200, Taylan Kammer ha scritto: > > On 28.06.2021 01:10, Damien Mattei wrote: > > > hi, > > > > > > i wanted to create a macro that is used like a function definition > > > and > > > allow return using call/cc: > > > > > > (define-syntax def > > > (syntax-rules (return) > > > ((_ (name args ...) body body* ...) > > > (define name (lambda (args ...) > > > (call/cc (lambda (return) body body* ...))))) > > > ((_ name expr) (define name expr)))) > > > > > > unfortunaly i got error: > > > > > > scheme@(guile-user)> (def (test x) (cond ((= x 3) 7) ((= x 2) > > > (return 5)) > > > (else 3))) > > > ;;; :2:42: warning: possibly unbound variable `return' > > > scheme@(guile-user)> (test 2) > > > ice-9/boot-9.scm:1685:16: In procedure raise-exception: > > > Unbound variable: return > > > > > > > > > any idea? > > > > Hi Damien, > > > > This is because of the "hygiene" rule of Scheme, where the notion of > > "lexical > > scope" is taken very seriously: for an identifier to be bound, it > > must be > > visible in the lexical (textual) surroundings where it has been > > bound. > > > > So for instance, in the following example code: > > > > (def (test x) > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5)))) > > > > We can't see a binding for "return" anywhere in the text, therefore > > it cannot > > be bound. > > > > This is good "default" behavior because it makes code more flexible > > and easier > > to understand. > > > > An easy way of overcoming this issue is to let the user explicitly > > name the > > return identifier however they like: > > > > (define-syntax def > > (syntax-rules () > > ((_ (name ret arg ...) body body* ...) > > (define (name arg ...) > > (call/cc (lambda (ret) body body* ...)))))) > > > > Now you could define: > > > > (def (test return x) > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5)))) > > > > Or for instance: > > > > (def (test blubba x) > > (cond > > ((= x 3) (blubba 7)) > > ((= x 2) (blubba 5)))) > > > > However, sometimes you're sure that you want to make an implicit > > binding for > > an identifier, and for those cases you need to write an "unhygienic" > > macro > > which can be achieved with the more complex macro system "syntax- > > case". > > > > Here's how your desired macro could be defined. I will use > > identifiers like > > "" just for easier readability; they don't have any special > > meaning: > > > > (define-syntax def > > (lambda (stx) > > (syntax-case stx () > > ((_ ( ...) * ...) > > (let ((ret-id (datum->syntax stx 'return))) > > #`(define ( ...) > > (call/cc (lambda (#,ret-id) * ...)))))))) > > > > There's a few things here to take note of: > > > > - Unlike with syntax-rules, the syntax-case is contained in a lambda > > which > > takes a single argument: a "syntax object" which is passed to > > syntax-case > > > > - Unlike with syntax-rules, the "body" of the macro (where it begins > > with a > > 'let') is not immediately part of the generated code; that 'let' is > > actually > > executed during compile-time. The body of the macro must result in > > an > > object of the type "syntax object" that represents the generated > > code. > > > > - You see that I define a variable called "ret-id" which I bind to > > the result > > of the expression: > > > > (datum->syntax stx 'return) > > > > which means "create a syntax object in the same lexical environment > > as stx, > > and is represented by the symbol 'return'." > > > > - The actual code generation begins within the #`(...) which is a > > shorthand > > for (quasisyntax (...)) just like '(...) is short for (quote > > (...)). The > > result of a quasisyntax expression is a syntax object. Basically, > > it's the > > most convenient way of creating a syntax object, but like syntax- > > rules it's > > also hygienic by default and you need to insert "unhygienic" syntax > > objects > > into it explicitly. > > > > - Within the quasisyntax, I use #,ret-id which is short for (unsyntax > > ret-id) > > to inject the unhygienic syntax object that holds the symbol > > 'return' into > > the generated code. > > > > For someone used to macros in the Common Lisp or Elisp style, this > > may seem > > over-complicated. It's the cost of the "hygienic by default" > > behavior. > > > > By the way I assume that you're just toying around with the language > > to learn. > > If you were thinking of using a 'def' macro like this in real code, I > > would > > discourage it because there's already a built-in mechanism that > > allows the > > programmer something very similar, called 'let/ec': > > > > (import (ice-9 control)) > > > > (define (test x) > > (let/ec return > > (cond > > ((= x 3) (return 7)) > > ((= x 2) (return 5))))) > > > > What does this return (defined with let/ec) do ? > > In the orevious versions I could see the call to call/cc so I could > (somewhat) figure out the "jump" imlpied by calling return > > But in this last case, where is the return behaviour defined ? > > > >