Hi, Anton,
First of all, let me say that overall I like the Piq syntax and I'm
not saying it itself should somehow modified or replaced. I'm just
making the point that readability and familiarity are very important
when it comes to adoption of new languages.
On Mon, Mar 23, 2015 at 10:08 AM, Anton Lavrik <
ala...@piqi.org> wrote:
> Speaking of
> which, would you rather use 'required', 'repeated', 'optional' keywords
> instead of '?' or '*' ?
Yes, as I mentioned, the symbolic representations seem noisy to me. I
would at the very worst apply them to the *type*:
type person = {
name :: string()
id :: int()
email :: string()? %% or even ?string() --
%% so that it's like a type constructor for
%% an 'option' type.
phone :: phone-number()* %% alt: * phone-number()
}
[In general, the repeated-field concept is, in my opinion, redundant
since it's isomorphic to a list type. I'd rather see lists as
primitive and use custom `.protobuf-*` flags to control the
serialization of fields with list type.]
Otherwise, just spell it out: (Optional string()), (Repeated phone-number()).
> As in LISP, all the benefits and downsides of the Piq syntax come from the
> fact it's abstract. Piq is somewhat unique however. While being abstract, it
> is less verbose than other data representation languages like JSON (but
> surely more verbose than a special-purpose concrete syntax). But best of
> all, as long you don't mind some verbosity, you don't have to think about
> concrete syntax. Designing a good concrete syntax is always a lot more
> difficult than one may think.
I completely agree and understand you here.
> Speaking of future plans for Piqi, I need to stabilize command-line API, add
> support for Protobuf 2.5, 2.6. 3.0, finish the portable RPC spec discussed
> earlier on this list, and release everything as v1. There is also a list of
> things for piqi-erlang and piqi-rpc and I have plenty of ideas of what to do
> after that. The tricky part is finding time.
If you wrote-up / categorised some of the plans (say, on the GitHub
wiki and/or issue tracker), in the future I might be able to
contribute and help you with some of it.
> On a slightly separate topic, in addition to the schema syntax, you seem to
> suggest to use an alternative syntax for representing attributes and default
> values. For instance,
>
> <[ deprecated; erlang-name = "big_number"; ]>
>
> Why do you think it is better than the Piq syntax for that, i.e.
>
> [ .deprecated .erlang-name "big_number" ]
>
> I agree that your's is somewhat more conventional but Piq is also pretty
> natural for anyone who is familiar with command-line options. Don't really
> remember hearing any complains about the Piq syntax.
The lack of an explicit separator means that `.` acts both as a prefix
to denote "name literals" and as a separator of sorts. This leads to
what you document in the docs in "2.13. Associativity control"[1].
For me, parenthesis are either for function application or "do
nothing". The distinction between `.foo .bar` and `.foo (.bar)` is
super confusing and unintuitive. At worst, I would expect the
behaviour of parenthesis to be "make `.foo` act as a constructor" and
writing `(.foo .bar)` to mean "Constructor .foo is _applied_ to the
_value_ .bar". However, such syntax is already reserved for repeated
name values, hence making the situation even more confusing.
So that's why I used (without really thinking about it) an alternative
syntax in the example, though it would probably make much more sense
to use just raw Piq syntax.
The allegory with command-line args/flags makes sense and it actually
provides a sane interpretation of `.foo (.bar)` (i.e. you read it as
-foo ".bar", so the value in parenthesis effectively becomes
"quoted"), but that's not what I'm thinking about when I write data
specifications! Perhaps the situation could also be improved by
mentioning very early on in the documentation that this is how you
should read the Piq syntax. The idea of 'quoting' does not really fit
in with the repeated name values syntax.
> To evaluate which representation is better, just compare them side by side.
> Here's a quick example of Piq and two more conventional syntax approaches:
>
> <..>
>
> As for me, such readability gain is
> marginal. On the other hand, you need to introduce at last one more lexical
> symbol for element separators. In theory, you could make separators optional
> but it can hurt readability when abused which defeats the reason for adding
> them in the first place. So to make it robust, you'd have to make such
> separators mandatory or maybe create some rules when they can be omitted,
> e.g. at the end of the line.
Once again, arguing about syntax is mostly futile, I too don't see
that much of a difference between the variants. I am mostly arguing
for improving familiarity among people who are newcomers to Piqi and
are used to the standard denotations of "assigning a value 'x' to a
field named 'a'".
That is, except for the separator part which I already mentioned as
problematic -- avoiding separators where they truly make sense is a
somewhat mysterious trend in computer languages I keep seeing.
> There's more to it. Unlike in Piq, you now don't have a good visual way of
> distinguishing between words in a quoted string, unquoted strings and
> symbols/atoms. So you use a different quoting style for atoms, e.g. 'work'
> and 'mobile'. You can probably get away with `work and `mobile as well, but
> it is way less conventional. And you obviously can't reuse any of ,.: for
> quotation, to avoid similarity with the separators.
Right, but -- if I understand this argument correctly -- on the
flipside you have the problem I described before with `.` acting
(implicitly) as a separator. I would actually see no problem with
explicitly denotating atoms -- I like it when the syntax makes the
data type explicit (instead of having it inferred by its usage).
> Now, not only you've added more lexical elements, but you made (label :
> value) or (label = value) pairs look substantially different from just
> 'label' without a value. Yet, such labels are very close in nature
> regardless of whether they come with or without values. Not pretty. To
> overcome this, you may always require labels to come with values, e.g.
> (mobile: true) or (mobile = true). However, in this case, you'd actually
> have to write (phone-type: mobile) instead. Ha-ha.
I don't really follow this argument. What is the use of a label
without a value? If it's a flag, it's implicitly always a boolean. If
it's an atom, it can be denoted as an atom?
Sorry for the wall-of-text that I'm producing here -- just trying to
synthesize my thoughts and give you some constructive feedback during
the process. I have some obscure plans for using Piqi as a backend for
a thing-I-might-build and so I'm re-evaluating all aspects of it. Piqi
is still by far the best data/interface-speification+serialization
infrastructure-thing out there (IMHO, hah) and I'm thinking on how to
make it even better :)
--
Ignas
[1]:
http://piqi.org/doc/piq/#associativitycontrol