A lot of our Odin procs take an allocator as a required argument specifically so they force you to choose one at the call site, because yes, often you want it to be explicit.
I am thinking now a language that had the default allocator be a GC, but you could change it to something else using implicits/context and this is enfoced everywhere (e.g.: there is no way to allocate memory "from magic", you need to call the allocator, even if it is from context).
At least thinking in Scala as a base syntax here, it would mean:
def foo(name: String)(implicit allocator: MemoryAllocator): StringBuf = {
val buf = allocator.new(100, String)
buf.append("Hello ")
buf.append(name)
buf
}
println(foo("John")) // implicit allocator from context, default to GC, no need to free
implicit val allocator: MemoryAllocator = allocators.NewAllocator()
println(foo("Alice")) // another implicit allocator, but now using the manual allocator instead of GC
defer allocator.free()
val explicitAllocator = allocators.NewArenaAllocator()
foo("Marie")(explicitAllocator) // explicit allocator only for this call
defer explicitAllocator.free()
I don't think there is any language right now that has this focus, since Odin seems to be focused in manual allocations.