14 ms·
Intercal, YAML, and Other Horrible Programming Languages
- Turing_Machine 6y agoEarlier discussion: https://news.ycombinator.com/item?id=26262503 https://news.ycombinator.com/item?id=26262503
- nerdbaggy 6y agoMy favorite thing about YAML is that I can put JSON in there instead and most programs will work just fine.
- progre 6y agoWhile YAML has some warts, the "if" statement in there really cant be blamed on YAML as it does nothing but inserting a node in the object tree. You'd need something else to act on that node. I get what the author is saying though, you should try to keep your config logic-free.
- PaulBGD_ 6y agoYeah, it seems the reason he mentions YAML specifically is because it has become highly used for these "build script"-like "config files".
- j16sdiz 6y ago/me looks at mongodb and groovy
- konjin 6y agoThat's like saying C doesn't have an if statement, you're just adding it to the AST, it's the CPU that does the actual jump not C. In short: a distinction without a difference.
- goto11 6y agoThe C language have an if-statement because it is part of the specification of the C language. YAML does not have an if anymore than JSON have an if because you can write {"if": "foo", "then": "bar"} and some processor can process this with if-semantics.
- sriku 6y agoIt is common for lisp folks to chime in at this point to iterate the value of s-expressions. While this is one such, but I actually have an evolution story about this which I shared in a talk here - http://sriku.org/posts/inevitable-lisp/ http://sriku.org/posts/inevitable-lisp/
- nerdponx 6y agoI somewhat disagree with the complaint here. If you write your config in a "full-blown" programming language, then your configs are full-blown programs in that programming language. This situation just plain sucks, or at least it comes very close to (or passes) the "suck" threshold every time I experience it. Code-as-configuration demands tremendous discipline from the team. Whereas if you abuse YAML (or JSON or XML or whatever) to create a limited and hard/impossible-to-extend DSL, you still have much more control over what can and cannot be executed by the config engine, even if the DSL happens to accidentally become Turing complete. You can embed limited shell commands in the DSL as an escape hatch, but make it difficult enough that you really have to try to make a mess. Another example of this DSL model done mostly-right is Make. Once you accept that idea, whether to use JSON vs YAML vs TOML vs XML vs S-expressions is just bikeshedding over syntax. As for "why YAML in 2021" specifically? Yes, YAML is a big spec and there are lot of ways to get strings wrong. But maybe you don't care or your team is unlikely to ever go near the darker corners of the spec. For simple config files, YAML is just really easy to read and write. And if you do need multi-line strings, it's a whole lot easier than doing it in JSON. I'm personally a big fan of TOML, but maybe YAML is still better for highly-nested data. Of course S-expressions are wonderful for many reasons, but they share the problem with JSON of being somewhat hard to diff and edit without support from tooling.
- tonyedgecombe 6y agoThe trouble I have with DSL's is I don't work on the scripts often enough to become proficient with them. If I haven't looked at it for six months then I'm going to spend most of my time googling or reading half baked documentation.
- konjin 6y ago>Of course S-expressions are wonderful for many reasons, but they share the problem with JSON of being somewhat hard to diff and edit without support from tooling. If you want support for trees xpath has been there for 25 years now.
- js8 6y ago> Whereas if you abuse YAML (or JSON or XML or whatever) to create a limited and hard/impossible-to-extend DSL, you still have much more control over what can and cannot be executed by the config engine, even if the DSL happens to accidentally become Turing complete. You can embed limited shell commands in the DSL as an escape hatch, but make it difficult enough that you really have to try to make a mess. The article actually mentions Dhall as a solution. This engineering problem has been resolved.
- murukesh_s 6y agoWondering why there is no light-YAML or just JSON without comma and braces sort of language available? Or even if there why not popular yet? Almost everyone complains about the huge spec of YAML and that pretty much seems to be the biggest complaint (other than it getting huge - but that can be there for all languages).
- thaumasiotes 6y ago> Wondering why there is no light-YAML or just JSON without comma and braces sort of language available? Well, JSON without commas or braces would be restricted to single literal values. (Or, I guess, single-element lists, but what would the point of that be?)
- coldtea 6y agoParent means YAML-like JSON-lite format, so you could have multiple elemnts without commas or braces, just with whitespace and newlines as separators. Where JSON here is just a stand-in for "simple format with few types", not about it being parseable as JSON or anything.
- thaumasiotes 6y agoIf all you have are record separators, so that the only data you can send is a list of values distinguished by nothing other than the order in which they occur, then the information about the structure of the data must exist separately on both the sending side and the receiving side. Better hope they agree. But regardless, I feel like that exists right now; doesn't this describe protocol buffers?
- coldtea 6y agoParent said no commas or braces. He didn't say "all you have are record separators". E.g.: a list: - foo - bar - buz and other things besides list of dicts: persons: - name: John Smith age: 54 occupation: Obergruppenführer - name: Frank Frink age: 32 occupation: craftsman (Those are already valid YAML iirc)
- gerdesj 6y ago"Writing control flow in a config file is like hammering in a screw." Sometimes a screw is the correct or perhaps only fastener for a job and a hammer is the only screwdriver available or the only screwdriver capable of driving the screw. I've done it.
- Cthulhu_ 6y agoUnfortunately this explains most problems with evolving software applications. You see a problem, and you KNOW it would be much better solved with e.g. a rewrite into a proper programming language, but as a developer (and manager) you have to make the tradeoff; spend five minutes adding an IF to a yaml file, or five months rebuilding the whole CI to allow for conditionals. I'm currently in tradeoff mode as well. Do I spend a month copy / pasting some shit code in the existing codebase so that I can spend the rest of the year on the project rebuilding things, or should I pause the rebuild project and instead clean up the existing one (effectively a rebuild-in-place).
- BrissyCoder 6y agoAre things like YAML considered "programming" languages now?
- IshKebab 6y agoThat's kind of the whole point of the article.
- undecisive 6y agoNope. Otherwise, one could argue that some programming languages use newlines to separate commands, therefore the file type is NSV (newline separated values), and therefore NSV is a programming language, and any newline-separated file is a program. This is clearly nonsense. Sometimes people confuse the medium with the language. YAML may be the medium in which programming instructions are conveyed, but it never makes YAML a programming language, irrespective of the file extension. If you put lines of bash into a YAML array, the YAML itself still only contains data. If you pass that data file to something that can take the bash lines out and make use of them, then great. Essentially, it's a storage medium - just a slightly higher-level storage medium than we're used to thinking about. You could create a programming language syntax that is entwined with YAML, but then the language would be more correctly named something like Whatever-over-YAML (or Whatever for short)
- agbell 6y agoAuthor Here. My point is not that YAML is a programming language, and that is horrible. Instead, it is used sometimes used to embed a vendor-specific unnamed programming language in, and that is horrible. People start with some YAML, and everything is fine. Then a simple condition is added, so ok, we are treating code as data, LISP style but in YAML. Then the logic and branching grows, and we introduce templates. It not that anyone wants to get where we've ended up. It's that each step along the way seems to make sense until you end up trapped in complex templates, and scripts to configure your config and it's too late. It is a vicious local optimum that everyone keeps falling into.
- aidenn0 6y agoIf you embedded a vendor-specific unnamed programming language in JSON or Dhall or TOML or INI or CSV it would be bad too.
- mastrsushi 6y agoYAML sounds like the, olde time "hardy hard har" solution to modern extensible languages. Where pretty much "anything goes" to the point of conceiving full blown tumor executables. People can say what they want about JSON but anything beats the old world of rolling your own serializers and convincing your boss over the hours you've spent reinterpreting some "sporadic flavor" like YAML.
- emptyparadise 6y agoI love JSON, but it sure would be nice to hop into a time machine and force Douglas Crockford at gunpoint to add comments to the spec.
- mastrsushi 6y agoShould serialized data allow comments though? I feel that's considered Metadata that could be connoatated elsewhere.
- emptyparadise 6y agoIdeally no, but with JSON being used as a configuration file format and being written by humans, I don't think we have much of a choice.
- whizzter 6y agoMany JSON parsers has flags to enable comment parsing (and someone went ahead and made a "standard" called JWCC that seems to be more or less what these parsers accept) I think that is a good tradeoff, JSON being strict for data interop with the possibility of enabling comments for those cases where people use it for configuration (and specifying it as JWCC)
- marcosdumay 6y ago> Should serialized data allow comments though? Hum... Why not? Serialized data can be written and read by humans too. Besides, if comments are out of scope, there is no reason for them to be textual either.
- HelloNurse 6y agoThe XSLT FizzBuzz example doesn't seem written "in jest", except perhaps in the loose sense of making a point about Turing completeness. It's as straightforward and readable as XSLT allows, leaving only a small refactoring on the table (putting "
" into an unconditional output instead of repeating it in the four cases).
- benibela 6y agoBut it is much simpler to write it in XPath (that could then be included in XSLT) for $i in 1 to 100 return if ($i mod 3 = 0 and $i mod 5 = 0) then "FizzBuzz" else if ($i mod 3 = 0) then "Fizz" else if ($i mod 5 = 0) then "Buzz" else $i Wrap it in string-join, if you need the output as one string with line breaks rather than a sequence list. Although one can also write horrible clever XPath: for $i in 1 to 100 return (("Fizz"[$i mod 3 = 0] || "Buzz"[$i mod 5 = 0])[.], $i)[1]
- zmix 6y agoUsing your solution, one may shorten the XSL-T (with XSL-T 3.0) to: <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template name="xsl:initial-template"> <xsl:sequence select=' for $i in 1 to 100 return (("Fizz"[$i mod 3 = 0] || "Buzz"[$i mod 5 = 0])[.], $i)[1] ' /> </xsl:template> <xsl:stylesheet> While I understand the ratio behind the article and agree, the author does not acknowledge, that XSL-T is not a "programming language" but a "templating language".
- emptyparadise 6y agoThere often comes a point where you might as well use some proper embeddable scripting language like Lua for config files.
- oftenwrong 6y ago{{ toYaml .Values.labels | indent 4 }} {{- include "grafana.labels" . | nindent 4 }} Building data structures by piercing together strings like this is a bit questionable.
- ann_cybil 6y agoThat looks like Jinja that outputs YAML, doesn't seem fair to blame YAML (which I think the author sort of does) just because someone wanted to bolt an include statement onto it.
- nonameiguess 6y agoThis is neither yaml nor Jinja. It's a Helm chart, which uses Go templating to generate yaml programmatically. The point of this is all of the actual config is in Values.yaml, which generates the .Values object referenced here, and you use those values to generate all of your deployment definition, making it easy to apply environment-specific overrides by switching out a single file and leaving everything else alone. So yeah, if Helm is complicated, sure, don't blame yaml for that. Similarly, I'm not sure all of these declarative CI examples are all valid yaml either and not fed through front-end preprocessor first. They're essentially feature-identical with Jenkins declarative pipeline minus the ability to run arbitrary Groovy code in your build scripts, though of course you can get this exact behavior if you want by feeding a HEREDOC to a sh step that invokes the Groovy interpreter. In any case, the author calling CI workflow definitions "config" is a little misleading. They're necessarily more complicated than a properties file and need to allow you to invoke external tools. Newer language ecosystems like Go and Rust are trying to solve this by putting dependency management, compiler, packager, and testing all into one tool provided with the language installation, but even there a lot of CI/CD needs to do a lot more than that, like deploy infrastructure, build container or VM images, etc.
- agbell 6y agoAuthor Here. Thanks for reading. I am not trying to be misleading. I'm trying to point out that although each step along the way of adding things to config seems to make sense, you arrive in a bad place. People start with some YAML, and everything is fine. Then a simple condition is added, so ok, we are treating code as data, LISP style but in YAML. Then the logic and branching grows, and we introduce templates and so on. You start with config, then the config ends up with its own config, and eventually, you are using Skaffold to configure Helm, which generates your YAML. That can't be the right solution, can it? https://skaffold.dev/docs/pipeline-stages/deployers/helm/ https://skaffold.dev/docs/pipeline-stages/deployers/helm/
- jaza 6y agoIn my opinion and in my experience, many actual programming languages are fine for defining config, and (due to you inevitably needing some control flow, and them having it built in) are often better than declarative languages. I for one have no problem with config in Python, JS, Bash, PHP, or Ruby. As long as it's in dedicated config files, and as long as it's kept as simple and as declarative as possible.
- tinus_hn 6y agoAnd as long as you don’t need to parse it in another language, or automatically manipulate it.
- waheoo 6y agoIf it's stored as code it's going to be trivial to dump it to Json in the rear situations you need an application config to be read across languages.
- tinus_hn 6y agoSo now you need the runtime for that other language in your system-wide configuration management solution. Plus all the other runtimes for languages someone decided to use as a configuration language.
- enriquto 6y agoSounds alright to me, as long as you restrict to sane, reasonable languages. For example lua's "runtime" fits in a single .c file and is likely simpler than many xml or json parsers.
- choeger 6y agoBut that does not allow you to manipulate it automatically (think about moving domains or something like this), nor does it help you to detect errors (which few tools do, but many actually should do).
- 6y ago
- anotherhue 6y agoThe indent function tells you everything you need to know about yaml templating. Take a look at Dhall as an alternative.
- chovybizzass 6y agoxml seems to be making a comeback in the shadows.
- southerntofu 6y agoI feel like a lot of people who were criticizing XML a few years back because "schemas are complicated" and "XML is too verbose" are slowly realizing these things were invented for a reason. JSON-LD or XML are perfectly good candidates for data with strict schema. But it took devops startup fanboys some time to realize schemas were useful in the first place.
- MaxBarraclough 6y ago> a lot of people who were criticizing XML a few years back because "schemas are complicated" and "XML is too verbose" are slowly realizing these things were invented for a reason Agreed, it's analogous to the way the programming language world has come around to realising the static type system folks had a point all along. I don't have much experience with XML so I can't speak to whether the other criticisms of XML make sense, especially regarding complexity.
- why_Mr_Anderson 6y agoIntercal isn't horrible! How could be the only language with PLEASE keyword be bad? (from wikipedia) This last keyword provides two reasons for the program's rejection by the compiler: if "PLEASE" does not appear often enough, the program is considered insufficiently polite, and the error message says this; if too often, the program could be rejected as excessively polite.
- Lucasoato 6y agoUsing traitlets for jupyter configuration completely changed the game. It enhanced jupyter versatility and extendability so much. The only downside is that it is kinda unparsable but that's because providing parsers for most used IDEs requires a lot of time...
- pdimitar 6y agoI keep hearing from people here and there to use Dhall. Anybody has direct impressions?
- andybak 6y agoJust took a quick look and the first example does that hateful thing with starting lines with commas. Even if that's just a convention thing it instantly makes me want to avoid it. Just allow trailing commas at the end of lists. It's much less jarring and unfamiliar. Trivial? Maybe. But my brain takes a while to adjust to new conventions and I do it way too frequently already.
- reactormonk 6y agoYou can have trailing commas just fine: https://github.com/dhall-lang/dhall-lang/pull/956 https://github.com/dhall-lang/dhall-lang/pull/956 However, `dhall format` is _very_ opinionated, and will remove it.
- andybak 6y agoDoes dhall format have an opinion about commas at the start vs end of lines? What's the recommended style?
- reactormonk 6y agoI formatted { foo = 3, bar = 4, baz = 5, verylongproperty = 6, dunnoneedsmoremore = 7, howmanytoforcealinebreak = 8 } And it forces the comma at the beginning of the line, Haskell-style: { foo = 3 , bar = 4 , baz = 5 , verylongproperty = 6 , dunnoneedsmoremore = 7 , howmanytoforcealinebreak = 8 }
- stickfigure 6y agoThis will not diff well if you add a new row at the beginning. It's the same problem with non-trailing-commas, but moved to the front instead of the end.
- moondev 6y agoI'm working on a project that allows you to put a special "yaml shebang" at the top of any kubernetes manifest. The shebang is actually valid yaml since it's interpreted as a comment. This allows you to combine the declarative kubernetes spec (yaml) with external controller (kubectl) example my-app.yaml #!/usr/local/bin/kubectl -f --- apiVersion: v1 kind: Namespace metadata: name: my-namespace --- apiVersion: v1 kind: Pod metadata: name: my-pod namespace: my-namespace spec: containers: - name: nginx image: docker.io/nginx:latest ports: - containerPort: 80 after making my-app.yaml executable you can now invoke the application's config to reconcile itself > chmod +x ./my-app.yaml > ./my-app.yaml apply namespace/my-namespace created pod/my-pod created > ./my-app.yaml get NAME STATUS AGE namespace/my-namespace Active 8s NAME READY STATUS RESTARTS AGE pod/my-pod 1/1 Running 0 7s > ./my-app.yaml delete namespace "my-namespace" deleted pod "my-pod" deleted obviously this is just a simple example but there is come really cool potential here.
- irgeek 6y agoTo be fair, this is just how executable scripts work — it’s not a special yaml shebang, just a regular shebang for an executable that happens to take yaml files as it’s input. The underlying OS just invokes the command in the shebang and passes the file as the first parameter, exactly as it would if the shebang were for bash or python.
- CyberDildonics 6y agoI never thought I would see the day when someone "discovers" the way shell scripts were intentionally designed 40 years ago. This is why perl and later python uses # for comments.
- morelandjs 6y agoI see this happen a lot with python projects. In my opinion, a superior strategy is to simply import python config modules, e.g. config.py. You can always write a dictionary into that config file, just like you would with normal yaml. It would actually be sort of nice if python had support for yaml style dictionaries exactly for this purpose.
- nailer 6y agoSame here is JS land. We have JSON (and JSONC) but it's easier to just have a `js` config file, with comments, importing the `dotenv` module for secrets values, or whatever else you need.
- yetihehe 6y agoThat's why erlang has file:consult from the start. It just reads whatever data is in file, that data can be any valid erlang terms. That format is also used for typical system configuration files. Of course, you could make execution based on that configuration file, it happens that erlang already has "standardised" way of storing this as {M,F,A} (module, function, args), which you could send directly to apply: {ok,Commands}=file:consult("functions.txt"), [ apply(M,F,A) || {M,F,A} <- Commands ]. With contents of functions.txt: {io,format,["Hello World!~n"]}.
- geerlingguy 6y agoYAML isn't a programming language. The fact that it's often abused to be one is not the fault of the syntax.
- agbell 6y agoIt is definitely not the fault of YAML. It has its own issues but that is another story. The problem is when you use YAML (or an ad hoc interpreter embedded in YAML, or a templating system built on top of YAML) for things that should really be a programming language. Things like imports and functions and composition are useful. Templating is a more ergonomic form of string concatenation.
- mumblemumble 6y agoUsually, when I have to deal with these crazy complicated YAML files at work, I'm not thinking, "I wish they had just turned all the configuration into a mess of shell scripts." I'm thinking, "We really need to clean this up. It's way more complicated than is necessary."
- agbell 6y agoYou have a point. A mess of shell scripts doesn't really sound like an improvement. If the config is too complex and the config consumer can be changed to simplify things then that should be the way to go. However, if the config is a travisCI YAML file that is really just a glorified list of commands I don't think bash or a makefile is a bad solution. Take as much as possible out of the CI config and use a neutral standard format like a makefile to encapsulate much of your logic. Then when TravisCI stops offering free usage for open source, its easy to move, because your format isn't specific to a vendor.
- SCLeo 6y agoI think the point of the this article is exactly what you said: YAML, when used as a programming language, is horrible.
- 6y ago
- rbanffy 6y agoI love the reference to Harlan Ellison's haunting "I Have No Mouth, and I Must Scream".
- agbell 6y agoAuthor here. Thanks for reading. That reference comes directly from the INTERCAL-90 compiler. it has hilarious error messages. One of my favs is that it is an error to not say PLEASE enough and also an error to say PLEASE to often: E079 PROGRAMMER IS INSUFFICIENTLY POLITE The balance between various statement identifiers is important. If less than approximately one fifth of the statement identifiers used are the polite versions containing PLEASE, that causes this error at compile time. E099 PROGRAMMER IS OVERLY POLITE Of course, the same problem can happen in the other direction; this error is caused at compile time if more than about one third of the statement identifiers are the polite form. Some more fun details: - The compiler is called `ick` - The compiler has a `-mystery` flag which is documented as "This option is occasionally capable of doing something but is deliberately undocumented. Normally changing it will have no effect, but changing it is not recommended." - Numbers have to be entered in English. 12345 would be written as `ONE TWO THREE FOUR FIVE` unless you put it in roman numeral mode where the characters ‘I’, ‘V’, ‘X’, ‘L’, ‘C’, ‘D’, and ‘M’ mean 1, 5, 10, 50, 100, 500 and 1000. - The debugger is called `yuk`
- jerf 6y agoMakes me want to hook up a simple predictive algorithm such as what is used for online Rock-Paper-Scissor against computers to demonstrate how predictable people can be and add E134 PROGRAMMER'S POLITENESS IS TOO PREDICTABLE Politeness, once made too predictable, is too easily overlooked. This error is caused at compile time if the programmer's politeness level is too easily predicted by the compiler as it encounters each statement in the code.
- 0xbadcafebee 6y ago> How did we get to this world of little programming languages embedded into YAML? A configuration file is just a bad programming language (or a good one...). Some people have forced YAML to be a configuration file because they're lazy and don't want to write a parser/lexer. But most people do it because they don't know the difference.
- alephnan 6y agoOh god, I remember some visionary people at a certain FANG org I worked at trying to reinvent HTML, but expressed as YAML.
- phtevus 6y agoThe author mentioned YAML but never once brought up CSS. This article feels more like a rant if anything and illustrates the author misunderstanding of the purpose of the language.
- loloquhwonedeo 6y agodespite what the article shows, YAML is NOT a programming language - constructs such as `if`, `when` and others are not generic. Try to feed an ansible playbook to Travis, or get those jinja-like variable substitutions working with a YAML parser that doesn't process them, and things won't work as expected.
- teh_klev 6y agoThe article already mentions this: The problem with these languages embedded into YAML is they are all one-off implementations. TravisCI conditionals have a TravisCI specific syntax, usage, and features. You can't use Travis's concat function or conditional regex in the YAML configuration for your ansible playbooks.
- Tabular-Iceberg 6y agoWhat about an SQLite database for configuration? For most applications it would probably be overkill, but it seems useful for applications that need to change their own configuration (e.g. by the user through its GUI), or need its configuration changed by other tools.
- wirrbel 6y agoLet’s use a key value store and call it the configuration registry!
- AnonymousPlanet 6y agoYes! And then let's have anyone put their shit in there without order. So you have config and runtime data in the same area. Have multiple processes change the same value at will. Except for anything larger than a few Bytes. That we just disperse across like 10 possible locations on all hard drives!
- datavirtue 6y agoI use a code first approach. I build my config as plain old objects and serialize/deserialize them (JSON). 100% flexible and very easy to grok. New devs look at it and just know what is going on, immediately.
- jrochkind1 6y agoI want my configuration to be easily diffable by git.
- tzs 6y agoI'm fine with having a program that transforms the configuration file into a more diffable format, and then doing my diffs on the transformed files. I like for this a sorted name=value format, where non-scalars such as arrays and hashes are flattened into the names. E.g., if the config contains an array named "users" with 3 items, the name=value pairs would flatten to names users.0, users.1, and users.2. An array named "servers" whose entries are 3 hashes with the host name and port would flatten to names servers.0.host, servers.0.port, servers.1.host, servers.1.port, servers.2.host, servers.2.port. That gives you diffs that tell you what has actually changed in the configuration itself rather than in the formatting of the configuration file.
- dsabanin 6y agoI think all Lisps work really nicely for configuration that is combining data and control flow. It's a shame that most people are too unfamiliar with the prefix notation.
- dan-robertson 6y agoSexps can be nice for a config representation (in particular, they imply less structure so they work well for more cases like maps between objects (just use an alist), little DSLs in configs (so long as you’re ok with a lisp-like language), and “tagged objects” where you want to specify what kind of thing you’re describing and then extra arguments, like enums in rust). There are problems though: 1. Casing (some lisps are case sensitive others aren’t) 2. Lots of types of atom. Eg Common Lisp has like a dozen different types of number (short/long/single/double floats, integers, rationals, complex numbers thereof), weird syntax (eg put a decimal point at the end of an integer to make sure it’s read in base 10. The fact that you have to worry it won’t be is already a serious concern), strings and symbols. 3. Extra syntax/types, eg vectors, arrays, bitvectors, #., backtick and comma, quote, backslash rules (but not sure if there’s a standard way to escape characters), keywords, packages 4. Multiple similar things, eg vectors and lists, symbols and strings, alists and plists. Many of these qualities may be useful in programming but if one treats a config representation as a thing which must be validated and parsed into the actual data, then all of this adds confusion. I think there should be only one kind of atom: the string which may be written without quotes. This way you can be flexible in parsing (some fields you might choose to parse 50% as 0.5 and other fields you might require that the number starts with a dollar sign so people don’t forget that it is referring so some amount of dollars) and make it easy for people to write config files (no errors about expecting a string and getting a symbol or vice versa).
- junke 6y agoFollowing the $ thing for amount of values, a thing I like in Common Lisp is the way the reader can be customized, and maybe this is a bad idea but I would like to have user-provided data-types formats and bind them to prefix characters, or pairs of delimiters, ... to avoid having to tag your values like this, as done in JSON: (published (type std.iso.8601 value 2020-02-26)) Or like this, where "date:" is something only your application knows: (published date:2020-02-26) Instead, you could rely on an externally specified format (prefix @ is std.iso.8601) And use it in your file to parse text so that your application can build values of the proper datatype: (published @2020-02-26) The application language would register lexers for those formats or fail the parsing step. You could have fake parsers that just skip over the defined syntax if you don't need to process it in your code. Or, the way the syntax is defined could be such that it tells the lexer how to skip over a token even if the type is not useful for a tool's purpose (skip until a space, or parse exactly N characters, or "read until this delimiter with backslash being an escape character"). (probably reinventing the wheel)
- gregwebs 6y agoI see Dhall mentioned in the comments. cue is another great configuration language: https://cuelang.org/ https://cuelang.org/ Both of these are actually designed well for dealing with the problem of configuration and it really shows.
- verdverm 6y agoI was hoping the article would mention Cue. I find the syntax so much better. Cue needs to be adoption ready and is getting close. The big one will be the 'cue mod' command, when that lands we should be in good shape. I think v0.4 will be when people start looking hard at Cue, but maybe a later 0.3.x
- dkarl 6y agoI suspect a lot of abuse of config files comes from moving logic out of source code for bad reasons. There are good reasons for not hard-coding, say, ports and service endpoints in your source code, because it makes it easier to run the code in different environments. However, there are also bad reasons for taking things out of code. A couple that I have encountered: Pride in creating a "generic" system that can be configured to do all kinds of new things "without touching the code." Reality check: only one or two programmers understand how to modify the config file, and changes have to go through the same life cycle as a code change, so you haven't gained anything. You've only made it harder to onboard new programmers to the project. Hope that if certain logic is encoded in config files, then it can never get complicated. Reality check: product requirements do not magically become simpler because of your implementation decisions. The config file will become as expressive as necessary to fulfill the requirements, and the code to translate the config file into runtime behavior will become much more complex than if you had coded the logic directly. Hope that you can get non-programmers to code review your business logic. Reality check: the DSL you embedded in your config file isn't as "human readable" as you think it is. Also, they're not going to sign up for a Github account and learn how to review a PR so they can do your job for you. Marketing your product as a "no code" solution. Reality check: none for you; this is great! Your customers, on the other hand, are going to find out that "no code" means "coding in something that was never meant to be a programming language."
- datavirtue 6y agoFor all the love of python and it's excellence at automation why in the fuck has everyone latched on to YAML? As soon as it appeared I thought it was dead on the vine. Joke was on me.
- gsmecher 6y agoYAML has such a comic-book reputation around here that I want to offer a defense of it. Many criticisms of YAML are either about adding non-YAML bits (like turing-complete templates) on top of it, or complaining that it's a bad JSON superset without considering things that can't be expressed in JSON. You know what's really interesting about YAML? !Tags (https://yaml.org/spec/1.2/spec.html#id2805019 https://yaml.org/spec/1.2/spec.html#id2805019), when used as type hints. In YAML, you can write: (forgive the contrived example) !Person name: Joe login: joe In Python, you can use "yaml.add_constructor" to automatically dispatch specific Python code when !Person tags are encountered in the YAML. You can transform text into an object tree (edit: graph, actually -- don't forget about anchors and aliases) automatically. In the right places, this is extremely handy. It's a middle ground between the "duck typing" you normally get with un-validated markup, and the quasi-"static typing" you get with the same inputs after a schema validation. There's an analogy with type annotations in Python. As always, there are right and wrong places to apply this kind of thing.
- petestaples 6y agoThanks gsmecher. We lean on YAML for writing automated hardware test scripts and have good reasons for it. JSON doesn't allow comments which are needed for a distributed team to understand the meaning of the tests. https://docs.pltcloud.com/TestPlanReference https://docs.pltcloud.com/TestPlanReference
- gsmecher 6y agoWe use YAML to capture a structured description of a large instrument deployment. Comments are absolutely key for us. The YAML is revision controlled in git and annotating it as a document (rather than as data) is a huge benefit. Tagged YAML allowed us to replace an older system that had ten times as much code. Now, there are far fewer, much warmer code paths, and it's easier to use and far less scary to maintain as a result. Other markups are not the only alternative to this kind of thing. I expect many developers would reach for a database (SQLite?) as a storage medium. However, keeping our data accessible in plain text has been a huge benefit.
- yongjik 6y ago> INTERCAL is a bit unusual. For example, single quotes are called sparks, and double quotes are called rabbit ears, less than (<) is an angle, and a dash (-) is a worm. Huh, didn't know urbit had a predecessor!
- StillBored 6y ago"And if so, is a c++ program just config you give to gcc?" LOL, reminds me of the C++ as shell scripts hack where you stick something to the effect: #!/usr/bin/tail -n +1 $0 | g++ -O -g -o ${0%.cpp} -x c++ - && ./${0%.cpp} $1 $2 && rm ./${0%.cpp} ; exit at the top of your cpp file and chmod +x it.
- 91aintprime 6y agothanks, I hate it so much
- ulisesrmzroche 6y agoI don’t know if you can call Intercal a horrible programming language since it’s a joke language. It’s like Brainfuck. YAML though, ugh. Nothing worse than looking at a helm chart. JSON sucks too, but I’d rather a JSON config than a YAML one anyday.