Hi, HCL was one of the source of inspiration. We wanted to push it 1 step further by providing a clear and open specification which allows to create parsers for languages other than go.
So the main differences are the ecosystem: a CLI to auto format - think go fmt) and validate SAN files, parsers for languages others than Go
Yes,
The problem is that we want a pure data configuration format.
We think that very few application require a full turing complete language for their configuration.
Bazel have too it's own (turing complete ?) Programming configuration language
Bazel's language (https://github.com/bazelbuild/starlark), also used in Buck and other tools, is technically not Turing-complete. In Bazel's BUILD files, there are additional restrictions (e.g. no function definition), making them relatively declarative and tool-friendly.
Could you be more explicit as why you think TOML is not good enough?
I used to think YAML was the greatest thing until I saw the spec and what was actually allowed. And then I sort of moved onto TOML, and now I'm curios, maybe TOML too has showstopping issues :)
My comment was actually prompted by looking at Json5 features and thinking that I'm not really bothered about any of those other features. I'd just like JSON to have comments.
Hi, the main concern with your solution is that it does not support auto format (think go fmt).
While adding braces and not being indentation based allow auto format and large file to be read more easily
Curly braces are not that unfriendly - people use parentheses in common text all the time, and curly braces are not that different. Perhaps the concept of a "block" or scope is a bit unfriendly but that's independent of syntax... and arguably, curly braces make that more explicit.
Meanwhile, with significant whitespace, non-developers have to learn to be aware that a syntactic element intended to mean nothing now suddenly means something, and that one type of whitespace means something different than another and that they can't be used together, which is counter-intuitive.
Hi, HCL was one of the source of inspiration. We wanted to push it 1 step further by providing a clear and open specification which allows to create parsers for languages other than go.
It does look very similar to a language I wrote: https://github.com/Keats/scl although SCL supports files inclusions and environment variables out of the box.
I would definitely change the supposed pronunciation though, no one is going to pronunce san as sane.
This looks great. I love the strictness and improvements over JSON and also the goal of preserving comments. The absence of specified a date type feels like a back compared to TOML though. Without this they end up as strings in all manner of formats.
An application should reject anything not in its expected format. I would not want to be boxed into the limits of the configuration format's date and time representations. For example, TOML accepts datetimes with fixed offset time zones, but not time zone designators with multiple offsets, like America/New_York.
I'm not sure I buy that it's a large improvement over TOML -- In practice I haven't found the homogeneous list requirement to be an issue, and I really appreciate toml's writing styles and the use of sections to clearly delineate.
I think TOML is still my favorite (especially in terms of readability) but SAN looks awesome
Interesting, but the first thing I checked was if it allows list elements to have different types. And it doesn't.
That was one issue I had with TOML, because the allowed data schema is not JSON compatible. Switching from YAML or JSON to TOML or SAN is therefore often difficult and as such easier to just stay with the one that is currently used.
For new projects, it might be nice. But having to work around this limitation when you need it is also a bit annoying.
For me a configuration file should be easy to write and read while not taking so much care about the data types.
So for me you get a shoe if you reverse your argument. Type limitations aren't improving write or readability IMO and just make it harder, because you have to think about using the right type. Application specific schema checkers should take care of the checking the type.
I think we need to start distinguishing between data formats and configuration formats. JSON is a data format. I loathe working with NodeJS because of the necessity of hand-editing JSON, and that just makes me want to bash my head against the wall.
In my side projects, generally I'll hand-write a parser with regular expressions because I haven't yet found one I actually like both looking at and editing. I can fix every single other problem except that one. With SAN, the issue is the bracket delimiters. I hate futzing with them, just let me use tabs. I want this:
This is easy to look at, easy to edit with a text editor, and, once the parser's written, dead simple with Ruby POROs, easy to parse into queryable data structures.
I have yet to find any format that's intended to be human-editable that doesn't actually feel 'nice to the touch'. So I just make my own.
When hand-editing the format above, I generally don't type in a whole line at a time. I'll just add in the basics, and fill it out later, perhaps with machine processing. Tags in particular are easy to copy-paste in by hand and are generally the last part of the line.
With a data format, you need auto-format, you have no idea what shape it's going to be in and it has to handle arbitrary everything. With a configuration format, you want a highly consistent structure, the machine should be able to output it just with print statements.
If my configuration needs auto-formatting, something's gone very very wrong in the design of my application.
I have used YAML and JSON and I loathe them both for reasons that are probably well known to many. I have, however, not used TOML - so I would very much like to hear the viewpoint of someone who has. If you use TOML today, do you see SAN as valuable? Why exactly?
I am now going to propose the key-value-inline-notation: KVIN. If JSON is that kid in the early '90s who had a l33t 286, then KVIN is JSON's older, iRoc driving brother. KVIN has a 'stache that all the girls love. (It's a little thinner than Magnum P.I.s 'stache, right now.)
A KVIN file follows one simple pattern: it's a list of key-values or comments. Comments are any line that starts with any amount of whitespace and then a '#'. A key-value starts with a key, ends with a value, and has a '=' in the middle:
key = value
A key is made up of any valid C-identifier or C-numeric expression. You can 'chain' keys together with '.'s:
A value is any valid c-identifier, c-number, or "byte string". A byte string starts with a '"', ends with a '"'. If you want to include a '"' then you have to escape with a '\'. If you want to include a '\', then you '\' the '\'. All whitespace is included in a byte-string: even a '\n'!
Strangely, KVIN understands relative paths. If a key starts with '.' then that means it's relative to the path just above it. Each '.' means 'go up one level from the last value':
foo.bar = 0
.baz = 2
Would be a JSON like this:
{ "foo" : { "bar" : 0, "baz" : 2 } }
KVIN has one final trick, besides the busted old turbo he's been trying to get in his iRoc: he knows how to autonumber a list:
foo.10 = a
.# = b
.# = c
.# = d
Which would be the JSON:
{ "foo" : [ ..., a, b, c, d ] }
With 'a' starting at index '10'. (The base index of arrays is 0.)
I've got code laying around, somewhere, that implements KVIN.
- a clean syntax and data model
- easy to parse and use
- friendly to human
- improving on JSON
SAM vs. Mark Notation
- SAM is primarily for configuration data
- Mark can be used for both configuration and mixed content (like HTML, XML)
- SAM is pure data (no templating)
- Mark is also designed for templating, e.g. Mark Template
I'll have a weird fondness for the special kind of bikesheding configuration languages invite.
To add my 2 cents. I really like what I saw in Skylark(Starlark?). It's fairly close to my dream setup: a simple Python interpreter with no libraries.
Pythons object notation looks 95% like JSON, it supports comments, solid multiline support, well known escaping rules, basic format strings when you need them.
65 comments
[ 9.2 ms ] story [ 1124 ms ] threadWe've created a new file format designed specifically for configuration: SAN (pronounce /seɪn/ like sane).
You can find a Go parser here: https://github.com/phasersec/san-go
Vim syntax here: https://github.com/z0mbie42/vim-san
SAN was created because of a need to have a Simple And Neat configuration format (with comments, unlike JSON, easy to parse unlike YAML....).
The main killer features compared to YAML/TOML are the following:
* Comments as first class citizens which means programs can manipulate and modify files with comments without destroying them.
* Safe
* Human and parser friendly
* Easy to use, even without syntax coloration
It's an open format and any feedback is welcome.
So the main differences are the ecosystem: a CLI to auto format - think go fmt) and validate SAN files, parsers for languages others than Go
Bazel have too it's own (turing complete ?) Programming configuration language
I'm a little bummed I was beat to it. I was going back and forth on allowing defining functions. Definitely no classes.
>Comments as first class citizens which means programs can manipulate and modify files with comments without destroying them.
>Safe
>Human and parser friendly
>Easy to use
Those were also my goals with StrictYAML: http://hitchdev.com/strictyaml
No, absolutely not.
I would never unleash a curly braces syntax on a non-developer. And if it's a format for developers then there are already plenty of options.
Furthermore, how would you explain to a non developer that ``` a: b: nested ```
is different than: ``` a: b: non nestee ```
Meanwhile, with significant whitespace, non-developers have to learn to be aware that a syntactic element intended to mean nothing now suddenly means something, and that one type of whitespace means something different than another and that they can't be used together, which is counter-intuitive.
I think there's a touch of Stockholm syndrome in your belief otherwise. You have been corrupted and are projecting "intuitive" on to the pure. ;-)
+1 for quoting all strings
+1 for comments
-1 for the pronunciation hehe :P
I don't like that map values don't need commas while arrays do, and also don't know how I feel about the equal sign instead of colon.
Great attempt overall. Thank you.
I've opened an issue https://github.com/astrocorp42/san/issues/12
I hope this gains traction, so that I could use it in my projects without people being upset about "some obscure configuration language".
The second point is acknowledged
Can I ask you why?
I will explore this.
I would definitely change the supposed pronunciation though, no one is going to pronunce san as sane.
Tabs would be more sane for indentation: one tab, one indentation level. Also, it would match gofmt, if that matters to you.
I'm not sure I buy that it's a large improvement over TOML -- In practice I haven't found the homogeneous list requirement to be an issue, and I really appreciate toml's writing styles and the use of sections to clearly delineate.
I think TOML is still my favorite (especially in terms of readability) but SAN looks awesome
[0]: https://astrocorp.net/san/san-vs/
That was one issue I had with TOML, because the allowed data schema is not JSON compatible. Switching from YAML or JSON to TOML or SAN is therefore often difficult and as such easier to just stay with the one that is currently used.
For new projects, it might be nice. But having to work around this limitation when you need it is also a bit annoying.
As for heterogenous list types, great reason to have them is when your list is logically the same type but physically isn't.
In some formats like Cargo.toml, the following are equivelant:
This allows a short-hand for the common case. Being able to do this in lists would improve the file formats I've been making.(Of course I would need to change the string to a map as well, but that is just clunky to write all the time.)
They can all be replaced by maps which may seems more verbose but carry in fact far more information and clear
So for me you get a shoe if you reverse your argument. Type limitations aren't improving write or readability IMO and just make it harder, because you have to think about using the right type. Application specific schema checkers should take care of the checking the type.
In my side projects, generally I'll hand-write a parser with regular expressions because I haven't yet found one I actually like both looking at and editing. I can fix every single other problem except that one. With SAN, the issue is the bracket delimiters. I hate futzing with them, just let me use tabs. I want this:
This is easy to look at, easy to edit with a text editor, and, once the parser's written, dead simple with Ruby POROs, easy to parse into queryable data structures.I have yet to find any format that's intended to be human-editable that doesn't actually feel 'nice to the touch'. So I just make my own.
When hand-editing the format above, I generally don't type in a whole line at a time. I'll just add in the basics, and fill it out later, perhaps with machine processing. Tags in particular are easy to copy-paste in by hand and are generally the last part of the line.
The reason for brackets are auto formatting by the san CLI (think go/rust fmt)
If my configuration needs auto-formatting, something's gone very very wrong in the design of my application.
https://github.com/kuyawa/dixy
I hate, hate, hate the ambiguity and the flavor of the week tokenization/operator precedence/does it trim whitespace questions.
This is JSON's biggest strength: it's trivially unambiguous.
A KVIN file follows one simple pattern: it's a list of key-values or comments. Comments are any line that starts with any amount of whitespace and then a '#'. A key-value starts with a key, ends with a value, and has a '=' in the middle:
A key is made up of any valid C-identifier or C-numeric expression. You can 'chain' keys together with '.'s: A value is any valid c-identifier, c-number, or "byte string". A byte string starts with a '"', ends with a '"'. If you want to include a '"' then you have to escape with a '\'. If you want to include a '\', then you '\' the '\'. All whitespace is included in a byte-string: even a '\n'!Strangely, KVIN understands relative paths. If a key starts with '.' then that means it's relative to the path just above it. Each '.' means 'go up one level from the last value':
Would be a JSON like this: KVIN has one final trick, besides the busted old turbo he's been trying to get in his iRoc: he knows how to autonumber a list: Which would be the JSON: With 'a' starting at index '10'. (The base index of arrays is 0.)I've got code laying around, somewhere, that implements KVIN.
2. No multi-line support?
What about JSON5?
2) https://astrocorp.net/san/versions/v1.0.0/#string
2) Awesome!
[0] https://github.com/hashicorp/hcl [1] https://xkcd.com/927/
To add my 2 cents. I really like what I saw in Skylark(Starlark?). It's fairly close to my dream setup: a simple Python interpreter with no libraries.
Pythons object notation looks 95% like JSON, it supports comments, solid multiline support, well known escaping rules, basic format strings when you need them.