sematic icon indicating copy to clipboard operation
sematic copied to clipboard

Make it possible to instantiate dataclasses with fields that are futures

Open augray opened this issue 2 years ago • 0 comments

This is a common pattern:

@dataclass
class Foo:
    foo: int
    bar: int

@sematic.func
def pipeline() -> Foo:
    some_int_result = some_sematic_func()
    
    # this currently breaks
    return Foo(foo=some_int_result, bar=42)

But it breaks, because some_int_result is a Future and Foo can't be instantiated with a future. This is essentially analogous to our automatic conversion from list-of-future to future-list: we need to convert from dataclass-with-future(s) to future-dataclass.

With this, as well as with the list thing, we should decide how deep to look for the futures, as they could be nested. Ex:

    return Foo(foo=AnotherDataclass(a=some_int_result), bar=42)

Instead of making this automatic, an alternative is to provide a helper:

@sematic.func
def pipeline() -> Foo:
    some_int_result = some_sematic_func()
    
    # 'make' would create a new Sematic func and apply it
    return make(Foo, foo=some_int_result, bar=42)

Note that there is a workaround for this pattern currently, but it's annoying:

@sematic.func
def make_foo(foo: int, bar: int) -> Foo:
    # wrapping with this func makes it so that futures will be resolved
    # before we call the init for Foo
    return Foo(foo=foo, bar=bar)
    
@sematic.func
def pipeline() -> Foo:
    some_int_result = some_sematic_func()
    
    
    return make_foo(foo=some_int_result, bar=42)

augray avatar Oct 19 '22 23:10 augray