From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?Linus_Bj=C3=B6rnstam?= Newsgroups: gmane.lisp.guile.user Subject: Re: define anywhere Date: Wed, 09 Jun 2021 12:11:21 +0200 Message-ID: References: <28842df5-d82b-4819-b7ad-2148265f7a83@www.fastmail.com> 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="6921"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Cyrus-JMAP/3.5.0-alpha0-519-g27a961944e-fm-20210531.001-g27a96194 Cc: Jean-Paul Roy To: "Damien Mattei" , guile-user Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Wed Jun 09 12:12:13 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 1lqvBz-0001aC-Tt for guile-user@m.gmane-mx.org; Wed, 09 Jun 2021 12:12:12 +0200 Original-Received: from localhost ([::1]:36722 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lqvBy-0004MD-VI for guile-user@m.gmane-mx.org; Wed, 09 Jun 2021 06:12:10 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:42558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqvBe-0004Jc-9x for guile-user@gnu.org; Wed, 09 Jun 2021 06:11:50 -0400 Original-Received: from wout2-smtp.messagingengine.com ([64.147.123.25]:49913) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lqvBb-0002Sk-Fj for guile-user@gnu.org; Wed, 09 Jun 2021 06:11:50 -0400 Original-Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 358F61DE0; Wed, 9 Jun 2021 06:11:44 -0400 (EDT) Original-Received: from imap43 ([10.202.2.93]) by compute5.internal (MEProxy); Wed, 09 Jun 2021 06:11:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.se; h= mime-version:message-id:in-reply-to:references:date:from:to:cc :subject:content-type:content-transfer-encoding; s=fm3; bh=eLxNk 2SPUDscFqq3KAmfrKJrdJP67o0sAMu+TP4SASQ=; b=BBVRX46JgnERmCu844n40 pnxqEWGouDvjQm3Kg5o6DFMRsPzLgpvpldQkKaJFjH29Do+j+mhy7hvRfX215zEd qXypBIhPTOF6ceWeKksHvJU+VaOhKlEpamBztxAEXMw4W9Db7xXwlLcmNcWj8BSE f3tqVPQl+dsL3YHWJ4ojm8TPdBEUmvzryurhl2++nDCiw/oLRotHmGLg665RlONV S331aSRggaSU2eWOt4Er9zXNyJ0ym8bswPeAIIuvU0ohwWjzz5BH9KqvoIUqIt65 pEJdIet+Ck2+hmwr3IEmO7yViZUnC+QTbDP9icyEKouc2GDqmBTEz4j5g2TdBXoA w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; bh=eLxNk2SPUDscFqq3KAmfrKJrdJP67o0sAMu+TP4SA SQ=; b=p02POKuvox/OTy3HSBNaUMQD5TqPqefID73BhMXwTYMcWJuw3F1HlWFSQ yzJCI1mjJb0ODxkJ3/QaFWgMhl3N8q8UITOK6tYpRlOdSjd9mjjNLoIe81KMOHfh BqUuqrHuXnStHp8cuAfN5/mpPoRNzTgI1tNIDTZvsa46uy0FVr1xhyhWir68S+vN 158GKRHWvi2gNhaocT4ixH/HRa03LrVbh227SXsF7sXJIRxoUYztUQRd4lKQ/LoI 6Kifpnobqd+Zg/TQSNi5NJexXiKhU7fjMyQBcYM4WOkOKs52pPzAdojuOLzdm39X Itmt/F9TuShHjT3BMuCa+MMeXmomw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrfeduuddgvdehucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgfgsehtqhertderreejnecuhfhrohhmpefnihhn uhhspgeujhpnrhhnshhtrghmuceolhhinhhushdrihhnthgvrhhnvghtsehfrghsthhmrg hilhdrshgvqeenucggtffrrghtthgvrhhnpeefvdejteeghfefgfegteeggfeileegffeg gfejueegvedtfeelgfefveektdfhieenucffohhmrghinhepshhrrdhhthdprhgvugguih htrdgtohhmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhho mheplhhinhhushdrihhnthgvrhhnvghtsehfrghsthhmrghilhdrshgv X-ME-Proxy: Original-Received: by mailuser.nyi.internal (Postfix, from userid 501) id 56A9EAC006A; Wed, 9 Jun 2021 06:11:43 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface In-Reply-To: Received-SPF: pass client-ip=64.147.123.25; envelope-from=linus.internet@fastmail.se; helo=wout2-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 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, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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:17587 Archived-At: Hi Damien! The problem that define only defines a variable in the current lexical e= nvironment. Even if a definition in an if block would work from a syntac= tical standpoint, it would be pointless. As per r6rs, internal (define ...) are akin to letrec, but are only allo= wed in definition context. Guile 3 relaxes this for function bodies, whe= reas the macros I linked above relaxes this for some additional forms. I= t cannot however "export" bindings to any outer environment. What you can do is use module reflection to create top-level variables i= n the current module, but that makes everyone flinch about 105% of the t= ime.=20 --=20 Linus Bj=C3=B6rnstam On Wed, 9 Jun 2021, at 11:29, Damien Mattei wrote: > hello, i'm just answering now because my ten years old Mac book pro=20= > definitely died sunday evening RIP=20 >=20 > i was trying to make macro that set! variable if they exist or create=20= > it before if the variable is not defined (tested by the Guile procedur= e=20 > 'defined?' which is not R*RS in any version) >=20 > but it seems that Guile 3.0 'define' can not create variable in local=20= > blocks, as in Python : > (if test=20 > (begin > (define x 7) > (foo x)) > (else-block)) > will not work. >=20 > This behavior force the definition of all variable at the upper level=20= > of the function, the only advantage of guile 3.0 is perhaps (i have no= t=20 > tested it fully) that you can put define not only at beginning of=20 > function. >=20 > This would be interesting to be able to define local variables with=20= > 'define',defining variable only in the block they are usefull. >=20 > With those limitation in mind i defined a few more macros: > (define-syntax <+ > (syntax-rules () > ((_ var expr) (define var expr)))) >=20 > { x <+ 7 } is equivalent to : (<- x 7) or (define x 7) >=20 > :=3D is the same as <+ > (define-syntax :=3D > (syntax-rules () > ((_ var expr) (define var expr)))) >=20 > { x :=3D 7 } is equivalent to : (:=3D x 7) or (define x 7) >=20 > ;; definition without a value assigned > ;; (def x)=20 > (define-syntax def > (syntax-rules () > ((_ var) (define var '())))) >=20 > i added all that to my previous macro system in my Scheme+=20 > (unfortunately my github account is on my dead mac,so no commit for no= w) >=20 > i do not think i can do more for now, define anywhere in code could be= =20 > a good solution to let letrec let* that in my opinion should no longer= =20 > exist in Scheme. >=20 > Here is an example on the famous sub set sum problem algorithm in two= =20 > versions one with define 'anywhere' and the other with my previous=20 > macro of Scheme+: > scheme@(guile-user)> (define L-init '(1 3 4 16 17 64 256 275 723 889=20= > 1040 1041 1093 1111 1284 1344 1520 2027 2734 3000 4285 5027)) > scheme@(guile-user)> (start-ssigma-sol-approx-pack-define-anywhere=20 > L-init 19836) > $1 =3D (1 3 4 16 17 256 275 723 1040 1041 1284 1344 1520 3000 4285 502= 7) > scheme@(guile-user)> (apply + '(1 3 4 16 17 256 275 723 1040 1041 1284= =20 > 1344 1520 3000 4285 5027)) > $2 =3D 19836 >=20 > code: > *Preview:*=20 >=20 > (define (start-ssigma-sol-approx-pack-define-anywhere L t) ;; Sub Set=20= > Sum problem (find solution or approximation) > ;; { } are for infix notation as defined in SRFI 105 > ;; <+ and :=3D are equivalent to (define var value)=20 > { best-sol <+ (lambda (L1 L2) > =20 > {s1 <+ (apply + L1)} > {s2 <+ (apply + L2)} > =20 > (if {(abs {t - s1}) <=3D (abs {t - s2})} > L1 > L2)) } >=20 > ;; :=3D is the same macro as <+ > { best-sol3 :=3D (lambda (L1 L2 L3) > =20 > {L22 <+ (best-sol L2 L3)} > (best-sol L1 L22)) } >=20 > =20 > { ssigma-sol-approx <+ (lambda (L) > ;; def is a macro for declared but unasigned variable, it is sam= e=20 > as (define var '()) > (def c)=20 > (def R) > =20 > (if (null? L) > L > (begin {c <- (first L)} > {R <- (rest L)} > =20 > (cond [ {c =3D t} (list c) ] ;; c is the solution > [ {c > t} (best-sol (list c) (ssigma-sol-approx R)) ] ;; c is= =20 > to big to be a solution but could be an approximation > ;; c < t at this point, 3 possibilities : > ;; c is the best solution > ;; c is part of the solution or his approximation > ;; or c is not part of solution or his approximation > [ else (best-sol3 (list c) ;; c is the best solution > =20 > ;; c part of solution or is approximation > (cons c (start-ssigma-sol-approx-pack-define-anywhere R {= t=20 > - c})) ;; we have to find a solution or an approximation for t-c now > =20 > ;; c is not part of solution or his approximation > (ssigma-sol-approx R))])))) } > =20 > =20 > ;; start the function > (ssigma-sol-approx L)) > * > * >=20 > with other macros of Scheme+ code looked like this:* > * >=20 > * > * >=20 > *Preview:*=20 >=20 > ;; scheme@(guile-user)> (define L-init '(1 3 4 16 17 64 256 275 723 88= 9=20 > 1040 1041 1093 1111 1284 1344 1520 2027 2734 3000 4285 5027)) > ;; scheme@(guile-user)> (start-ssigma-sol-approx-pack L-init 19836) > ;; $1 =3D (1 3 4 16 17 256 275 723 1040 1041 1284 1344 1520 3000 4285=20= > 5027) >=20 > (define (start-ssigma-sol-approx-pack L t) ;; Sub Set Sum problem (fin= d=20 > solution or approximation) > =20 >=20 > (letrec-arrow* [ best-sol =E2=86=90 (lambda (L1 L2) > =20 > (let-arrow* [ s1 =E2=86=90 (apply + L1) > s2 =E2=86=90 (apply + L2) ] > =20 > (if {(abs {t - s1}) <=3D (abs {t - s2})} > L1 > L2))) >=20 > best-sol3 =E2=86=90 (lambda (L1 L2 L3) > =20 > (let [(L22 (best-sol L2 L3))] > (best-sol L1 L22))) > =20 > ssigma-sol-approx =E2=86=90 (lambda (L) > =20 > (if (null? L) > =20 > L > =20 > (let-arrow* [ c =E2=86=90 (first L) > R =E2=86=90 (rest L) ] > =20 > (cond [ {c =3D t} (list c) ] ;; c is the solution > [ {c > t} (best-sol (list c) (ssigma-sol-approx R)) ] ;; c is=20= > to big to be a solution but could be an approximation > ;; c < t at this point, 3 possibilities : > ;; c is the best solution > ;; c is part of the solution or his approximation > ;; or c is not part of solution or his approximation > [ else (best-sol3 (list c) ;; c is the best solution > =20 > ;;(begin > ;; (display "append c=3D") (display c) (newline) > ;; c part of solution or is approximation > (cons c (start-ssigma-sol-approx-pack R {t - c}));;) ;; we= =20 > have to find a solution or an approximation for t-c now > =20 > ;; c is not part of solution or his approximation > (ssigma-sol-approx R))])))) >=20 > =20 > ] >=20 > ;; start the function > (ssigma-sol-approx L))) >=20 >=20 > the use of define anywhere will make code more readable, infixe=20 > notation and macros too... >=20 > A last example in Scheme+ with arrays on the dynamic solution of subse= t=20 > sum problem (just answer if a solution exist or not): >=20 > *Preview:*=20 >=20 > (include "../library-FunctProg/first-and-rest.scm") > (include "../library-FunctProg/guile/array.scm") > (include "../library-FunctProg/pair.scm") > (include "../library-FunctProg/number.scm") > (include "../library-FunctProg/list.scm") > (include "../library-FunctProg/let.scm") >=20 >=20 > (define L-init '(1 3 4 16 17 24 45 64 197 256 275 323 540 723 889 915=20= > 1040 1041 1093 1099 1111 1284 1344 1520 2027 2500 2734 3000 3267 3610=20= > 4285 5027)) >=20 > (define t-init 35267) >=20 > (define ls (length L-init)) >=20 > (define dyna (make-array 0 {ls + 1} {t-init + 1})) >=20 > (define (one-two b) > (if b 1 2)) >=20 > (define cpt 0) >=20 > ;; scheme@(guile-user)> (ssigma-dyna-define-anywhere L-init t-init) > ;; $1 =3D #t > ;; scheme@(guile-user)> cpt > ;; $2 =3D 147801 > (define (ssigma-dyna-define-anywhere L t) >=20 > {cpt <- {cpt + 1}} ;; cpt is defined at toplevel > =20 > ;;(display L) (display " ") (display t) (newline) > =20 > {ls <+ (length L)} > {dyn <+ {dyna[ls t]}} >=20 > (def c) > (def R) > =20 > ;; dyna[ls t] means 0: unknown solution, 1: solution found, 2: no so= lution > (one? > (if (not (zero? dyn)) > =09 > dyn > =09 > ;; set the array but return the variable > { dyna[ls t] <- (one-two > (if (null? L) > #f > (begin > {c <- (first L)} > {R <- (rest L)} > (cond [ {c =3D t} #t ] ;; c is the solution > [ {c > t} (ssigma-dyna-define-anywhere R t) ] ;; c is to big= =20 > to be a solution but can be an approximation > ;; c < t at this point > ;; c is part of the solution or his approximation > ;; or c is not part of solution or his approximation > [ else {(ssigma-dyna-define-anywhere R {t - c}) or=20 > (ssigma-dyna-define-anywhere R t)} ] )))) } ))) >=20 >=20 > Damien >=20 >=20 > On Sun, Jun 6, 2021 at 7:32 PM Linus Bj=C3=B6rnstam=20 > wrote: > > Try=20 > > ,expand (new-set! X 7) at the repl.=20 > >=20 > > That will however not do what you want. define does not work like th= at. Define adds the binding in what is called the current lexical enviro= nment: a define inside an if will not be visible outside that if (even i= f it would have been valid syntax). > >=20 > > What are you trying to write? > >=20 > > --=20 > > Linus Bj=C3=B6rnstam > >=20 > > On Sun, 6 Jun 2021, at 17:16, Damien Mattei wrote: > > > macros... i can not figure out how to make this one works: > > > (define-syntax new-set! > > > (syntax-rules () > > > ((_ var expr) (if (defined? (quote var)) > > > (set! var expr) > > > (define var expr)))))=20 > > >=20 > > > scheme@(guile-user)> (new-set! x 7) > > > ;;; :24:0: warning: possibly unbound variable `x' > > > ;;; :24:0: warning: possibly unbound variable `x' > > > ice-9/boot-9.scm:1669:16: In procedure raise-exception: > > > Unbound variable: x > > >=20 > > > Entering a new prompt. Type `,bt' for a backtrace or `,q' to cont= inue. > > > scheme@(guile-user) [1]> ,bt > > > In current input: > > > 24:0 1 (_) > > > In ice-9/boot-9.scm: > > > 1669:16 0 (raise-exception _ #:continuable? _) > > >=20 > > > any idea? > > >=20 > > > Damien > > >=20 > > > On Sat, Jun 5, 2021 at 5:24 PM Linus Bj=C3=B6rnstam=20 > > > wrote: > > > > I implemented this hack before guile 3 got defines in function b= odies: https://hg.sr.ht/~bjoli/guile-define > > > >=20 > > > > Even I guile 3 it allows a more liberal placement of define, but= it won't work for things like bodies of imported macros (like match) > > > > --=20 > > > > Linus Bj=C3=B6rnstam > > > >=20 > > > > On Sat, 5 Jun 2021, at 00:27, Damien Mattei wrote: > > > > > hello, > > > > > i'm was considering that i want to be able to define a variabl= e=20 > > > > > anywhere in > > > > > code, the way Python do. Few scheme can do that (Bigloo i know= ) > > > > > ( the list here is not exact: > > > > > https://www.reddit.com/r/scheme/comments/b73fdz/placement_of_d= efine_inside_lambda_bodies_in/ > > > > > ) > > > > > is it possible in guile to do it? i do not know, so could it = be added=20 > > > > > to > > > > > the language specification for future release? > > > > >=20 > > > > > regards, > > > > > Damien > > > > >=20