Alternatives to XML?

Chris Angelico rosuav at gmail.com
Thu Aug 25 06:07:28 EDT 2016


On Thu, Aug 25, 2016 at 5:13 PM, Frank Millman <frank at chagford.com> wrote:
> "Chris Angelico"  wrote in message
> news:CAPTjJmof_sXqax0Ury5LsBEj7cdFv92WiWKbfvAC+bM=HwtHXA at mail.gmail.com...
>
>> Sounds to me like you have two very different concerns, then. My
>> understanding of "GUI" is that it's a desktop app running on the user's
>> computer, as opposed to some sort of client/server system - am I right?
>
>
> Not exactly, but the difference in not important, as you have got the
> essentials below spot on.

Cool. The essential difference, in this case, being where the edits
are happening.

> Absolutely. If an organisation running my system wants to be secure, they
> should keep the server in a locked room only accessible by a trusted system
> administrator.

Right. That saves a ton of effort for you - it's no longer about
malicious users.

>> Here's a very simple format, borrowing from RFC822 with a bit of Python
>> added:
>
>
> if: _param.auto_party_id != None
>    if: on_insert
>        value: =auto_gen(_param.auto_party_id)
>    elif: not_exists
>        value: <new>
>
> Getting close, but it is not *quite* that simple.
>
> For example, having isolated the LHS of the if clause, I process it
> something like this -
>
> if source.startswith("'"):
>    source_value = source[1:-1]

I don't like this; if you're going to surround strings with quotes,
you either need some sort of escaping mechanism, or disallow the same
quote character from coming up inside. (At very least, demand that the
string ends with an apostrophe too, or you'll have a lot of VERY
confusing failures if someone omits the closing apostrophe. Make it an
instant error instead.)

> elif '.' in source:
>    source_objname, source_colname = source.split('.', 1)
>    source_record = caller.data_objects[source_objname]
>    source_value = source_record.getval(source_colname)

Fair enough; your dot notation is restricted to "this column from this
thing", where a thing effectively identifies a table. Though I'm
beginning to get the idea that the snippet you're showing here has
elided all error checking - assuming that you actually do have that
checking in the real version.

> elif source == '$None':
>    source_value = None
> elif source == '$True':
>    source_value = True
> elif source == '$False':
>    source_value = False

If you're looking for specific strings, you shouldn't need to adorn
them. Point of note: "None" is a peculiarly Python concept, so anyone
who's using it is going to need to understand its semantics from a
Python perspective. If None is significant to your code, it's probably
semantically important, and that might cause issues if anyone doesn't
know code. And if everyone who edits this file knows Python, well,
we're back to "why not just let them write in Python".

> elif source.startswith('int('):
>    source_value = int(source[4:-1])

Hrm. This is where I'd move away from Python syntax. If you're only
allowing a scant few typecasts, I'd go instead for an SQL-like syntax
eg "some_value::int", or switch it around as "int::some_value", and
make it clearly NOT a function call. Otherwise, I'd have a very simple
"drop to Python" mode, which would be handled something like this:

elif source.startswith("="):
    source_value = eval(source[1:])

> Anyway, you have isolated the essential issue. I need a DSL which is easy
> for a non-technical user to read/write, and easy to verify that it is
> achieving the desired result.

Yes; or, if not easy to verify the result, at least make it easy to
verify the syntax, even in the face of errors.

> I suspect that this is quite challenging whatever format I use. Up to now I
> have been using XML, and it works for me. As Rob pointed out, I have become
> too comfortable with it to be objective, but no-one has yet convinced me
> that the alternatives are any better. I may eventually end up with an
> additional layer that prompts the user through their requirement in 'wizard'
> style, and generates the underlying XML (or whatever) automatically.

That's one option. At that point, the storage format becomes opaque to
humans - it's just an interchange format between two programs. As
such, I would advocate the use of JSON.

Of course, you still need to build that UI, which is a lot of work.
You'll also have to have GUI controls on your wizard for every
possible option, which makes options very expensive (in contrast to a
textual language, in which options are far cheaper) - every user has
to see every option every time. So you have to strike a *very* careful
balance between expressiveness/power and simplicity, and it's entirely
possible to fall down on both fronts.

ChrisA



More information about the Python-list mailing list