I gave a YAMLScript talk at the Perl conference in Las Vegas last Wednesday. https://www.youtube.com/watch?v=RFIukRdFe1o
To my mind, the nutshell is between minute 14-18:
"YAMScript is a functional language, which is cool, but it looks like Python. if is a function, so when you see it in Clojure, there are parens around the whole thing. YAMLScript does not have parens around everything, which is what they [Clojure people] are used to, they know where stuff begins and ends. Its awsome when you get into it, but I do not want to push it. I don't want to say, hey look at this thing you just got to use parens, I know that's not gonna sail very far. So I made the language, Pearl is a major influencer."
From the talk I deduced that there might be either 2 or 3 primary motivations (use cases) for YS.
@markus.agwin Lots of little sugary things that I've enjoyed from Perl made their way into YS, but model-wise it's all Clojure. Also I'd probably only say that at a Perl conference 😄
@phill do tell!
My #1 question about YS is "What are the use cases?". I don't have the elevator pitch yet.
My go for 3 would be: • Stable plain YAML loading exactly same in any language • Dynamic YAML with clean file importing, node transformation and interpolation • A functional Python 😄
Yes! You must've been at the same YS presentation I just watched on Youtube 🙂
I just made up "Functional Python" but I kinda like it. Needs a bit more story around it.
Surely you can add to that!
The YAML interpreter bugs could be fixed. On the other hand, YS depends on a richer parse than you can get from standard YAML parsers - distinguishing strings by how they're quoted, and allowing duplicate keys - so YS cannot be bolted onto an existing parser, but rather needs its own parser. Slipping YS in as a capability of a grand-and-correct YAML parser is just as audacious an exploitation of circumstances as ... as... as the rest of YS!
I say exploitation of circumstances because, to me, the greatest thing is the interpolation, the evaluation within a template.
The "macros" in YAML are the killer feature.
But the feature won't kill unless parsers support it.
And I have a sort of visceral sense that the demand for the YS-in-YAML-template feature will be grass-roots, not top-down. But YAML is one of those things where the engineer is usually not the customer. The customer is an enterprise that chose Kubernetes, or something like that. Therefore the CEO's may have little clue about the utility of YS in their products. The YS-capable parsers would need to be "made necessary" - and the promise to correct years of YAML-parsing bugs is the magic carpet that can make that happen
Meanwhile "functional python" is sort of a freebie. But it is a less principled benefit. In the sense, that I am not quite sure that the best YAML-macro-expander and the best functional-python have YAML in common.\
e.g., (remind me its name) the Scheme, I mean Racket variant that uses no parentheses... is also an attempt at what I would mean if I said "functional python"
Not that "functional python" isn't necessary - it is - Python being a clean-room reinvention of all of Perl's issues -
@phill that's a lot to break down! I'm going to have to insist on a more precise YAML vocab. (It's important) By interpreter you mean "loader" (the stack of transforms that take yaml text to some language's native objects). The first stage of loading is parsing. Nobody in the real world uses a YAML parser, it's just an internal part of a YAML loader, which is what everyone uses. Duplicate keys, btw, are not detected by the parse stage, that can happen later in the load stack. The world's loader bugs could be fixed only in theory. They never will be in my lifetime. The only way out is for someone to write a reference loader for every language (my strong opinion). YS's "parser" is off the shelf Java one (with its bugs) not written by me. Good enough for now. To be swapped out shortly with the best known one. The YS compiler is a YAML loader stack but with a couple extra stages for parsing out the yes expressions (clojure parts) and making/printing a clojure AST. There's no duplicate keys to consider for code becaus by the point you would detect them they aren't mapping keys anymore; they are parts of clojure AST expressions. It just turns out that I can sell YS as the best plain YAML loader for config style (95% use case) YAML. But it's not really a YAML serialization framework, because there's no "dumper" (opposite of "loader"). I have an upcoming project to do just that. Think YS without code and with a dumper, delivered everywhere. That will fix YAML.
What do you mean by "macros" there? I talked about them as a future YS thing. Is that what you mean? Just want to clarify.
Overall I don't think YS can take off any way but grassroots usage of hey I found this cool code written in YAML and did this other cool thing with it... it was awesome.
aka luck 🙂
Blood, sweat, tears and a LOT of luck...
colloquial Macros - What you demonstrated - generating YAML by programmatic means. (I think the 95% would not write macros in the Lisp sense - YS code that generates YS code - but if SCI supports it, then why not?)
Gotcha. There's also one big important (to me and the YS design team) where anyone can hook into any stage of the YS compiler and change things. This is then how all of the special casing in YS will be done. Currently its a bit hard coded and not exposed. Compare these:
if foo:
lhs: rhs
lhs: rhs
cond:
lhs: rhs
lhs: rhs$ ys -ce '
if foo:
lhs: rhs
lhs: rhs
cond:
lhs: rhs
lhs: rhs'
(if foo (lhs rhs) (lhs rhs))
(cond lhs rhs lhs rhs)There's a hard coded "macro" in the compiler that makes cond both look nice and do what you want.
If you think about it, that's the best way to describe a lisp macro.
Even though the YAML thing is happening at a very different level
anyway, that's what I'll mean by YS macro here.
aka defys (likely defining fn name)
(pronounced defwise 🙂 )
Pulling macros together with the compilation stages, here's the same command with -d to show compilation stage output:
https://gist.github.com/ingydotnet/64d43e58ed260b9a360c3b97f3a487e0
With defys anyone could alter any one of those stages (within the appropriate scope)
and the various mutations currently littered around the compiler could be also defined the same say. dead simple stage logic with macros to make the DWIMmy adjustments that we enjoy now.
I just made up "Functional Python" but I kinda like it. Needs a bit more story around it.For the to-be-told YS story I'd like to point out that YS comes in two variants 1) CLI 2) library, and I am of the strong opinion that this dichotomy needs to be prominently featured in the YS story because my guess is that in the end the use cases are going to be very different (my guess arguably). ad 1) when calling the CLI a "Functional Python", the immediate question will be how to access existing Python libraries. Afaik there is no way and hence no complete story to tell. ad 2) when calling the library a "Functional Python" there is the interop, yes, but the name clearly falls short of what the library is, namely supporting 39 languages next to Python. I do not have an improved suggestion on the name "Functional Python" though. But I'd like to dwell and muse on telling the dichotomy of CLI/Library story. Maybe, just an idea, maybe, while the CLI has SCI/GRAAL-native as runtime, the Library would be just the loader and uses Fennel/Lua as runtime. I never used Lua, I only think storywise, Lua to me already has such a compelling story as an embeddable scripting language that it would sell the Library, storywise, maybe.
heh. I wasn't really angling towards any working relationship between Python and YS. It was more like: "YAMLScript: Functional Programming as easy(/cute/simple/whatever) as Python"
read between the lines: "YAMLScript: Like Python, but solid as Clojure"
There are certainly stories involving both Python and YS. And the dichotomy you mention is one of the elephants in the room.
What I really need to figure out is why functional programming is gold. How to say "YS is FP" and make people go gaga.
maybe it's a good time to chat with a gpt...
https://gist.github.com/ingydotnet/187ae7a32ee52b4d65c80aa3c911ca58 not bad
when I had (like clojure) in there it was way too clojure/java specific
also, I didn't know scala was fp.
I should at least do a quick review of scala to see if we are missing anything nice from there
Scala is a hoot. It's as if Rich Hickey's checklist of "problems with Java" had also been Scala's checklist. But each decision RH made in favor of simplicity, Scala made in favor of complexity.
I don't have high expectations there, but I should at least be able to say I looked.
and full disclojure (I didn't mean to type that but I guess clojure is in my blood now) I never liked python (I've written and even published quite a bit of it)
> What I really need to figure out is why functional programming is gold My opinion is that FP is not gold per se. I think one should never try to argue for FP in general, it's not tenable. I have two situations though where FP made sense (no "alchemy" or "sorcery" pls.) to me in practice, corresponding to 6) and 7) of your gpt-gist: 6) Reagent (instead of React) 7) https://emmy.mentat.org (instead of Python+SymPy) Point 10) I think pertains not so much directly to FP but to the "Code as Data" property i.e. the possibility of Macros (thinking https://github.com/kloimhardt/LisRoot of course). In my view the "Code as Data" story suits YS much better than the FP story.
> the dichotomy you mention is one of the elephants in the room do you want this elephant to be addressed or rather left? Asking because I have a habit of addressing elephants which is sometimes disliked :-(
> In my view the "Code as Data" story suits YS much better than the FP story. ❤️
> do you want this elephant to be addressed or rather left? I want you to not underestimate your value here! I appreciate all your feedback; you've shaped YS, and I hope you continue to.
Changing the __ ys::std function to _-> to make it look like the thread-first op which is how it behaves.
$ ys -ce 'foo.5.bar.baz()'
(__ foo 5 'bar (list baz))
->
$ ys -ce 'foo.5.bar.baz()'
(_-> foo 5 'bar (list baz))Like other YS operators it's a little more magic that -> .
And you can always use -> directly for the real thing semantics.
But making it _-> is just clearer to read than __ imho.
fwiw, symbols containing _ is what I use for "private" stuff in generated code. It's not allowed in the YS symbol syntax, so works out ok so far.
open to criticisms and suggestions (always on anything)
@markus.agwin and I have been noodling in the background about a Least Common Denominator REPL experience for YS that takes the REPL experience to non-programmers (data science folk etc).
All you need is the simplest editor (notepad for instance), the ys command and a terminal.
After watching some of @olical 's (Conjure) youtube videos about REPL I reached out and we started chatting about it.
I'm planning to get a first cut of this done this week, and I'll share it here for review.