Go 1.2: encoding.TextMarshaler and TextUnmarshaler

1,471 views
Skip to first unread message

Russ Cox

unread,
Jul 16, 2013, 2:59:07 PM7/16/13
to golang-dev
golang.org/s/go12encoding proposes a new mostly-interfaces package named encoding. Values implementing TextMarshaler or TextUnmarshaler would be recognized by the Marshal or Unmarshal of any text-based encoding, such as xml or json, without having to write distinct methods for each possible encoding.

Comments welcome here.

Russ

Kyle Lemons

unread,
Jul 16, 2013, 3:37:00 PM7/16/13
to Russ Cox, golang-dev
w.r.t. the BinaryMarshaler question, we actually do have two packages that render data structures into a binary format, encoding/gob and encoding/binary.  The latter does not provide a mechanism for arbitrary serialization of values, and as such can only en/decode fixed-size values.  Introducing a BinaryMarshaler interface could solve this, if it's a problem we want to solve.


--
 
---
You received this message because you are subscribed to the Google Groups "golang-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-dev+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ingo Oeser

unread,
Jul 16, 2013, 7:04:24 PM7/16/13
to golan...@googlegroups.com
On Tuesday, July 16, 2013 8:59:07 PM UTC+2, rsc wrote:
golang.org/s/go12encoding proposes a new mostly-interfaces package named encoding. Values implementing TextMarshaler or TextUnmarshaler would be recognized by the Marshal or Unmarshal of any text-based encoding, such as xml or json, without having to write distinct methods for each possible encoding.

Would be useful to see a BinaryMarshaler interface proposal side by side. It would help me to imagine, when to use what and what to support for certain custom types.

Both have great use for structures containing public cached/calculated/transformed values. The kind of stuff usually solved by getters and setters in other languages.

Nigel Tao

unread,
Jul 16, 2013, 8:49:20 PM7/16/13
to Russ Cox, golang-dev
On Wed, Jul 17, 2013 at 4:59 AM, Russ Cox <r...@golang.org> wrote:
> golang.org/s/go12encoding proposes a new mostly-interfaces package named
> encoding.

As adg asked on the xml thread, should MarshalText have an
append-style signature?

Russ Cox

unread,
Jul 16, 2013, 8:50:37 PM7/16/13
to Nigel Tao, golang-dev
On Tue, Jul 16, 2013 at 8:49 PM, Nigel Tao <nige...@golang.org> wrote:
As adg asked on the xml thread, should MarshalText have an
append-style signature?

Maybe, although that would be different from all the existing marshalers (json, gob, proto). I lean more toward consistency.

Russ

Andrew Gerrand

unread,
Jul 16, 2013, 8:59:25 PM7/16/13
to Russ Cox, Nigel Tao, golang-dev
Since we're introducing a new API, why not introduce a more efficient one. It gives people impetus to switch to the new approach.




--

David Symonds

unread,
Jul 16, 2013, 9:18:04 PM7/16/13
to Russ Cox, golang-dev
I wonder if it makes sense to merge these two new interfaces into a
single interface with MarshalText and UnmarshalText. If this is indeed
for machine encoding, why not force types to support a round-trip? If
it's really inappropriate, they could always return an error from the
one they don't support, but it seems like it would more likely to be a
mistake to only implement one.

I realise that's different from interfaces we currently have.

Brad Fitzpatrick

unread,
Jul 16, 2013, 9:23:23 PM7/16/13
to David Symonds, Russ Cox, golang-dev
On Wed, Jul 17, 2013 at 11:18 AM, David Symonds <dsym...@golang.org> wrote:
I wonder if it makes sense to merge these two new interfaces into a
single interface with MarshalText and UnmarshalText. If this is indeed
for machine encoding, why not force types to support a round-trip?
 
Probably because a time.Time would be a TextMarshaler but a *time.Time would be a TextUnmarshaler?

Jan Mercl

unread,
Jul 17, 2013, 3:50:11 AM7/17/13
to Kyle Lemons, Russ Cox, golang-dev
On Tue, Jul 16, 2013 at 9:37 PM, Kyle Lemons <kev...@google.com> wrote:
> w.r.t. the BinaryMarshaler question, we actually do have two packages that
> render data structures into a binary format, encoding/gob and
> encoding/binary. The latter does not provide a mechanism for arbitrary
> serialization of values, and as such can only en/decode fixed-size values.
> Introducing a BinaryMarshaler interface could solve this, if it's a problem
> we want to solve.

net.Lookup* underlying functionality (the DNS wire format) could
pehaps also use the binary marshaling interfaces.

-j

roger peppe

unread,
Jul 17, 2013, 10:47:08 AM7/17/13
to Andrew Gerrand, Russ Cox, Nigel Tao, golang-dev
+1

there are likely to be cases where these methods will produce
significant quantities of garbage and it would be nice to
be able to mitigate that.

roger peppe

unread,
Jul 17, 2013, 10:49:02 AM7/17/13
to David Symonds, Russ Cox, golang-dev
I think I'm -1 on this. It's not that uncommon to have types that can
be marshalled but not unmarshalled (I'm thinking textual representations
of internal data objects here where we want *some* representation
of the object, but don't care if it's reversible).

Russ Cox

unread,
Jul 17, 2013, 11:11:41 AM7/17/13
to roger peppe, Andrew Gerrand, Nigel Tao, golang-dev
As far as append is concerned, I am not particularly inclined to break the convention set by json.Marshaler, proto.Marshaler, and gob.GobEncoder. I think there is too much recent focus on micro-optimization like this, and it's a pretty bad reason to introduce inconsistency into an API. If it's really important, we can change them all, together, in Go 2.

Russ

Paul Borman

unread,
Jul 17, 2013, 12:22:42 PM7/17/13
to golan...@googlegroups.com, roger peppe, Andrew Gerrand, Nigel Tao
The encoding package looks like a good addition that should be there, but I do not believe it is sufficient.

I believe it has the same design flaw as the json package.  It places the burden on the package that defines the type.  If the package does not implement this for its types and you want to use them, you may be out of luck.  If the package defines an encoding/decoding that is different from what you need to use, you are out of luck.

The more I have thought about it the more I am convinced that there needs to be a facility to register an external function with an encoding/decoding.  This solves two issues.  First, it allows the use of types from a package that might not have implemented encoding.TextMarshaler / encoding.TextUnmarshaler.  Second, it provides the ability to override the package author's decision if it is inappropriate for your use case.

    -Paul

Russ Cox

unread,
Jul 17, 2013, 12:39:26 PM7/17/13
to Paul Borman, golang-dev, roger peppe, Andrew Gerrand, Nigel Tao
This may be true, but I don't want to add too much in one release, for fear of not having time to understand how it all interacts, both with itself and with the surrounding system.

I'd be happy to think about custom registrations in json and xml in Go 1.3. I created golang.org/issue/5901.

Russ

David Crawshaw

unread,
Jul 17, 2013, 12:47:41 PM7/17/13
to Russ Cox, golang-dev
Given fmt.Stringer has been brought up, should this interface specify
what behaviors are acceptable with []byte? Can the same []byte be
returned by subsequent calls to MarshalText? Can MarshalText modify
and reuse the slice? Is it safe for the caller to modify the slice?
Can UnmarshalText rely on the given []byte to go unchanged by the
caller?

u

unread,
Jul 17, 2013, 2:12:17 PM7/17/13
to golan...@googlegroups.com
+1
Thank your Russ for standing your ground on this.

The first priority should be to create a clean API. If profiling reveals
that this area becomes a bottleneck then different optimizations
techniques can be discussed. Micro-optimizations should not interfere
with high level design decisions.

As the compiler evolves it may be possible to get the same performance
without these kinds of micro-optimizations.

"We should forget about small efficiencies, say about 97% of the time:
premature optimization is the root of all evil" - Donald Knuth

Reply all
Reply to author
Forward
0 new messages