Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fluent: consider deprecating and then removing Reflect APIs in favor of bindnode #337

Open
mvdan opened this issue Jan 20, 2022 · 5 comments
Labels
P3 Low: Not priority right now

Comments

@mvdan
Copy link
Contributor

mvdan commented Jan 20, 2022

bindnode is also implemented via reflection, it has more features (such as using custom Go types), and I believe it supports all the features that these fluent reflect APIs provide.

We should probably deprecate the fluent reflect APIs (n.b. just the "reflect" family, not all of the fluent package) in favor of bindnode, and remove them a couple of releases later.

Before doing any of this, we could be nice and search across PL for users of these APIs, and submit PRs to move them to bindnode.

When we deprecate, we can then also close #212.

cc @warpfork @rvagg

@mvdan
Copy link
Contributor Author

mvdan commented Jan 20, 2022

func Reflect(np datamodel.NodePrototype, i interface{}) (datamodel.Node, error)

This would be replaced by bindnode.Wrap, most of the time.

One quirk is that bindnode represents maps as a keys-values tuple, to maintain map order. The fluent APIs deal with this by sorting keys via Reflector.MapOrder. We should keep this in mind when updating existing bits of code. I imagine that some of them could simply replace a Go map with a Go struct, for instance.

func ReflectIntoAssembler(na datamodel.NodeAssembler, i interface{}) error

I don't imagine many people will be using this today. But one could certainly use bindnode.Wrap with a custom prototype to gain more control.

@warpfork
Copy link
Collaborator

Hm. Sounds potentially legit to me.

I'd like to spend a moment wondering out loud if it will have any effect on maintainability, and performance, feature range, and the library's explanatory effect.

Maintenance: seems neutral: these reflect functions haven't really had any maintenance costs since first penned; bindnode does (at least for now, as it continues to grow in range of what it supports), but it's so unquestionably valuable that those investments are already accounted for before this.

Performance: bindnode is going to spend some time inferring a schema, rather than directly proceeding through the very simple switch table that fluent.Reflect uses. I'm not sure exactly how much that costs. That said... I imagine if one is using these reflect functions at all, one is unlikely to be ranking speed absolute first (these methods have always disclaimed that's not what they prioritize), so, surely it's fine. Also, as bindnode gets performance work, having the results also 'for free' here would seems nice.

Feature range: that's easy, bindnode already eclipses these functions, completely, I think.

Library's explanatory effect: okay, this is in the eye of the beholder; and it also may not be worth prioritizing here. That disclaimer aside: something I appreciate about fluent.Reflect is that it's so simple that it's linearly readable, and could be pointed at as part of learning material about how a developer can mentally map golang types vs the IPLD Data Model. This is probably worth dismissing, though: if we really wanted this to be discoverable and useful as learning material, we can replicate that code in a documentation site or such.

Overall: yep, I can't find any objection.

@warpfork
Copy link
Collaborator

We may want to leave some function stubs even beyond a deprecation period, which redirect to the bindnode behaviors? It may help keep guiding people to the right place if they look in this package for these feature. (go-ipld-prime/node/bindnode, from the package name alone, isn't super likely to jump out at a new user looking for these features.)

On the other hand, such facade and discovery aid functions could just as well belong in the root package, nowaday, too.

@mvdan
Copy link
Contributor Author

mvdan commented Jan 20, 2022

I thought about forwarding APIs as well. We could certainly do that for backwards compatibility in the fluent package. I'm less certain that a top-level reflect API will be a good idea; it's either going to be a copy of the bindnode API, in which case we duplicate, or it's going to be a simplified version, at the cost of either features or performance.

@rvagg
Copy link
Member

rvagg commented Jan 24, 2022

Yeah, I think I'm fine with this. I had an instinctive negative reaction to this but it's mostly about the simple cases, like building data for tests. But mostly I think that's just an aversion to having to introduce types for even the simplest tasks. And also, when you get simple enough you can also just use basicnode, which I think I'd reach for. So no, I don't think I can see myself reaching for the fluent APIs for anything new at the moment.

@BigLep BigLep added the P3 Low: Not priority right now label May 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 Low: Not priority right now
Projects
None yet
Development

No branches or pull requests

4 participants