# [Python-ideas] Python Object Notation (PyON)

Tue Nov 4 12:09:45 CET 2008

```2008/11/4 Greg Ewing <greg.ewing at canterbury.ac.nz>:
> Zaur Shibzoukhov wrote:
>
>> _p__0=['foo',None]
>> _p__0[1]=_p__0
>> _p__0
>
> It would be nice if it could be made a bit more declarative,
> such as:
>
>  _p__0=['foo',_p__0]
>
> --
> Greg

I implemented a rough version of dumps for fun on sunday, and I
decided to let recursive / mutually recursive object be represented in
this manner.  Here are some examples below.

>>> print dumps([1, 2, 1])
[1, 2, 1]

Recursive objects are represented 'declaratively'

>>> x = [1, 2]
>>> y = [x, 'a', x]
>>> print dumps(y)
sym0 = [1, 2]
[sym0, 'a', sym0]

Mutually recursive objects also:

>>> x.append(y)
>>> print dumps((x, y))
sym0 = [1, 2, sym1]
sym1 = [sym0, 'a', sym0]
(sym0, sym1)

Some examples with dictionaries

>>> d = {'foo': (1, 2)}
>>> print dumps(d)
{'foo': (1, 2)}

>>> d['me'] = d
>>> print dumps(d)
sym0 = {'me': sym0, 'foo': (1, 2)}
sym0

An example with a class

>>> class A(object): pass
...
>>> a = A()
>>> a.my = 'spam'
>>> a.oh = (3, a)
>>> print dumps(a)
sym0 = A(my='spam', oh=(3, sym0))
sym0

Implementing this gave me the idea of extending it to representing
object 'given' some definition. E.g. given that a='hello', then
['hello', 'world'] can be represented as [a, 'world'].

This could be useful as when 'pickling' an object sometimes you end up
pickling a lot of the state of the program, which is not necessary as
you know it will not vary.  Or sometimes you would like to pickle
something 'modulo' some state.  E.g.

>>> print dumps(['hello', 'world'], a='hello')
[a, 'world']

For hashable types, equal objects will be factored:

>>> t = (1, 2)
>>> print dumps(((1, 2), (1, 2)), u=(1, 2))
(u, u)
>>> print dumps((t, (1, 2)), u=(1, 2))
(u, u)

For non hashable types, this is not the case unless the objects are
actually the same object:

>>> l = [1, 2]
>>> print dumps((l, l), mylist=l)
(mylist, mylist)
>>> print dumps((l, [1, 2]), mylist=l)
(mylist, [1, 2])

One last example:

>>> a = 3
>>> b = [1, 2]
>>> class C(object): pass
...
>>> c = C()
>>> c.x = a, b
>>> b.append(c)
>>> print dumps(c)
sym0 = C(x=(3, [1, 2, sym0]))
sym0
>>> c.y={a:b}
>>> print dumps(c)
sym0 = C(y={3: sym1}, x=(3, sym1))
sym1 = [1, 2, sym0]
sym0
>>> print dumps(b)
sym0 = [1, 2, C(y={3: sym0}, x=(3, sym0))]
sym0
>>> print dumps(b, c=c)
[1, 2, c]

--
Arnaud

```