unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Damien Mattei <damien.mattei@gmail.com>
To: "Linus Björnstam" <linus.internet@fastmail.se>,
	guile-user <guile-user@gnu.org>
Cc: Jean-Paul Roy <jean-paul.roy@unice.fr>
Subject: Re: define anywhere
Date: Wed, 9 Jun 2021 11:29:31 +0200	[thread overview]
Message-ID: <CADEOadeXFdQQBmKTsOiMnw6+ANqp7j4TcnSzbBCTqWPAiJJbHQ@mail.gmail.com> (raw)
In-Reply-To: <28842df5-d82b-4819-b7ad-2148265f7a83@www.fastmail.com>

hello, i'm just answering now  because my ten years old Mac book pro
definitely died sunday evening RIP

i was trying to make macro that set! variable if they exist or create it
before if the variable is not defined (tested by the Guile procedure
'defined?' which is not R*RS in any version)

but it seems that Guile 3.0 'define' can not create variable in local
blocks, as in Python :
(if test
    (begin
         (define x 7)
         (foo x))
     (else-block))
will not work.

This behavior force the definition of all variable at the upper level of
the function, the only advantage of guile 3.0 is perhaps (i have not tested
it fully) that you can put define not only at beginning of function.

This would be interesting to be able to define local variables with
'define',defining variable only in the block they are usefull.

With those limitation in mind i defined a few more macros:
(define-syntax <+
  (syntax-rules ()
    ((_ var expr) (define var expr))))

{ x <+ 7 } is equivalent to : (<- x 7) or (define x 7)

:=  is the same as <+
(define-syntax :=
  (syntax-rules ()
    ((_ var expr) (define var expr))))

{ x := 7 } is equivalent to : (:= x 7) or (define x 7)

;; definition without a value assigned
;;  (def x)
(define-syntax def
  (syntax-rules ()
    ((_ var) (define var '()))))

i added all that to my previous macro system in my Scheme+ (unfortunately
my github account is on my dead mac,so no commit for now)

i do not think i can do more for now, define anywhere in code could be a
good solution to let letrec let* that in my opinion should no longer exist
in Scheme.

Here is an example on the famous sub set sum problem algorithm  in two
versions one with define 'anywhere' and the other with my previous macro of
Scheme+:
scheme@(guile-user)> (define L-init '(1 3 4 16 17 64 256 275 723 889 1040
1041 1093 1111 1284 1344 1520 2027 2734 3000 4285 5027))
scheme@(guile-user)> (start-ssigma-sol-approx-pack-define-anywhere L-init
19836)
$1 = (1 3 4 16 17 256 275 723 1040 1041 1284 1344 1520 3000 4285 5027)
scheme@(guile-user)> (apply + '(1 3 4 16 17 256 275 723 1040 1041 1284 1344
1520 3000 4285 5027))
$2 = 19836

code:

*Preview:*

(define (start-ssigma-sol-approx-pack-define-anywhere L t) ;; Sub Set
Sum problem (find solution or approximation)
  ;; { } are for infix notation as defined in SRFI 105
  ;; <+ and := are equivalent to (define var value)
  { best-sol <+ (lambda (L1 L2)
		
		  {s1 <+ (apply + L1)}
		  {s2 <+ (apply + L2)}
		
		  (if {(abs {t - s1}) <= (abs {t - s2})}
		      L1
		      L2)) }

  ;; := is the same macro as <+
  { best-sol3 := (lambda (L1 L2 L3)
		
		   {L22 <+ (best-sol L2 L3)}
		   (best-sol L1 L22)) }


  { ssigma-sol-approx <+ (lambda (L)
			   ;; def is a macro for declared but unasigned variable, it is
same as (define var '())
			   (def c)
			   (def R)
			
			   (if (null? L)
			       L
			       (begin {c <- (first L)}
				      {R <- (rest L)}
				
				      (cond [ {c = t} (list c) ] ;; c is the solution
					    [ {c > t} (best-sol (list c) (ssigma-sol-approx R)) ] ;; c is
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
							
							      ;; c part of solution or is approximation
							      (cons c (start-ssigma-sol-approx-pack-define-anywhere R
{t - c})) ;; we have to find a solution or an approximation for t-c
now
									
							      ;; c is not part of solution or his approximation
							      (ssigma-sol-approx R))])))) }
		
	
  ;; start the function
  (ssigma-sol-approx L))


with other macros of Scheme+ code looked like this:


*Preview:*

;; scheme@(guile-user)> (define L-init '(1 3 4 16 17 64 256 275 723
889 1040 1041 1093 1111 1284 1344 1520 2027 2734 3000 4285 5027));;
scheme@(guile-user)> (start-ssigma-sol-approx-pack L-init 19836);; $1
= (1 3 4 16 17 256 275 723 1040 1041 1284 1344 1520 3000 4285 5027)
(define (start-ssigma-sol-approx-pack L t) ;; Sub Set Sum problem
(find solution or approximation)


  (letrec-arrow* [ best-sol ← (lambda (L1 L2)
			
				(let-arrow*  [ s1 ← (apply + L1)
					       s2 ← (apply + L2) ]
				
					     (if {(abs {t - s1}) <= (abs {t - s2})}
						 L1
						 L2)))

		   best-sol3 ← (lambda (L1 L2 L3)
			
				 (let [(L22 (best-sol L2 L3))]
				   (best-sol L1 L22)))
	
	           ssigma-sol-approx ← (lambda (L)
				     				
				      (if (null? L)
					
					  L
					
					  (let-arrow* [ c ← (first L)
						        R ← (rest L)  ]
					
					    (cond [ {c = t} (list c) ] ;; c is the solution
						  [ {c > t} (best-sol (list c) (ssigma-sol-approx R)) ] ;; c is
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
								
								    ;;(begin
								      ;; (display "append c=") (display c) (newline)
								    ;; c part of solution or is approximation
								    (cons c (start-ssigma-sol-approx-pack R {t - c}));;) ;; we
have to find a solution or an approximation for t-c now
								
								    ;; c is not part of solution or his approximation
								    (ssigma-sol-approx R))]))))

	
	       ]

	     ;; start the function
	     (ssigma-sol-approx L)))



the use of define anywhere will make code more readable, infixe notation
and macros too...

A last example in Scheme+ with arrays on the dynamic solution of subset sum
problem (just answer if a solution exist or not):

*Preview:*

(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")

(define L-init '(1 3 4 16 17 24 45 64 197 256 275 323 540 723 889 915
1040 1041 1093 1099 1111 1284 1344 1520 2027 2500 2734 3000 3267 3610
4285 5027))
(define t-init 35267)
(define ls (length L-init))
(define dyna (make-array 0 {ls + 1} {t-init + 1}))
(define (one-two b)
  (if b 1 2))
(define cpt 0)
;; scheme@(guile-user)> (ssigma-dyna-define-anywhere L-init t-init);;
$1 = #t;; scheme@(guile-user)> cpt;; $2 = 147801(define
(ssigma-dyna-define-anywhere L t)

  {cpt <- {cpt + 1}} ;; cpt is defined at toplevel

  ;;(display L) (display " ") (display t) (newline)

  {ls <+ (length L)}
  {dyn <+ {dyna[ls t]}}

  (def c)
  (def R)

  ;; dyna[ls t] means 0: unknown solution, 1: solution found, 2: no solution
  (one?
    (if (not (zero? dyn))
	
	dyn
	
	;; 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 = t} #t ] ;; c is the solution
				      [ {c > t} (ssigma-dyna-define-anywhere R t) ] ;; c is to big
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
(ssigma-dyna-define-anywhere R t)} ] )))) } )))



Damien


On Sun, Jun 6, 2021 at 7:32 PM Linus Björnstam <linus.internet@fastmail.se>
wrote:

> Try
> ,expand (new-set! X 7)  at the repl.
>
> That will however not do what you want. define does not work like that.
> Define adds the binding in what is called the current lexical environment:
> a define inside an if will not be visible outside that if (even if it would
> have been valid syntax).
>
> What are you trying to write?
>
> --
>   Linus Björnstam
>
> 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)))))
> >
> > scheme@(guile-user)> (new-set! x 7)
> > ;;; <stdin>:24:0: warning: possibly unbound variable `x'
> > ;;; <stdin>:24:0: warning: possibly unbound variable `x'
> > ice-9/boot-9.scm:1669:16: In procedure raise-exception:
> > Unbound variable: x
> >
> > Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> > scheme@(guile-user) [1]> ,bt
> > In current input:
> >      24:0  1 (_)
> > In ice-9/boot-9.scm:
> >   1669:16  0 (raise-exception _ #:continuable? _)
> >
> > any idea?
> >
> > Damien
> >
> > On Sat, Jun 5, 2021 at 5:24 PM Linus Björnstam
> > <linus.internet@fastmail.se> wrote:
> > > I implemented this hack before guile 3 got defines in function bodies:
> https://hg.sr.ht/~bjoli/guile-define
> > >
> > > 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)
> > > --
> > >   Linus Björnstam
> > >
> > > 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 variable
> > > > 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_define_inside_lambda_bodies_in/
> > > > )
> > > >  is it possible in guile to do it? i do not know, so could it be
> added
> > > > to
> > > > the language specification for future release?
> > > >
> > > > regards,
> > > > Damien
> > > >
>


  parent reply	other threads:[~2021-06-09  9:29 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-04 22:27 define anywhere Damien Mattei
2021-06-05  2:10 ` Taylan Kammer
2021-06-05  8:50   ` Dr. Arne Babenhauserheide
2021-06-05 15:23 ` Linus Björnstam
2021-06-06  8:09   ` Linus Björnstam
2021-06-06 12:02     ` Dr. Arne Babenhauserheide
2021-06-06 13:36       ` Linus Björnstam
2021-06-06 16:45         ` Dr. Arne Babenhauserheide
2021-06-11  8:08         ` Damien Mattei
     [not found]   ` <CADEOadcwk1D9of6C1owQQSqFNRvUmA=wJKSngySbGsfdDUzoMw@mail.gmail.com>
     [not found]     ` <28842df5-d82b-4819-b7ad-2148265f7a83@www.fastmail.com>
2021-06-09  9:29       ` Damien Mattei [this message]
2021-06-09 10:11         ` Linus Björnstam
2021-06-11  8:15           ` Damien Mattei
2021-06-11  8:07   ` Damien Mattei
2021-06-11 23:43   ` Damien Mattei

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CADEOadeXFdQQBmKTsOiMnw6+ANqp7j4TcnSzbBCTqWPAiJJbHQ@mail.gmail.com \
    --to=damien.mattei@gmail.com \
    --cc=guile-user@gnu.org \
    --cc=jean-paul.roy@unice.fr \
    --cc=linus.internet@fastmail.se \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).