Mutable global xtlang variables

35 views
Skip to first unread message

Toby Gifford

unread,
Nov 29, 2015, 4:05:56 AM11/29/15
to extemp...@googlegroups.com
I vote for allowing mutation of bind-val'ed variables. Sure, insist on the type remaining the same, but is there any good reason to protect the values from change? Is is a caching efficiency thing?

Jason Levine

unread,
Nov 29, 2015, 5:50:29 AM11/29/15
to extemp...@googlegroups.com
I am also curious to know more about this.

If I have:

(bind-val x float 100.0)
(bind-val y float 100.0)
(bind-val xspeed float 2.5)
(bind-val yspeed float 2.0)

then I can mutate them like this:

(bind-func draw_frame
  (let ((frame 0))
    (lambda ()
;; draw background
   (background 1.0 1.0 1.0)
    
;; update the ball position
    (set! x (+ x xspeed))
    (set! y (+ y yspeed))
    (if (or (> x width) (< x 0.0))
  (set! xspeed (* xspeed -1.0)))
    (if (or (> y height) (< y 0.0))
  (set! yspeed (* yspeed -1.0))) 
      
;; draw the ball
      (circle x y 48.0) 
 
;; increment and end frame
      (set! frame (+ frame 1))))) 

but somehow I can't mutate them outside of a function.  Doing this:
(set! x 4.0)

gives me:
stack-catch: ()
stack-catch: ()
set!: unbound variable:
Trace: 
 

which is curious! 

On Sun, Nov 29, 2015 at 5:05 PM, Toby Gifford <toby.g...@gmail.com> wrote:
I vote for allowing mutation of bind-val'ed variables. Sure, insist on the type remaining the same, but is there any good reason to protect the values from change? Is is a caching efficiency thing?

--
You received this message because you are subscribed to the Google Groups "Extempore" group.
To unsubscribe from this group and stop receiving emails from it, send an email to extemporelan...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Jason Levine
new media performer + creative coder

Toby Gifford

unread,
Nov 29, 2015, 5:56:17 AM11/29/15
to extemp...@googlegroups.com
I think in your case the (set! x 4.0) fails because it is invoking the scheme interpreter, which doesn't know about x.

But, good point, the bind-val'd variables are mutable, just not by re-bind-val'ing them.

Andrew Sorensen

unread,
Nov 29, 2015, 6:11:21 AM11/29/15
to extemp...@googlegroups.com, Toby Gifford
This has always been about allocation rather than mutation i.e. don't allow reallocation. It is of course easy enough to mutate with.

(call-as-xtlang (set! x 5))
Or shorter
(xtmX (set! x 5))

Reevaluating bind-val multiple times has a slightly different semantics though.

This has been something that I've been thinking about - just not for quite long enough yet :). I made a bunch of bind-val changes pre 0.6 and want to give those some time to settle.

Cheers
Andrew.


On 29 November 2015 7:05:55 pm AEST, Toby Gifford <toby.g...@gmail.com> wrote:
I vote for allowing mutation of bind-val'ed variables. Sure, insist on the type remaining the same, but is there any good reason to protect the values from change? Is is a caching efficiency thing?


--
Sent from my Android device with K-9 Mail. Please excuse my brevity.

Jason Levine

unread,
Nov 29, 2015, 7:26:29 AM11/29/15
to extemp...@googlegroups.com, Toby Gifford
Can you please explain (call-as-xtlang) ?

If I understand correctly, its treating xtlang as data and asking the xtlang compiler to evaluate this code. But why?

In the case of (set! x 4.0) you are using it because set! is a scheme function to the compiler defaults to scheme?


Here's the context, I'm trying to make this code:

(sys:load "libs/external/glfw3.xtm")
(bind-val width float 800.)
(bind-val height float 200.)
(bind-val window GLFWwindow*
  (begin
    (glfwSetErrorCallback (convert (get_native_fptr glfw_error_callback)))
    (glfw_init_and_create_interaction_window (convert width) (convert height))))
(sys:load "libs/external/nanovg.xtm")
(bind-val vg NVGcontext* (nvg_create_context))
(bind-val pixel_ratio float (glfw_get_pixel_ratio window))

into a function like this:
(setup_graphics 800. 200.) 

Obviously, I can't wrap it in a function because you can't allocate global variables from within a bind-func. Plus, at the time of binding, many of the types used don't exist yet because the libs haven't been loaded yet. 

I tried wrapping it in a (call-as-xtlang) but then I get this semi-cryptic message:
Compiler Error cannot find variable  pixel_ratio 
Compiler Error cannot find symbol  impc:aot:insert-globalvar-binding-details 
 
Is a macro what I'm looking for? (I don't know macros yet)  In OOP, this kind of thing would happen in a function in the top most class.

--
You received this message because you are subscribed to the Google Groups "Extempore" group.
To unsubscribe from this group and stop receiving emails from it, send an email to extemporelan...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Andrew Sorensen

unread,
Nov 29, 2015, 9:09:36 PM11/29/15
to extemp...@googlegroups.com, Toby Gifford
On Sun, Nov 29, 2015 at 10:26 PM, Jason Levine <jasonbe...@gmail.com> wrote:
Can you please explain (call-as-xtlang) ?

call-as-xtlang compiles (and then executes) the expression that you pass it.
 

If I understand correctly, its treating xtlang as data and asking the xtlang compiler to evaluate this code. But why?
 
In the case of (set! x 4.0) you are using it because set! is a scheme function to the compiler defaults to scheme?

*Everything* that you evaluate in your editor is sent to the scheme interpreter. It is in fact impossible to do anything in xtlang without going through the scheme interpreter.  For example, call-as-xtlang is a scheme macro that compiles an xtlang expression and then executes it.  The way that I like to think about this is that scheme is bash scripting in the shell, and xtlang is the c code that your bash scripts are executing.  


Here's the context, I'm trying to make this code:

(sys:load "libs/external/glfw3.xtm")
(bind-val width float 800.)
(bind-val height float 200.)
(bind-val window GLFWwindow*
  (begin
    (glfwSetErrorCallback (convert (get_native_fptr glfw_error_callback)))
    (glfw_init_and_create_interaction_window (convert width) (convert height))))
(sys:load "libs/external/nanovg.xtm")
(bind-val vg NVGcontext* (nvg_create_context))
(bind-val pixel_ratio float (glfw_get_pixel_ratio window))

into a function like this:
(setup_graphics 800. 200.) 

Obviously, I can't wrap it in a function because you can't allocate global variables from within a bind-func. Plus, at the time of binding, many of the types used don't exist yet because the libs haven't been loaded yet. 

Correct. Also neither bind-val nor sys:load are valid xtlang expressions - they are both scheme functions/macros.  How can you tell?  Because they are used at the top level - and anything at the top level *must* be a valid scheme expression - like call-as-xtlang (a scheme macro).  This is why we need something like call-as-xtlang - as there is no way to get xtlang code compiled and executed without going through scheme we need the thin scheme wrapper that call-as-xtlang provides.  

Note that the scheme veneer can be very thin.  Just like in bash, once we have 'executed' our native xtlang code, it runs independently of bash.  Also, like bash, variables defined in bash (env variables) are not directly available to C and C variables are not directly available to bash - at least not by default.  Instead we need to explicitly pass information between the two - as we do between scheme and xtlang.

What can be confusing is when you have syntax that is valid in both xtlang and scheme.  set! is just such an example.  Here are examples of 'x' and 'y'.

(define x 5)  ;; defined in scheme - like a bash environment variable
(bind-val x i32 7)  ;; defined in xtlang 
(set! x 6)      ;; set scheme 'x' to be 6
(call-as-xtlang (set! x 8))  ;; set xtlang 'x' to be 8

(define y 5) ;; defined in scheme
(call-as-xlang (set! y 9)) ;; fails - xtlang doesn't know about 'y'
 
 Is a macro what I'm looking for? (I don't know macros yet)  In OOP, this kind of thing would happen in a function in the top most class.
 
Yes this is where a scheme macro can be useful.  However, this is perhaps better realised as a plain old file which you load at runtime using sys:load.  

Cheers,
Andrew.
Reply all
Reply to author
Forward
0 new messages