Closed acl-cqc closed 1 week ago
On #1195, @ss2165 wrote:
Thoughts on builder interface:
- Builders that infer extensions should be default, therefore they should have the short names (probably just the set of names we currently use with explicit deltas).
- Explicit delta versions, if necessary, can have some standard naming convention (e.g.
dfg_builder_delta
)- Could a potential simplification be just to require
FunctionType
inputs wherever possible (rather than in_types + out_types) and then make the default extension set inFunctionType
TO_BE_INFERRED
. Thenwith_extension_delta
onFunctionType
would overwrite the default set? Are there uses ofFunctionType
where having the default extension set be empty is important?
On #1195, @ss2165 wrote:
Thoughts on builder interface:
- Could a potential simplification be just to require
FunctionType
inputs wherever possible (rather than in_types + out_types) and then make the default extension set inFunctionType
TO_BE_INFERRED
. Thenwith_extension_delta
onFunctionType
would overwrite the default set? Are there uses ofFunctionType
where having the default extension set be empty is important?
On the latter - yes: every time a FunctionType is used inside a Type::new_function
, say, or for a FuncDefn (which we don't infer, but I suppose could - just requires a more complex algorithm that builds a call graph and looks for cycles), or a FuncDecl (which we definitely can't infer). Also not for OpDef signatures...
Moreover whilst I agree that the builder should default to inference I'm less sure about Hugr's built directly without the builder. One thing we could do though would be
::new_pure
FunctionType::new
taking 2*TypeRow + ExtensionSetnew_endo
/ new_pure_endo
FunctionType::new_inferred
(or maybe a shorter name) taking 2*TypeRow (and setting TO_BE_INFERRED)::new_inferred_endo
However whilst fine for directly-constructed Hugrs (inference is available at reduced cost but still slightly more than being explicit, which feels right) this still leaves the builder wanting.
I also thought about making the builder methods take not a FunctionType
but an impl Into<FTSpec>
(for some new type FTSpec
) where we impl From<FunctionType> for FTSpec
(providing all the existing interfaces from before this PR), but then we can also have impl From<(TypeRow, TypeRow)> for FTSpec
(with extensions TO_BE_INFERRED) and impl From<TypeRow> for FTSpec
(endomorphic TO_BE_INFERRED). However the problem with this is that we rely heavily (e.g. in FunctionType::new
) on impl Into<TypeRow>
with all sorts of handy conversions there (e.g. from a single Type
or Vec<Type>
) which we'd not be able to use. (I think the Rust foreign-trait impl rule prevents us from defining transitive conversions - we can't have impl <T: Into<TypeRow>> From<T> for FTSpec
as we might like.)
Hence I think specific builder functions are the right way to go...
@ss2165 sending this your way because you looked at the original (#1195) from which this was split. Feel free to reassign....
Attention: Patch coverage is 78.37838%
with 8 lines
in your changes missing coverage. Please review.
Project coverage is 86.98%. Comparing base (
c05edd3
) to head (d4d1c4e
).
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Hmmm, I'm starting to think that having a new type BuilderFunctionTypeSpec
(call it FTSpec
or ContainerSpec
or something maybe) with factory methods new_endo(impl Into<TypeRow>)
, new(impl Into<TypeRow>, impl Into<TypeRow>)
, new_fixed_exts(impl Into<TypeRow>, impl Into<TypeRow>, impl Into<ExtensionSet>)
, maybe alsonew_endo_fixed_exts
might be the best way to go. (new_fixed_exts
could also take a FunctionType but taking the three params will require less typing at use sites).
Roughly, we're gonna want to change the builder interface for DFGs, CFGs, and simple-basic-blocks, also non-simple basic blocks + Conditionals + TailLoops (these have an extra row of common inputs), that's gonna be a lot of new methods if we add _endo
and _ft
variants of each one...
Ok, redone with a couple of helper methods. I admit/agree that ft1
and ft2
are extremely terse names...but that is part of the point.... ;-). (foo,)
where foo is a row/type/etc. would be even shorter, but I've not gone there...(I could definitely be persuaded!)
builder::ft2
that takes 2Into<Typerow>
s, and builds a FunctionType with extension delta TO_BE_INFERREDbuilder::ft1
that takes a singleInto<TypeRow>
and makes an endomorphic FunctionType similarlydfg_builder_endo
method that was hinted at by one of the incorrect doc comments, and that infers the delta.