Proposal for new operators to python that add syntactic sugar for hierarcical data.

G

glomde

i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier and that resulting code would be
more readable than how you write today with packages like elementtree
and xist.
I dont want to replace the packages but the packages could be used with
the
new operators and the resulting IMHO is much more readable.

The syntax i would like is something like the below:

# Example creating html tree

'*!*' is an operator that creates an new node,
'*=*' is an operator that sets an attribute.

So if you take an example to build a smalle web page
and compare with how it looks with in element tree now
and how it would look like when the abover operators would exist.

With element tree package.

# build a tree structure
root = ET.Element("html")
head = ET.SubElement(root, "head")
title = ET.SubElement(head, "title")
title.text = "Page Title"
body = ET.SubElement(root, "body")
body.set("bgcolor", "#ffffff")
body.text = "Hello, World!"



With syntactical sugar:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"



I think that with the added syntax you get better view of the html
page.
Repeating things dissapears and you get indentation that corresponds to
the tree.
I think it is very pythonic IMHO.

It could be done quite generic. If the variable, object after '*!*'
must support append
method and if you use '*=*' it must support __setitem__

Any comments?
 
G

George Sakkis

glomde said:
i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier and that resulting code would be
more readable than how you write today with packages like elementtree
and xist.

Given that python doesn't have syntactic sugar for something as
prevalent as regular expressions, it's not that hard to predict the
luck of this proposal. Good luck pushing it forward.

George
 
D

Diez B. Roggisch

glomde said:
i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier and that resulting code would be
more readable than how you write today with packages like elementtree
and xist.
I dont want to replace the packages but the packages could be used with
the
new operators and the resulting IMHO is much more readable.

The syntax i would like is something like the below:

# Example creating html tree

'*!*' is an operator that creates an new node,
'*=*' is an operator that sets an attribute.

So if you take an example to build a smalle web page
and compare with how it looks with in element tree now
and how it would look like when the abover operators would exist.

With element tree package.

# build a tree structure
root = ET.Element("html")
head = ET.SubElement(root, "head")
title = ET.SubElement(head, "title")
title.text = "Page Title"
body = ET.SubElement(root, "body")
body.set("bgcolor", "#ffffff")
body.text = "Hello, World!"



With syntactical sugar:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"



I think that with the added syntax you get better view of the html
page.
Repeating things dissapears and you get indentation that corresponds to
the tree.
I think it is very pythonic IMHO.

It could be done quite generic. If the variable, object after '*!*'
must support append
method and if you use '*=*' it must support __setitem__

Any comments?

It's ugly, and could easily achieved using the built-in tupels, lists
and dictionaries together with a simple traversing function.

Like this (untested):

class Node(object):
def __init__(self, value):
self.value = vallue
self._childs = []
def append(self, child):
self._childs.append(child)


t = ('root',
('child1,
('grandchild', ()),
'child2',
()
)
)

def create_node(t):
value, childs = t
n = Node(value)
if childs:
for ch in childs:
n.append(create_node(ch))
return n


IMHO that tuple-based tree is waaay more readable than your proposal -
and no need to come up with new syntax.

Diez
 
B

Ben Finney

glomde said:
With element tree package.

# build a tree structure
root = ET.Element("html")
head = ET.SubElement(root, "head")
title = ET.SubElement(head, "title")
title.text = "Page Title"
body = ET.SubElement(root, "body")
body.set("bgcolor", "#ffffff")
body.text = "Hello, World!"



With syntactical sugar:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"

We already have syntax for building hierarchical data structures:
lists and/or tuples. If you want to define Node and Attribute classes,
you can already do so without adding new syntax.
I think that with the added syntax you get better view of the html
page.

I think indenting our existing data type syntax can do the same thing:

root = Node("html", children=[
Node("head", children=[
Node("title", children=[
"Page Title",
])
]),
Node("body", children=[
Attribute("bgcolor", "white"),
"Hello, World!",
]),
])

Set up the __init__ for those classes to do whatever you would have
done with the syntax you proposed.
Repeating things dissapears and you get indentation that corresponds
to the tree.
Indeed.

I think it is very pythonic IMHO.

Adding new punctuation to deal with a particular type is extremely
un-Pythonic.
 
S

Scott David Daniels

glomde said:
i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier ...
With syntactical sugar:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"

Hunt up PyYAML. It might be what you want.

--Scott David Daniels
(e-mail address removed)
 
G

glomde

There are some difference which are quite essential.

First of all I dont se how you set attributes with that and
then I dont see how you can mix python code with the creation.

So how do you do this:

root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
for i in sections:
!*! section():
*=*Text = section
 
G

glomde

But you cant mix python code in there when creating the nodes.
That is when it gets quite ugly an unreadable according to me.

But I also relly do think that this:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"

Especially if you start having deeper hierachies like. But the big
other plus is that you can
have any python code in beetween.
 
G

glomde

Actually we did start of with YAML, but realised that we need to have
the power
of a programming language aswell. But I wanted to come up with
something that looked
very clos to YAML since I find it quite readable.

I have implemented the syntax, but as a preprocessor for python and it
works quite nice.

Cheers,

T
 
D

Diez B. Roggisch

glomde said:
There are some difference which are quite essential.

First of all I dont se how you set attributes with that and

Use dicts as childs.
then I dont see how you can mix python code with the creation.

You can put any python expression in there, and in the Node class you can do
what you want.

Seems that you are after a templating-system. Well, there are plenty of them
available, including yours. A preprocessor is nothing but a template system
- see TurboGears-utilized KID (http://kid.lesscode.org/) for example, it
generates python files. And way more readable, because you are working in
the domain of your application (HTML) instead of some crude syntax that is
neither fish or flesh.

Counterquestion: how do you create this:

<?xml version='1.0' encoding='utf-8'?>
<?python
from urllib import urlopen
from elementtree.ElementTree import parse, tostring
feed = 'http://naeblis.cx/rtomayko/weblog/index.atom'
root = parse(urlopen(feed)).getroot()
ns = '{http://purl.org/atom/ns#}'
title = root.findtext(ns + 'title')
?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://purl.org/kid/ns#">
<head>
<title py:content="title" />
</head>
<body bgcolor="blue" text="yellow">
<h1 py:content="title" />
<table cellpadding="4" cellspacing="4">
<tr py:for="i, entry in enumerate(root)"
py:if="entry.tag == ns + 'entry'">
<td py:attrs="bgcolor=('white', 'yellow')[i % 2]">
<a py:attrs="href=entry.find(ns + 'link').attrib['href']"
py:content="entry.findtext(ns + 'title')" />
</td>
</tr>
</table>
</body>
</html>


Diez
 
G

Gerard Flanagan

glomde said:
i I would like to extend python so that you could create hiercical
[...]

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"



I think that with the added syntax you get better view of the html
page.
Repeating things dissapears and you get indentation that corresponds to
the tree.
I think it is very pythonic IMHO.

It could be done quite generic. If the variable, object after '*!*'
must support append
method and if you use '*=*' it must support __setitem__

Any comments?

I personally dislike the nested-indented-brackets type of code given in
other replies, and i think your suggestion has a certain appeal - 'What
you see is what you mean' . But it's not Python.

You also repeat yourself: head("head"), title("title"), body("body")

What about this:

# build a tree structure
root = ET.Element("html")
!root
!head
!title
if A is True:
&text = "Page A"
else:
&text = "Page B"
!body
&bgcolor = "#ffffff"
&text = "Hello, World!"

mmm...yamlthon? yython...:)

All the best

Gerard
 
B

bruno at modulix

glomde said:
i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier and that resulting code would be
more readable than how you write today with packages like elementtree
and xist.
I dont want to replace the packages but the packages could be used with
the
new operators and the resulting IMHO is much more readable.

The syntax i would like is something like the below:

# Example creating html tree
'*!*' is an operator that creates an new node,
'*=*' is an operator that sets an attribute.
(snip)

With syntactical sugar:

# build a tree structure
root = ET.Element("html")
*!*root:
*!*head("head"):
*!*title("title):
*=*text = "Page Title"
*!*body("body"):
*=*bgcolor = "#ffffff"
*=*text = "Hello, World!"

What about using <XXX>data</XXX> for nodes and '=' for attributes ?
Would look like:

<html>
<head>
<title>Page Title</title>
</head>
<body bgcolor='#ffffff'>
Hello World
</body>
I think that with the added syntax you get better view of the html
page.

indeed !-)
 
A

Alan Kennedy

[glomde]
i I would like to extend python so that you could create hiercical
tree structures (XML, HTML etc) easier and that resulting code would be
more readable than how you write today with packages like elementtree
and xist.
Any comments?

Yes: it's ugly and unnecessary.

Why would you want to change the language syntax just to make it easier
to express markup directly in program code? Javascript just made that
mistake with E4X: IMHO, it makes for some of the ugliest code. E4X
reminds me of that Microsoft b*stardisation, XML Data Islands.

http://www.w3schools.com/e4x/e4x_howto.asp
http://en.wikipedia.org/wiki/E4X

For a nice pythonic solution to representing markup directly in python
code, you should check out stan.

http://divmod.org/users/exarkun/nevow-api/public/nevow.stan-module.html

Here's a nice stan example, taken from Kieran Holland's tutorial

http://www.kieranholland.com/code/documentation/nevow-stan/

aDocument = tags.html[
tags.head[
tags.title["Hello, world!"]
],
tags.body[
tags.h1[ "This is a complete XHTML document modeled in Stan." ],
tags.p[ "This text is inside a paragraph tag." ],
tags.div(style="color: blue; width: 200px; background-color:
yellow;")
[
"And this is a coloured div."
]
]
]

That looks nice and simple, and no need to destroy the elegance of
python to do it.

regards,
 
G

glomde

You can put any python expression in there, and in the Node class you can do
what you want.

But the main advantage is any python code not only expressions. In
addition to that
you get nice flow style. Can set variables which you later use as want.
Seems that you are after a templating-system. Well, there are plenty of them
available, including yours. A preprocessor is nothing but a template system
- see TurboGears-utilized KID (http://kid.lesscode.org/) for example, it
generates python files. And way more readable, because you are working in
the domain of your application (HTML) instead of some crude syntax that is
neither fish or flesh.

What I propose is for all data that is hierarcical. Not only HTML. I
dont use it for creating html. Templating systems have the drawback IMO
that the more code you get the more undreadable it gets. If the code
part is small they are very nice.

The other part is that indentation, syntax highlighting and so on works
not so well when working with such code.


I would translate your example to the below. Which I think is much more
readable, since you see the python code flow much easier. I realised
that you realy should do Element("html") and not html("html") when
adding nodes in my syntax and using elementtree.

from urllib import urlopen
from elementtree.ElementTree import parse, tostring
feed = 'http://naeblis.cx/rtomayko/weblog/index.atom'
root = parse(urlopen(feed)).getroot()
ns = '{http://purl.org/atom/ns#}'
title = root.findtext(ns + 'title')

root = ET.Element("html")
*+* root:
*+* Element("head"):
*+* Element("title")
*+* Element("body"):
*=* bgcolor = "blue"
*=* text = "yellow"
*+* Element("table"):
*=* cellpadding="4"
*=* cellspacing="4"
for i, entry in enumerate(root):
*+* Element("tr"):
if entry.tag==ns + 'entry':
*+* Element("td"):
*=* bgcolor = ('white', 'yellow')[i %
2]
*+* Element("a"):
*=* href = entry.find(ns +
'link').attrib['href']
*=* text = "entry.findtext(ns +
'title')"


With the above you can use your favorite editor to do the coding and
get indentation, syntax highlightning and so on. Which I find can be
quite a burden with a templating system especially the more code that
is in there.

It is also easier to debug in comparison when using a templating system.
 
G

glomde

You also repeat yourself: head("head"), title("title"), body("body")
What about this:

# build a tree structure
root = ET.Element("html")
!root
!head
!title
if A is True:
&text = "Page A"
else:
&text = "Page B"
!body
&bgcolor = "#ffffff"
&text = "Hello, World!"

Yes this is how it should be. But It depends on which package would be
used. If you used xist it would look like that since they have one
class for each html tag. I really propose
a generic solution that any package that support the method append and
__settiem__
could use the new syntax.

But minor isssues but it would look something like this with xist:

!root
!head():
!title():
if A is True:
&text = "Page A"
else:
&text = "Page B"
!body()
&bgcolor = "#ffffff"
&text = "Hello, World!"


mmm...yamlthon? yython...:)
Guess what I have for suffix on the files before preprocessing?
.....pyml ofcourse.
 
G

glomde

What about using said:
Would look like:

<html>
<head>
<title>Page Title</title>
</head>
<body bgcolor='#ffffff'>
Hello World
</body>


indeed !-)

I dont think it is very pythonic :). You dont use endtags and then you
dont use ':' to
mark that you nest a level. :)
And I dont see where it is allowed to put real python code.
So could you show an example with a for loop? :)
 
G

glomde

Here's a nice stan example, taken from Kieran Holland's tutorial

I took a quick look and it looks nice as long as your page is static.
But I couldnt
se how you could mix in python code seamlessy when creating your tree.

But I might be wrong if you could write:

tags.body[
for i in range(10):
tags.h1[ "Heading %s." %(i) ],
tags.p[ "This text is inside a paragraph tag." ],
]

I think that this is close enough to my syntax. But I dont think you
can do it.
 
B

bruno at modulix

glomde said:
I dont think it is very pythonic :).

Adding ugly and unintuitive "operators" to try to turn a general purpose
programming language into a half-backed unusable HTML templating
language is of course *much* more pythonic...

I think you would have much more success trying to get this added to
Perl !-)
 
H

Heiko Wundram

Am Donnerstag 18 Mai 2006 13:27 schrieb bruno at modulix:
Adding ugly and unintuitive "operators" to try to turn a general purpose
programming language into a half-backed unusable HTML templating
language is of course *much* more pythonic...

What about writing a mini-language that gets translated to Python? Think of
Cheetah, which does exactly this (albeit not being limited to templating HTML
data).

Adding these kind of operators to Python is an absolute NoNo, because it's
nothing general the OP is trying to achieve here. Creating a small wrapper
language: why not? (it's not that we have enough templating languages
already ;-))

By the way: the language you (the OP) are trying to implement here goes
strictly against the MVC model of application programming. You know that,
right?

--- Heiko.
 
G

glomde

Adding ugly and unintuitive "operators" to try to turn a general purpose
programming language into a half-backed unusable HTML templating
language is of course *much* more pythonic...

IT is not only for HTML. I do think html and xml are the biggest
creators of
hierarcical treestructures. But it would work for any package that
manipulates,
creates hierarchical data. I used HTML as example since it is a good
example and
most people would understand the intention.

But could you elaborate on your comment that it is unusable. Do you
think all template systems are unusable or what is the specific reason
you think what i propose is unusable?

IMO it is a mix between yml and python. Yml has the advantage that it
can be read by many programming languages but the disadvantage is that
it is static.
 
G

glomde

What about writing a mini-language that gets translated to Python? Think of
Cheetah, which does exactly this (albeit not being limited to templating HTML
data).
I have implemented my proposal as preprocessor. And it works fine. But
my
proposal in not only for HTML it can be used for all hieracical data.
Example:

myList = []
*+* myList:
*+* []:
for i in range(10):
*+* i
*+* {}:
for i in range(10):
*=* i = i
Which should create myList = [[0..9], {0:0, ... 9:9}]

So it adds the power of for loops etc when creating data structures.
ANY datastructure.
> nothing general the OP is trying to achieve here
Define general :). I do think I solve something and make it more
readable.
You could also argue that list comprehension doesnt solve anything
general.
By the way: the language you (the OP) are trying to implement here goes
strictly against the MVC model of application programming. You know that,
right?

???. I cant see how this breaks MVC. MVC depends on how you parition
your application
this doesnt put any constraint on how you should do your application.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top