soegaard2
2020-6-7 16:53:06

@sorawee Your recent experiments with definitions in an expression context made be think of a similar problem.

I’d like to have an definition/assignment form (:= id expr) that works like define the first time := is used with an identifier and like set! the second, third, etc. time. Simply expanding := to define doesn’t work, due to duplicate definitions of the same identifier. There is module wide setting to turn that restriction off, but I’d like to keep the restriction for standard define.

If := also works in an expression context, that would just be a bonus.



soegaard2
2020-6-7 17:28:47

Your if-defined makes it simple: #lang racket ; The macro (define-syntax (if-defined stx) (syntax-case stx () [(_ id iftrue iffalse) (let ([where (identifier-binding #'id)]) (if where #'iftrue #'iffalse))])) ; Tests (if-defined z (list z) 'not-defined) ; -> not-defined (if-defined t (void) (define t 5)) t ; -> 5 (define x 3) (if-defined x (void) (define x 6)) x ; -> 3 (define-syntax (:= stx) (syntax-case stx () [(_:= id expr) (syntax/loc stx (if-defined id (set! id expr) (define id expr)))])) (:= a 42) a (:= a 43) a