For freeing resources automatically in Factor, take a look at destructors: https://docs.factorcode.org/content/article-destructors.html
The approach is quite different to ATS and other typed systems and is more akin to the C++ use of destructors to free resources when a scope is exited. I've used both Factor and ATS (both 1 and 2) quite a bit if you have any other questions. I've written about both in my blog: https://bluishcoder.co.nz/tags/factor/ https://bluishcoder.co.nz/tags/ats/index.html -- https://bluishcoder.co.nz On Fri, Jun 13, 2025, at 9:23 PM, toastal wrote: > Wanting to understand how safety is handled in Factor being an absolute > concenative novice… Last year I went out to learn ATS2 > <https://www.cs.bu.edu/~hwxi/atslangweb/> in the ML family (those > familar with OCaml or SML would be familar with the syntax). One of the > standout features was linear types for safe resource tracking (closing > file handles, always calling free, disallowing double free—where affine > types only assert can be used at most once vs. linear types *must* be > used exactly once). While the ATS2 language is a bit obtuse & > unconventional, it felt very safe to use it due to explicit typing. For > a ‘trivial’ example: > > ------------------------------------------------------------------------ > > #include "share/atspre_define.hats" > #include "share/atspre_staload.hats" > > implement main0 (): void = { > (* allocate for an integer, returning a tuple with proofs for values > & token for garbage collection | the pointer address *) > val (pfval, pfgc | ptr) = ptr_alloc<int>() > > (* set pointer value to 42 (! is sugar to dereference @ address) *) > val () = !ptr := 42 > > (* get pointer value assiging to x *) > val x = !ptr > > (* prints “x = 42” to console *) > val () = println!("x = ", x) > > (* frees pointer using consuming both linear types *) > val () = ptr_free(pfgc, pfval | ptr) > } > > ------------------------------------------------------------------------ > > If I skip the ``ptr_free(…)`` I will get a compiler error: > >> the linear dynamic variable [pfval$8389(-1)] needs to be consumed but >> it is preserved with the type [S2Eat(S2Eapp(S2Ecst(g1int_int_t0ype); >> S2Eextkind(atstype_int), S2Eintinf(42)), >> S2Evar(l$14498$14499$14500(23073)))] instead. > > If duplicate the ``ptr_free(…)`` line, I will get this compiler error: > >> the linear dynamic variable [pfgc$8390(-1)] is no longer available. > > It’s a lot of manual code, but these linear types prevent leaks & enforce > cleanup at the compiler level. These types are not limited to > hardware-level resource tracking in the sense that you could use this to > model in the type system of a game that you can’t unlock already > unlocked door & unlocking a door consumes a key. > > I understand Factor does not have these sorts of types (almost no > languages do) & is dynamically typed (ignoring ``TYPED:``), but I am > curious, especially from the C FFI side of things where freeing is > normally a manual/error-prone task, how would the Factor language, or > concatenative languages in general, model resource tracking. Is there > some sort of stack mechanism to sort of enforce cleanup or other > contracts? > > — toastal > > > _______________________________________________ > Factor-talk mailing list > Factor-talk@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/factor-talk _______________________________________________ Factor-talk mailing list Factor-talk@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/factor-talk