Commit ce94db1f authored by Eric Myhre's avatar Eric Myhre

Expose styles with nicer syntax.

I'm not sure if there's a name for this way of grouping methods,
but the end result is dotted.Access.Patterns, and it's kinda nice.

This was extensively discussed in the PR:

https://github.com/ipld/go-ipld-prime/pull/49#issuecomment-596465234
https://github.com/ipld/go-ipld-prime/pull/49#issuecomment-597549108
https://github.com/ipld/go-ipld-prime/pull/49#issuecomment-604412736

The "inlinability_test.go" file can be compiled with special flags
(described in the comment at the top of the file) to see the
outcome in assembly.  Result?  Yep, things are still inlinable;
this change is performance neutral.
parent de201f2d
...@@ -105,14 +105,41 @@ Note that these remarks are for the `basicnode` package, but may also ...@@ -105,14 +105,41 @@ Note that these remarks are for the `basicnode` package, but may also
apply to other implementations too (e.g., our codegen output follows similar apply to other implementations too (e.g., our codegen output follows similar
overall logic). overall logic).
### nodestyles are implemented as exported concrete types ### nodestyles are available through a singleton
This is sorta arbitrary. We could equally easily make them exported as Every NodeStyle available from this package is exposed as a field
package scope vars (which happen to be singletons), or as functions in a struct of which there's one public exported instance available,
(which happen to have fixed returns). called 'Style'.
These choices affect syntax, but not really semantics. This means you can use it like this:
In any of these cases, we'd still end up with concrete types per style ```go
(so that there's a place to hang the methods)... so, it seemed simplest nbm := basicnode.Style.Map.NewBuilder()
to just export them. nbs := basicnode.Style.String.NewBuilder()
nba := basicnode.Style.Any.NewBuilder()
// etc
```
(If you're interested in the performance of this: it's free!
Methods called at the end of the chain are inlinable.
Since all of the types of the structures on the way there are zero-member
structs, the compiler can effectively treat them as constants,
and thus freely elide any memory dereferences that would
otherwise be necessary to get methods on such a value.)
### nodestyles are (also) available as exported concrete types
The 'Style' singleton is one way to access the NodeStyle in this package;
their exported types are another equivalent way.
```go
basicnode.Style.Map = basicnode.Style__Map{}
```
It is recommended to use the singleton style;
they compile to identical assembly, and the singleton is syntactically prettier.
We may make these concrete types unexported in the future.
A decision on this is deferred until some time has passed and
we can accumulate reasonable certainty that there's no need for an exported type
(such as type assertions, etc).
// Compile with '-gcflags -S' and grep the assembly for `"".Test`.
// You'll find that both methods produce identical bodies modulo line numbers.
package inlinability
import (
"testing"
ipld "github.com/ipld/go-ipld-prime"
basicnode "github.com/ipld/go-ipld-prime/node/basic"
)
var sink ipld.NodeBuilder
func TestStructReference(t *testing.T) {
nb := basicnode.Style__String{}.NewBuilder()
sink = nb
}
func TestVarReference(t *testing.T) {
nb := basicnode.Style.String.NewBuilder()
sink = nb
}
package basicnode
// Style embeds a NodeStyle for every kind of Node implementation in this package.
// You can use it like this:
//
// basicnode.Style.Map.NewBuilder().BeginMap() //...
//
// and:
//
// basicnode.Style.String.NewBuilder().AssignString("x") // ...
//
// Most of the styles here are for one particular Kind of node (e.g. string, int, etc);
// you can use the "Any" style if you want a builder that can accept any kind of data.
var Style style
type style struct {
Any Style__Any
Map Style__Map
List Style__List
Bool Style__Bool
Int Style__Int
Float Style__Float
String Style__String
Bytes Style__Bytes
Link Style__Link
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment