[ats-lang-users] Can you pass !(&viewtypevar) as an argument that can be mutated?
Unleashing the potentials of types and templates
Status: Beta
Brought to you by:
ats-hwxi
From: Hans V. <keg...@gm...> - 2021-12-04 01:38:56
|
Hello Dr. Xi & friends, I am a very stupid man when it comes to types, and I'm working on my first ATS project using SDL and Emscripten. It worked right away, which felt amazing! However, I'm trying to understand how I can pass around a var like I do !type to avoid consuming the linear proof and still be able to mutate the argument. (Perhaps assuming this makes sense is my mistake.) I found a few posts on this list about creating "takeout/putback" prvals, as well as this excellent post https://bluishcoder.co.nz/2011/04/25/sharing-linear-resources-in-ats.html which came very close, but unfortunately I was unable to figure out how to apply it to my problem of passing around a reference to a var of a viewtype whose proofs I want to avoid consuming while still being able to mutate the argument. The below compiles if I don't attempt to set any field of ui, but If I uncomment either the ui.dimensions or ui.running :=, I get an error that seems to indicate that the l1 proof for ui was consumed. 10062(line=333, offs=5) -- 10064(line=333, offs=7): error(3): unsolved constraint: C3NSTRprop(C3TKmain(); S2Eeqeq(S2Evar(l1$9081(14901)); S2Evar(l1$9028(14847)))) src/main.dats: 10062(line=333, offs=5) -- 10064(line=333, offs=7): error(3): unsolved constraint for var preservation typechecking has failed: there are some unsolved constraints: please inspect the above reported error message(s) for information. This makes sense to me since I'm passing &ui, not !ui. If I change the argument of oneLoop to !ui (whether ui is an @ or '), I get this error: 9865(line=324, offs=34): error(3): a non-proof component is replaced of the type: [S2Ecst(bool)]. I assume this is because the argument is no longer mutable. Should I not be trying to use a viewtype var this way? Thank you in advance, Hans PS: Bonus question: Is there a way in ATS to do the matching of SDL_Event below as a switch statement (i.e. pattern-matching on $extval constants)? --- typedef dimensions = @{ width = int , height = int , refreshRate = int } viewtypedef ui (l1 : addr, l2 : addr, l3 : addr) = @{ window = SDL_Window l1 , renderer = SDL_Renderer l2 , font = TTF_Font l3 , dimensions = dimensions , running = bool } viewtypedef ui = [l1, l2, l3 : agz] ui(l1, l2, l3) // (SDL_Window/Renderer/TTF_Font are addr absviewtypes + agz viewtypedef as you'd expect) typedef callback = (&ui) -<fun1> void extern fun emscripten_set_main_loop_arg (func : callback, arg : &ui, fps : int, simulate_infinite_loop : bool) : void = "mac#" fun oneLoop (ui : &ui) : void = let var e : SDL_Event val () = e.type := $Unsafe.cast 0 var pollRet : int = SDL_PollEvent e val () = while (pollRet = 1) ( let val () = if e.type = SDL_MOUSEMOTION then () else if e.type = SDL_WINDOWEVENT then () // ui.dimensions := getWindowDimensions ui.window else if e.type = SDL_QUIT then () // ui.running := false else () in pollRet := SDL_PollEvent e end ) // val () = draw ui in () end implement main0 () = let ... var ui : ui (null, null, null) val () = ui.running := true val () = ui.dimensions := getDesktopDimensions () val () = ui.window := SDL_CreateWindow ("risk", 0, 0, ui.dimensions.width, ui.dimensions.height, SDL_WINDOW_SHOWN_RESIZABLE_OPENGL_HIGHDPI) val () = ui.renderer := SDL_CreateRenderer (ui.window, ~1, SDL_RENDERER_ACCELERATED) val () = ui.font := TTF_OpenFont ("fonts/UbuntuMono-R.ttf", 64) val ((* main loop *)) = emscripten_set_main_loop_arg(oneLoop, ui, 0, true) val () = SDL_DestroyRenderer ui.renderer val () = SDL_DestroyWindow ui.window val () = TTF_CloseFont ui.font val () = TTF_Quit () val () = SDL_FreeCursor cursorArrow val () = SDL_Quit () in () end |