ta0kira / zeolite

Zeolite is a statically-typed, general-purpose programming language.
Apache License 2.0
18 stars 0 forks source link

Make `TypeInstance` usage shared. #48

Closed ta0kira closed 4 years ago

ta0kira commented 4 years ago

The main reason to do this is to remove types from the cache when they're no longer needed.

The cache can probably be handled by storing weak_ptr, having the type instance store an iterator to its cache entry, and removing itself in its destructor.

An alternative to this is to just disallow unbounded type recursion, e.g., prohibit this:

concrete Type<#x> {
  @type recursive (Int) -> ()
}

define Type {
  recursive (x) {
    if (x > 0) {
      \ Type<Type<#x>>$recursive(x-1)
    }
  }
}

That's probably not feasible for mutual recursion, however. Maybe the problem is using Type<#x> in param substitution.

ta0kira commented 4 years ago

Another option is to make type instances shared and remove the caches. That would make all type calls from outside of the respective type inefficient, however.

ta0kira commented 4 years ago

With that last option, the only sharing would be between values that were initialized from @value functions from the same type. So, pretty much the same as not sharing and not caching.

ta0kira commented 4 years ago

Regardless of the solution, this will require changing the C++ API.

ta0kira commented 4 years ago

It's probably better to do #50 first, since updating instance semantics will break all existing C++ extensions. In particular, I don't feel like hand-editing all of the builtins.

ta0kira commented 4 years ago

The breaking change that uses shared_ptr instead of & can be made without committing to a particular caching policy. Changes to caching can then be done later without breaking existing extensions, e.g., providing a helper macro to construct GetType_Foo, etc.

Overall, this should only break categories backed by C++ (since they could have @type members), since the zeolitecompiler currently disallows @type members.

ta0kira commented 4 years ago

One major issue I hadn't thought of is that this will require all occurrences of type instances to be shared, e.g., params stored within other type instances, and in ParamTuple.

ta0kira commented 4 years ago

This also requires adding a self variable (or similar) to all @type-function implementations so that they don't need to GetType_Foo/CreateType_Foo to call other functions or to create values.

This is problematic because value construction requires the derived type (to give @value functions access to the params), whereas self in @type calls will be S<TypeInstance>. On the other hand, @value creation requires memory allocation, which is already quite a bit slower than a cache lookup.

ta0kira commented 4 years ago

Also note that it's critical for the functioning of reduce that there is no TypeInstance duplication at any time, other than isomorphic unions and intersections.

ta0kira commented 4 years ago

Closing this, since TypeInstance is now shared. I'll create a new issue if/when I decide to implement some sort of cache clearing. Caches currently use weak_ptr, so the only thing that needs to be deallocated is the empty entries in the map.

(Also, regarding my comment above about avoiding duplication of TypeInstances: This really only applies to categories that have no params.)