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

Reply via email to