strictyaml icon indicating copy to clipboard operation
strictyaml copied to clipboard

What is the rationale for disabling flow-style arrays?

Open bt2901 opened this issue 5 years ago • 8 comments

The docs/why/flow-style-removed.md outlines the reasonable argument for disabling flow-style mappings:

  • The difference between inline mappings and explicit mappings is confusing.
  • The curly brackets can denote different things when used as a part of complex toolchain. Notably, Django and Jinja use {{stuff-like-this}} for templating; the python itself uses {stuff-like-this}.

However, I cannot help but notice that all of those arguments are related to flow-style mappings and use only them as examples. Meanwhile, all counterarguments are related to the flow-style arrays, not flow-style mappings.

Is there a reason for disallowing inline arrays? I don't think anybody uses square brackets for templating, and the both forms of arrays seem natural for me, and easy to understand.

The inspection of code does not show anything problematic: https://github.com/crdoconnor/strictyaml/blob/3b535705d283bcac667e3bdc59be052d9325b13c/strictyaml/parser.py#L210

It seems easy enough to disallow FlowMappingStartToken while tolerating FlowSequenceStartToken.

bt2901 avatar Aug 22 '19 21:08 bt2901

Sorry to leave this hanging. I should have responded earlier.

Is there a reason for disallowing inline arrays?

The rationale is pretty much the same as for mapping:

  • There's already one, obvious way to represent lists - a dash on each line. I tend to follow the rule of there should be one obvious way of doing things (i.e. the zen of python). This also means that a serializer doesn't have to "think" or be told about whether to represent a list of things using dash notation or flow style - there is only one way of representing a list.

  • Related : a goal of StrictYAML was that it should be viewable and editable by non-programmers. I tend to find that non-programmers get confused by this notation (obvious though it is to programmers).

  • It can be syntactically confusing - especially if you are trying to distinguish strings that have [ and ] vs arrays. I have seen square brackets used for templating as well as several other things that you might want to put in a yaml value.

There are some down sides - notably, that [] is quite a neat way of representing an empty list and for lists that are short it's nice and compact and readable.

crdoconnor avatar Sep 12 '19 18:09 crdoconnor

For me [a, b, c] feels more clean, convenient and obvious than multiline description with dash on each line (at least, for most of my use-cases).

should be viewable and editable by non-programmers

That's fair.

and for lists that are short it's nice and compact and readable.

I don't think it's about length. I think it mainly depends on entries' complexity:

target_numbers:
  - 1
  - 2
  - 3
  - 4
  - 5
  - 6

feels too verbose, but target_numbers: [1, 2, 3, 4, 5, 6] feels natural.

On the other hand,

possible_clients:
  - name: John
    last_name: Doe
    country: US
  - name: Jane
    last_name: Doe
    country: UK
  - name: Hans
    last_name: Smith
    country: DE
  - name: Stas
    last_name: Medvedev
    country: RU

feels OK, while flow-style would be very clunky. (Note that the length of first list is 6, but the length of second one is 4)

Strings occupy middle ground, where both fruits: ['apple', 'banana', 'watermellon'] and

fruits: 
 - apple
 - banana
 - watermelon

look natural.

Maybe some restriction based on type would be reasonable?

bt2901 avatar Sep 16 '19 16:09 bt2901

For me [a, b, c] feels more clean, convenient and obvious than multiline description with dash on each line (at least, for most of my use-cases).

Understood.

For what it's worth, you can achieve much the same effect with the comma separated validator: https://hitchdev.com/strictyaml/using/alpha/scalar/comma-separated/

key: a, b, c

Does this fit your use case?

crdoconnor avatar Sep 16 '19 21:09 crdoconnor

That's great! It does fit my use case, maybe even better than [a, b, c] (even the empty list, I think?).

I suggest you expand on docs/why/flow-style-removed.md and mention comma separated validator as possibly superior alternative to flow-style arrays.

bt2901 avatar Sep 17 '19 10:09 bt2901

Will do, yes. Thanks for the tip.

crdoconnor avatar Sep 21 '19 15:09 crdoconnor

I just got an error related to this issue, because I wrote [], an empty array. I use lists with dashes everywhere, except when I need to write an empty array. All answers on the internet on how to write an empty array in YAML point me to [], which makes StrictYAML perhaps way too strict. I understand if StrictYAML prevents notation which is cryptic or leads to errors, but this is apparently a recommended way how to do something in YAML and it doesn't work. I can't think of another way to write an empty array myself, and I'm quite proficient in both JSON and YAML. Is there any at all?

Update:

I tried speakers: [], speakers: ,, no luck. Obviously things like

speakers:
    -

or

speakers:

end up with a validation error, as this is an array with a single empty string. My schema is an array of 0 to infinity items which are integers.

Update:

I had to rewrite my whole YAML document to use comma-separated integers instead of classic lists. I'm a big fan of StrictYAML, but I don't think this is the best design decision. Perhaps disallowing [1, 2, 3] is correct direction, but I'd keep [] as a shortcut as it's pretty straightforward and widely used. Also I really don't think there's another way how to make a list empty. Let's say you have 30 lists in your document and only 1 is empty, the others you'd like to have with items on separate lines for better readability. I don't think this is currently possible.

honzajavorek avatar Nov 08 '21 19:11 honzajavorek

I came across the same problem as @honzajavorek : there seems to be no good way of representing an empty array using StrictYAML.

Admittedly, I haven't thought much about this... but my favorite solution would be to make an exception to the no-flow-style rule for empty arrays (and maybe empty mappings?). Something like this:

In [1]: import strictyaml

In [2]: strictyaml.load("hello:\n- world").data
Out[2]: {'hello': ['world']}

In [3]: strictyaml.load("hello: [world]").data
FlowMappingDisallowed: While scanning
  in "<unicode string>", line 1, column 8:
    hello: [world]
           ^ (line: 1)
Found ugly disallowed JSONesque flow mapping (surround with ' and ' to make text appear literally)
  in "<unicode string>", line 1, column 9:
    hello: [world]
            ^ (line: 1)

# Currently, this raises FlowMappingDisallowed
In [4]: strictyaml.load("hello: []").data
Out[4]: {'hello': []}

# Currently, this raises YAMLSerializationError: Empty lists are not serializable to StrictYAML unless schema is used.
In [5]: strictyaml.as_document({'hello': []}).as_yaml()
Out[5]: 'hello: []\n'

# Currently, this produces 'hello:\n', which other YAML parsers can't interpret correctly
In [6]: strictyaml.as_document({'hello': []}, strictyaml.Map({'hello': strictyaml.EmptyList()})).as_yaml()
Out[6]: 'hello: []\n'

Sjlver avatar Mar 09 '22 10:03 Sjlver

I might be able to contribute tests and code for this. Let me know if you'd accept a pull request.

Sjlver avatar Mar 09 '22 10:03 Sjlver