here is the "draft mail" i think it was better to answer separetely,but i send it waiting more...
thanks for all the answer,
i'm answering in a single answer to all for easyness and because some answers where same
First some people don't understand well my goal. It was just to be able to create an assignment operator the way Python,C,etc do it :
in Python if i create a variable, simply like that x=7 in a function, block...the variable can be modified the same way later: x=8 and the binding have a lexical scope (?),can be see anywhere in block or function and more if global keyword used .
In scheme it is different ,the binding is made first by definition let,let*,letrec.... and after if you want to modify it with set! or if you redo a define or a let in a block or nested code it will become a local variable to the block .
(which is perhaps not a problem,depending what we want to do)
Note that perhaps it is not clear or not a good idea what i want to do, testing will be necessary.
What complicate the things when creating macro or code doing this assignment operator is that in Scheme:
-i got often this error (not really clear for me): example : unknown file:6:7: definition in expression context, where definitions are not allowed, in form (define modul (current-module))
Now about the solutions:
Taylan give me some hints to answer, i first wrote this macro:
(define-syntax <$
(syntax-rules ()
((_ var expr) (begin
(define modul (current-module))
(define exist-var (module-variable modul (quote var)))
(if exist-var
(module-set! modul (quote var) expr)
(module-define! modul (quote var) expr))))))
sound good:
scheme@(guile-user)> {xx <$ 47}
scheme@(guile-user)> xx
47
scheme@(guile-user)> {xx <$ 49}
scheme@(guile-user)> xx
49
until i test this:
scheme@(guile-user)> (if #t {xx <$ 50} 'never)
While compiling expression:
Syntax error:
unknown file:6:7: definition in expression context, where definitions are not allowed, in form (define modul (current-module))
then i wrote this macro:
(define-syntax <§
(syntax-rules ()
((_ var expr) (let* ((modul (current-module))
(exist-var (module-variable modul (quote var))))
(if exist-var
(module-set! modul (quote var) expr)
(module-define! modul (quote var) expr))))))
and it seems good:
scheme@(guile-user)> {yy <§ 49}
scheme@(guile-user)> {yy <§ 50}
scheme@(guile-user)> (if #t {yy <§ 51} 'never)
scheme@(guile-user)> yy
51
i will test it in multiple context and programs
for this example i directly put the macro operator <§ in the main file,so it was easiest.
I later integrate it in a module and it works too.
.....
i paused writing the mail to think and realise that what i wanted to do was not clear,
Python and Scheme have to different 'scoping' for variables
those programs behave different:
def foo():
x=1
if True:
x=2
print(x)
print(x)
>>> foo()
2
2
and this one:
(define (foo)
(define x 1)
(if #t
(let ()
(define x 2)
(display x)
(newline))
'never)
(display x)
(newline))
(foo)
2
1
it is not like this ones which works like Python's foo version:
;; scheme@(guile-user)> (bar)
;; 2
;; 2
(define (bar)
(define x 1)
(if #t
(let ()
(set! x 2)
(display x)
(newline))
'never)
(display x)
(newline))
and it will not be a good idea for an extended Scheme to behave as Python, i must allow the two behaviors
and find a way they do not conflict each other using a special syntax.
basically what i need to define is two operators <- and <+ ( + for adding a variable in environment)
that can act as in the comments below:
;; scheme@(guile-user)> (foo)
;; 2
;; 1
(define (foo)
(define x 1) ;; x <- 1
(if #t
(let ()
(define x 2) ;; x <+ 2
(display x)
(newline))
'never)
(display x)
(newline))
;; scheme@(guile-user)> (bar)
;; 2
;; 2
(define (bar)
(define x 1) ;; x <- 1
(if #t
(let ()
(set! x 2) ;; x <- 2
(display x)
(newline))
'never)
(display x)
(newline))
<+ can be defined as <§ above.
problem is the code of <§ is not portable ,it is specific to guile.
The solution of Maxime Devos, should works too but is not portable, because all scheme does not allow this.The two solutions does not use R6RS .
Every Scheme implementation of my code will be specific for this operator.
I will test the Maxime's solution too. But i realize now is solution is good but my goal has changed now!
i need to act still more like Scheme than Python, be able to create local variables.
Matt Wett suggest to use define-once (also not existing in other Scheme implementations)
it is a good solution to write the <- operator using it and set!.
To be tested with define-once and set! if define-once is allowed in the context the macro is written.
Possible problem of this new operator <§,it creates only global (top-level?) variables,not lexically scoped:
scheme@(guile-user)> (if #t (begin {t <§ 57} (+ t 1) ) 'never)
;;; <stdin>:58:27: warning: possibly unbound variable `t'
$7 = 58
worked!
scheme@(guile-user)> t
$8 = 57
but now the nested variable in conditional branch is global (can be seen at top-level)
i'm still making test...