sematic
sematic copied to clipboard
Make it possible to instantiate dataclasses with fields that are futures
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)