Shawn_Clabough:
Hello and welcome to another episode of Adventures in.NET. I'm Sean Clabo, your host, and today I have Caleb Wells with me. Hey Caleb.
Caleb_Wells:
Hey Sean, how you doing?
Shawn_Clabough:
Doing good, doing good.
Caleb_Wells:
Yeah,
Shawn_Clabough:
So, uh, this snow
Caleb_Wells:
long
Shawn_Clabough:
was
Caleb_Wells:
time
Shawn_Clabough:
melted
Caleb_Wells:
no see.
Shawn_Clabough:
pretty much. Yeah. And so, uh, you know, spring should be coming, right? But I don't think so. I'm probably going to have
Caleb_Wells:
Well,
Shawn_Clabough:
some snow left.
Caleb_Wells:
we were in the 70s and 80s most of this week. And now today we're down to the 40s, which for us is cold. So.
Shawn_Clabough:
Wow, it's 42 for me, so am I warmer than you?
Caleb_Wells:
Right now it is officially 52 degrees, so it's warmed up a little bit.
Shawn_Clabough:
Ah,
Caleb_Wells:
Yeah.
Shawn_Clabough:
yeah, dang.
Caleb_Wells:
Yeah. Right?
Shawn_Clabough:
All right, so let's welcome our guest today, Martin Tyrion. Welcome, Martin.
Martin_Tirion:
Hi, thanks, welcome John. Nice to talk to you and Caleb of course.
Caleb_Wells:
Yeah,
Shawn_Clabough:
Just
Caleb_Wells:
thank
Shawn_Clabough:
me,
Caleb_Wells:
you
Shawn_Clabough:
you
Caleb_Wells:
for
Shawn_Clabough:
don't
Caleb_Wells:
joining.
Shawn_Clabough:
have to worry about Caleb.
Caleb_Wells:
Now, nobody worries about me. Ha ha ha.
Shawn_Clabough:
All right, Martin, could you tell us a little bit about yourself, you know, what you do and how you got into working with.NET and things like that?
Martin_Tirion:
Yes, so I'm a senior software engineer at Microsoft. I'm in commercial software engineering or CZ as we call it. So we're a big organization of about a thousand people I believe now worldwide working with large customers, mostly on Azure deployments and everything that's connected to it. And I started out like a million years ago as a global developer. And then from COBOL went to C and C++ and then ended up with C sharp and.NET. And actually, so we try to do with all languages or platforms that we encounter at customers. But most of the time it's Azure and.NET and C sharp.
Shawn_Clabough:
Well, it's kind of a similar journey to what I had. You know, I took Cobalt and Pascal and Fortran when I was in college. So I had some familiarity with those old languages and just C, you know, before C++ did some of that. So I can,
Caleb_Wells:
Yay,
Martin_Tirion:
Yeah.
Shawn_Clabough:
a
Martin_Tirion:
Well,
Shawn_Clabough:
flashback
Caleb_Wells:
not me.
Shawn_Clabough:
there for me.
Martin_Tirion:
it's, it's still here and actually you can make a lot of
Caleb_Wells:
Yes.
Martin_Tirion:
money. You're a total programmer, right?
Caleb_Wells:
Yeah, yeah,
Martin_Tirion:
Not sure
Caleb_Wells:
I know
Martin_Tirion:
if
Caleb_Wells:
a couple.
Martin_Tirion:
you want to do that all the time, but I had fun when I did it.
Shawn_Clabough:
Yeah, I just traded periods at the end of everything for semicolons, you know.
Martin_Tirion:
Exactly, exactly.
Shawn_Clabough:
All right. So I think our main topic for today is using liquid for making templates and using in.NET. So I don't think we're talking about liquid fluid, water, and things like that. So first, let us know what liquid really is.
Martin_Tirion:
Yeah, so maybe describing the problem that we faced. So one of the things we were doing for a customer is where we had notifications of data going over specific levels and things like that. And then we wanted to capture that and then send an email to people. So it needed the kind of subscription model, but also some kind of content to send. to someone to say, hey, these numbers are not what you expected or whatever. And of course, what the content of that message is, is changing every time for every scenario. So we needed to have something that you can have your, a piece of text and a piece of data and have that come together and do a kind of a mail merge and send it to people. So we were looking into a solution and at first you think like, oh, you can do a two string or things like that, right? Do that yourself. But then you're very stuck to maybe what you put in code or you have some text file and you have to do some magic there to do replacements. But most of the time you want to do more. And especially when you think of maybe generating a report. that has tabular data for instance, it's not longer just replace a name or something, but now it's also about iterating over data and maybe structuring it and update or have a layout for it and maybe give colors and stuff like that. So you want more and more and more. And then of course you don't do that in pure code anymore. So we were looking for something that would be a very good solution for this. So we stumbled upon Liquid Language. And actually when you dig into Liquid, so the simplest way to describe it for me is it's just combining text with data and the output is again text. And then you would say, okay, so you have just plain text. but you can also do that with HTML because that's also text or JSON or XML or any other text based something where you can put in data and output something else. So this was the first scenario where we used Nliquid because we then had a template that had a specific structure with some text and showing some data. And then we brought in the data. and outputted it as an HTML which we send by email. So you get a nicely formatted email that you can read and you can have something like a graph in there or stuff like that. So that's actually what Liquid is. It was originally written by Shopify. They say written in Ruby. And it's actually a standard. And when you look at it, it looks... pretty familiar. If you have ever worked with ASP or things like that or Razor, you have those curly braces that you see everywhere or double curly braces and that's actually what's being used in the liquid language. And the nice thing of liquid, it's not only like put this piece of data here but there's also a lot of stuff there to do logic in your data. So to iterate over things or to filter a list and then use only that output or have logic constructions like if else or things like that. And that makes it very powerful to do these text transformations and output something else. And the nice thing is, it's like when you're using a good engine, it's amazingly fast. And of course, when you think of this being used with things like ASP, you want a very fast transition from the ASP code you have to HTML. It can take minutes or something or seconds. It should be very fast because you want to do that every time. So, and that's exactly what you see with these parsers. It's very fast to deliver into another format. And it's very flexible. So that's a bit like the purpose of Liquid. It's coming from the HTML background. So to generate HTML from static data or combine HTML with data. But when you think of it, there's a lot of text already mentioned like JSON or XML and all kinds of special JSON documents that you have. We also did for instance, conversion from XML to JSON to specific formats and all using liquid. So then it's very easy to apply that.
Shawn_Clabough:
So how
Caleb_Wells:
Gotta
Shawn_Clabough:
do
Caleb_Wells:
be
Shawn_Clabough:
you
Caleb_Wells:
curious.
Shawn_Clabough:
get Liquid? Is it a NuGet package that you just install and you can start from there and build your templates? Or, I
Martin_Tirion:
Well,
Shawn_Clabough:
mean, is this something free?
Martin_Tirion:
a liquid is the language itself. So that's the definition of the, let's say the syntax or the structure. And there are a number of NuGet packages out there that you can use. The one that we have been using. So we started with Scriben. So that's S-C-R-I-B-A-N. We run into that one. That was a very good one when we started with it, but it has limitations. So it only... implements a limited set of actually the language. Later on, we came across Fluid, Fluid.Core. It's also an open source project, it's on GitHub. It turned out that it was actually created by one of my colleagues in Seattle. It's the package that is frequently used also within Microsoft and also in other projects. It's very, very fast. And that's why, and the nice thing of that implementation is that they also built in the kind of security. So of course there's, you can have a potential leak when you have this template language and you just say, well, give me the data and you can do anything with it. Then you actually can inspect with the template, everything that's in your data and maybe more because you. It's not strongly typed, of course, so there's a way to interact with the data. So what they did with fluid.core is their security model. So you can open up specific objects or methods or properties. Or of course, what we all as devs do say, I don't care, just open up anything so you can just use it, but this is what you can do with on that level of security. So you just bring in that NuGet package, you create a template object, get the template that you created with the liquid code and define the data and then say render and then you get your output as a string. So that's essentially how it works. And the nice thing that we found with the fluid is that you have all kinds of ways to insert logic in there, because sometimes you want specific conversions of data, or you want to expose. So for instance, I had a structure with tables and fields and records, like normal stuff, but I want to enable it in liquid that they can do a table name dot, and then maybe index as a with the row, and then dot give the fields, and then you have your value. So then you need to do some things like value converters in fluid. And it's very easy to implement the class in that, give it as an option, and then it's all being like processed in the, in the rendering. So you have a lot of flex flexibility there to even add something to the data structure and have a, an easy way to, to access the data.
Caleb_Wells:
I was wondering, and this kind of goes in line with what you're saying with, you know, how you're formatting the data and putting in tables. Does it
Martin_Tirion:
in
Caleb_Wells:
make
Martin_Tirion:
terms
Caleb_Wells:
formatting
Martin_Tirion:
of...
Caleb_Wells:
the emails for multiple clients harder or easier with Liquid? It's hard in general because,
Martin_Tirion:
So
Caleb_Wells:
you
Martin_Tirion:
what
Caleb_Wells:
know,
Martin_Tirion:
do
Caleb_Wells:
it's
Martin_Tirion:
you
Caleb_Wells:
a
Martin_Tirion:
mean
Caleb_Wells:
bit of a
Martin_Tirion:
by
Caleb_Wells:
pain.
Martin_Tirion:
multiple clients?
Caleb_Wells:
Well, you know, right, like Outlook desktop, Outlook mobile, Google Gmail. I'm not sure how, you know, you get these newsletter emails and they're very complex with lots of graphics. I don't know that you guys went that far, but in that same vein, does this help with that formatting and that workflow? No.
Martin_Tirion:
No, not at all, because it's just going from text to text. So for instance, we had recently a small site project where we also had a kind of a reporting engine. And then when we used it, the guys who were working on it were referencing a CSS file, an external file. And then it turned out when you send that through Outlook to mail, It doesn't work. So you have the same restrictions there. So then the liquid or the liquid parser doesn't solve that for you. I didn't hear of any liquid parser that would help you out with that because again, it's what the context of the template is that gets to the output, right? So, but you could do things, maybe smart things in there where parts of the template are data again. And when it's data, you can maybe like structure it and give a parameter like, I'm now sending it to this kind of browser or email package and then use a specific like output of that data to use that in the template. So you can do like software architecture stuff there to make it work and then have that work in different ways as well. So one of the things for instance, we did when we had to go from XML to an HL7 JSON format. So this is a healthcare like claim structure. We had to do data transformations there for having an MF like male and female in the data. And it has to be like real male or female. So you can have. liquid structures there again to do those transformations. So you can do this for other purposes as well, but you have to do it yourself.
Shawn_Clabough:
Is fluid something fairly new? I haven't heard about it before, so is it something that just came about?
Martin_Tirion:
I don't know how old it is. Let me see if there's any information there. So the liquid language itself is created by Shopify in 2006. So that's now about 16, 17 years old. Fluid, I don't know when he started.
Shawn_Clabough:
Okay, so yeah. Is it just for.NET Core or are there packages that also work with full framework?
Martin_Tirion:
Now, Fluid is for, I think it's a.NET standard library. So you can use it for.NET and for.NET Core. It doesn't support any other languages, but there are other liquid parsers that you can use for JavaScript or TypeScript or Python. There are other runtimes as well. But this was the ones we found. Yeah, well, most easiest in use for the.NET platform.
Shawn_Clabough:
I wonder
Caleb_Wells:
No.
Shawn_Clabough:
why not just use the Razor syntax, come up with a new language and a new syntax for your templates instead of just having something that people are already familiar with using Razor, but then just have the output be a merged text.
Martin_Tirion:
Yeah, so we tried it as first, but the biggest problem is now you're in a like a back end service in the.NET Core application and you just want to have an object and say render to it now and you just want to have back a string that you can use and I don't know, email or put in a database or whatever you want to do with it. So we were looking into Razor, but just calling into this. and have the files in there and then generate stuff, that's very complex. So that's where these kind of rendering engines are much easier because they're just like input the template, input the data and outputs a text and that's it. It's nothing more. So that's why then very easy to use for those scenario. And it's really comparable to what you see with Razer. So it's not that you have to learn a complete new structure.
Caleb_Wells:
So when you're working with liquid and fluid and.NET, and I see in your medium article, which will add the show notes, you have a fluid parser. How do you test the different data sets that you might be getting for that? Do you write unit tests for it? Do you just do manual testing?
Martin_Tirion:
No, we do a unit test because it's very easy to, so for instance, when we did the transformation from XML to JSON form, which is HL7 schema, so it's very easy to come up with an XML data set, get it through your code and the parser and know what the output is, and you can just compare it with like a pre-formatted JSON, or you can even go further and... pick up the JSON and see if the specific elements are there that you need. So that's what we actually always do. We always put it in unit test. So you can easily test that to make sure that your code still works. But the main thing is what you do with Fluid is when you provide your data, you actually give it a name. So for instance, when I started my first implementation, I always did a model object. So you had to do model. And then you get your table name or your object or things like that. And now we've, because we were importing parquet files and every parquet file is one table. So we had that combined in one model. But now we added also things like importing JSON files or. importing.env files where you have an environment setting, environment variable setting. You have different structures there. Now, depending on the kind of data, we have different way of providing that to the template. Of course, you want to test it in unit test that when you maybe change that name of the data, that still all works. So then it's very important to solve that in your unit test. Yeah,
Caleb_Wells:
It
Martin_Tirion:
but.
Caleb_Wells:
also looks like y'all created a VS Code extension
Martin_Tirion:
Yes.
Caleb_Wells:
to be able to test Liquid, I guess,
Martin_Tirion:
Yeah.
Caleb_Wells:
or to familiarize yourself with it.
Martin_Tirion:
Yeah, so it's a kind of inception because we for this project where we went from XML to to JSON. Actually, the template was used by people not too technical at a customer site. So we had to explain them first what what is liquid and secondly, so imagine that you have this big claims file of JSON, which can be like. very very large. So when you have this this in the big text file and with all this liquid code flying around for a person who is not too technical it can be very hard to to understand and maintain and make sure that it's still valid JSON that that comes out of it. So what I then did is I started this VS Code extension to actually use the technology that you also have with the Jupyter notebooks. where you can have your markdown and then have a block of code that you can actually execute and you see the result in your document. So I took this approach and now it's marked down together with liquid. So you have these blocks of liquid that you can have where you can test it. So you can also configure this file to tell it where is the data, mostly in a... So what I did is put it in a folder, you say where that is. So then the extension know where to pick up the data. And then you can just write your pieces of liquid and then see the output of it. And that made it possible to firstly create a document with the technology to explain what liquid is and to also have pieces of liquid there that you can play with and execute and see what happens with a standard data set. But then we also created a training for the customer. with that same extension that helped them how to build up a template for the HL7 JSON structure that they needed and to go piece by piece. And then they can pick up each piece and put it in a separate file because there's also an include solution in liquid. So where you can have a component that is in another file. So now you can structure your template like that. And then in that VS Code extension, you can have a block that only has that piece of code and you can focus on that and make sure that it works. And with real data, you can just run it and see what the output is. So that was the goal of that VS Code extension. And then recently I added support for JSON there as well and.env because we're using it in another project. So recently we used this in a project for... with Azure IoT Edge where we wanted to do. We for some reason we couldn't use layered deployments there, base deployment, but we wanted to make sure that we deployed two Edge devices ourselves where we know which modules we want to deploy. And actually we use Liquid for this as well with our own data from the database and then iterate over it and then output. a manifest in the JSON format, send it to IoT Hub, and then IoT Edge and IoT Hub do the rest of the magic of getting down all the data and the modules and run that. But then it's very easy again with this VS Code extension to test those pieces of code to make sure that it works. And you can then immediately document it. So that's what I meant with inception. It's the... liquid describing liquid.
Shawn_Clabough:
This has got me thinking. I'm wondering if you could take a template, combine it with liquid and the data and have the resulting merge sent out to the browser and. What I'm thinking of use case is like generating an XML file. So XML Excel file or something like that. So using just a standard Excel and then create a template that you then merge some data in and then send that out. It might be a lot easier to generate some custom Excel files that way versus the other libraries that you have to use all the different commands to build cells and workbooks and so forth. If you just got an empty workbook file that you would start with and just you know populate it with your data as you need it that might
Martin_Tirion:
Yeah,
Shawn_Clabough:
be a
Martin_Tirion:
yeah.
Shawn_Clabough:
cool
Martin_Tirion:
Yeah,
Shawn_Clabough:
way to use it.
Martin_Tirion:
so it's in this project that I mentioned about the for IoT Edge in the manifest. So one thing we did there, we created a base liquid template, where we put in some data and we merge it. And then we have this JSON structure. And then the next step what we did was we we used an implementation to read that into memory into an object model. so we can modify some stuff and then wrote it back to JSON because that's in essence what IET Hub is using to have this manifest file and push it there and have it do its work. But then it turned out when we were using that, it's like, so wait a minute, why are we using this strong template language, output JSON that bring it into memory in an object model, which is like really complex because that structure is not fixed. and then do your stuff there, and then generate JSON again. Why not do it all in the template? So we were actually working on now on migrating that piece of code back into the template because we already have the code and then generate JSON from that. Now, when you do that with Excel files, because it's like XML based, you can do that, right? The only thing is if the schema changes. you have to make those changes as well, of course. But well, even the XML structure is very well defined. So I think mostly for most solutions, you can do something that's sustainable for a long time. Yeah, so it's doable.
Shawn_Clabough:
Yeah, I think definitely just starting and just create the empty shell that has, you know, your columns and your headers defined and extra data that goes along with it and then just iterate over that inside the file to fill out all the different cells, you know, as long as you're trying to doing something really fancy and what you're trying to do, like you might be hard to do spans or joins and things like that. But other than that, I think it'd be pretty cool. So I might have to. to give that a try.
Martin_Tirion:
Yeah, and so my first experience with, because we were working on this HL7 big JSON structure, which was really a big file, and then I started experimenting with Liquid, and at first I was a bit overwhelmed because the JSON structure is already, you have to know where the braces are, and where an array starts, and the commas, and stuff like that. And now you're putting in calls to do it in an iteration. So you need to make sure that you have the commas in the right place to keep it like a valid array and things like that. So at first then you're a bit overwhelmed. You're like, is it maybe making it too hard? But once you get the hang of it, there are very easy ways to do that and to test if you're iterating over the collection, if you're at the last one of the collection. So you know that you don't have to put another like comma behind it, for instance. So you have to get a little bit over the first like a hard thing to use. But I found within a day or so you get the hang of it and then you get better and better at it. And it's easier to use all the time.
Shawn_Clabough:
Yeah, so there's a few hurdles at the beginning, but yeah, yeah. But I use classic ASP back in the day, so this should be just a
Martin_Tirion:
Oh,
Shawn_Clabough:
breeze
Martin_Tirion:
this could be
Shawn_Clabough:
for
Martin_Tirion:
it.
Shawn_Clabough:
me.
Martin_Tirion:
Yeah, so the nice thing of Liquid is there are a number of filters in there. So you can even do basic queries on tables. It's pretty basic, it's more like filtering. But the nice thing is even you can introduce your own commands in the language if you want. Of course, you need to support that with the right runtime for it. But when you do that, then you also understand how to use it, how you can get the size of a table, for instance, or how to transform a text to all uppercase or lowercase or split things into an array, for instance. So they're really like basic programming language elements in the liquid language itself. And then of course the implementation then depends on the runtime you're using and if the runtime supports it. But then you can do real magical stuff with it. I'm really an enthusiast of the technology because it opens more and more possibilities to have it in a very nice maintainable way. So let's see your Excel implementation, Sean.
Caleb_Wells:
There you go.
Shawn_Clabough:
So are there some good learning resources out there for learning the syntax and the language and how to use it?
Martin_Tirion:
So what I use myself is when you go to shopify.github.io slash liquid, that's the definition of the language. Of course they are like, like I mentioned, like Scriben, they have a kind of a, like a basic implementation of the language. So there are multiple implementations and multiple let's say versions of the language. But this is the one I've been using because this is where the the guys who came up with it. And they have a very good documentation there of what are the basic operators, for instance, what can you do with control flow, what are the implemented filters that you can use with some examples. So that's, for me, that's the go-to source to learn about what can you do with liquid. And then the other thing with fluid, with the runtime. They also added very nice documentation there how to use it in your code and how to also do some specific things with the value converters for instance that I mentioned. And I found when I was doing this I encountered a few things that were not supported or not working as I expected. So I did the PRs on the GitHub repo as well you get very fast response there. So that was a very good help for me as well. And the rest is, well, it's text that I already knew.
Shawn_Clabough:
So I guess one thing to be aware of is that if you did switch between different parsers, they might work off different versions of the language.
Martin_Tirion:
Yes, they might implement specific filters or not, or specific language constructs. The language construct isn't that complex, but some things evolve in that language as well, so you need to see if that's implemented with the runtime that you're using. Yes.
Shawn_Clabough:
The extension that you have for VS Code, is that just one parser or is it, can
Martin_Tirion:
Yeah,
Shawn_Clabough:
you
Martin_Tirion:
so
Shawn_Clabough:
set that
Martin_Tirion:
what I
Shawn_Clabough:
up?
Martin_Tirion:
actually did is the codes that I used in the previous project. And that's in a, so it's also on GitHub. So you can see it. It's a, it's a dot net application, a console application that I just built for both for Linux and for, for windows. And actually VS code extension under the hood just calls in that console app. to give it the data and then brings back the output string. It's not the ideal solution for a VS Code extension, because I would actually rather implement a language server, because then you can also do some things intermediate with getting your data structure, for instance, that you get help with IntelliSense there as well. But. But at that moment for the project, it was not the focus. But that could be a nice improvement to go to a language server and have this implemented as well. Now it's just every block just is base 64 encoded and sent to that console app. And then you get the output back and that's shown in the VS Code extension.
Shawn_Clabough:
Okay, so before
Martin_Tirion:
Thank
Shawn_Clabough:
we move
Martin_Tirion:
you.
Shawn_Clabough:
on to Pix, is there any last minute things that you want us to to know about liquid or the parsers or anything like that?
Martin_Tirion:
No, I would just encourage you to try to use it and dig into it. And it really more and more solves the problems we encounter as engineers all the time when you go to a new project. And most of the time, there is this templating mechanism in place when you really have a good look at it. So then look again at this template language. and see if it's something that you can solve your problems as well. And it's then very easy to share with like people who are not that deep into dev and know how to do.NET code,.NET code, et cetera, and just want to do this like simple template thing, but, but, but use it in a powerful way. So, yeah, it's, it's a good. Good thing to use and to test it as well and share it with others. So encourage people to use it.
Shawn_Clabough:
Okay, so if people have questions and they want to reach out to you, is there a best way to do that?
Martin_Tirion:
I'm on LinkedIn. My GitHub repo is there with the VS Code extension, so you can reach me there as well. Yeah, so feel free to reach out.
Shawn_Clabough:
OK, great. And if our listeners have questions and want to reach out to the show, they can get me on Twitter. I am at dot net superhero.
Martin_Tirion:
It's you.
Caleb_Wells:
Wait, wait, it's my turn. Dun, dun, dun, dun. I see I haven't done this in a while. And I'm at Caleb Wells Codes.
Shawn_Clabough:
Yeah.
Martin_Tirion:
That was Captain Underpants, right?
Caleb_Wells:
Heh heh heh.
Martin_Tirion:
Tra la la!
Shawn_Clabough:
That's a different thing.
Martin_Tirion:
Hehehe
Caleb_Wells:
Yeah, right.
Shawn_Clabough:
Okay, so let's move on to picks now. Caleb, do you wanna let us know what your pick is for this week?
Caleb_Wells:
There. So my pick is it's actually something that I kick started more than a year ago. I'm going to have had it for a little while. And just not getting the habit of using. But it's a hardware device that goes on your head or on your forehead. And it actually tracks your brain waves. to some extent, and then it's got a software application and you use them together to help build your ability to focus and to strengthen your brain. It's an interesting device, right? And of course they've got science back behind it and they've done research and stuff like that. But it's a cool device. and the software they gamify it so it's fun so yeah it's uh mindi
Shawn_Clabough:
Mindy? Like
Caleb_Wells:
Yep,
Shawn_Clabough:
in Mork
Caleb_Wells:
M-E-N-D-I.
Shawn_Clabough:
and Mindy? Oh, Mendy.
Caleb_Wells:
No,
Martin_Tirion:
No, no,
Shawn_Clabough:
Man.
Martin_Tirion:
no.
Caleb_Wells:
no. Ha
Shawn_Clabough:
Ha ha ha ha.
Caleb_Wells:
ha.
Shawn_Clabough:
All right, all right, we'll check it out. All right, Martin, what's your pick for us?
Martin_Tirion:
Well, so a few months ago I picked up piano lessons again, because I already did a little bit of piano, but I was always intrigued by jazz and I just wanted to learn so there should be some kind of structure here, right? Because jazz always sounds like doing whatever you want to do, but it always sounds like amazing. And the nice thing is that I took lessons from a jazz pianist and she started explaining to me that there's actually a structure here. So, and of course I'm a nerd, so she told me like go practice your chords, right? So I just couldn't just practice chords. So I wrote a UWP app, put in my... so I can have my keyboard, plug it into my PC. I get all the MIDI notes in there, I capture the MIDI notes, but now you have to think about what makes a chord a chord. And that struck me that it's all mathematics. It's everything that you do there, there's a structure. And that's actually pretty easy to do. And the fun thing is when you then start writing code, you have to like try to get that... theory of how a chord works into code and then see if you can bring that back on the screen so you can show what chord are you playing. And then of course I started with the bass like three notes but now I can also do with seven chords and I'm now working on like on the tensions there. But then the fun thing was for me everything is just about structure. So there's this circle of fifths that's magical when you use it. And so that made it a lot of fun to me because now when I'm, I already understood a lot of when I listen to music, there's a structure there, but now you more and more see what the structure is and what you can do with it. So it's very fun to see that you can have like real structure and then like implement chaos with it called jazz. So, yeah,
Shawn_Clabough:
Yeah.
Martin_Tirion:
so I don't have a link for that, but. Go have fun with piano and the circle of fifths.
Shawn_Clabough:
You know, you remind me of John Skeet.
Caleb_Wells:
Nice.
Shawn_Clabough:
You know, he got an electronic electronic drum set and he could couldn't just leave it as a drum set. He had to start writing software to make the drum set do things that it wasn't supposed to originally do in this and customize it and do this and do that. So, yeah.
Martin_Tirion:
Maybe you can write liquid coat on your drums, kids.
Shawn_Clabough:
All right, John, if you're listening, you know, let's, let's see some liquid code
Martin_Tirion:
Yes.
Shawn_Clabough:
on your electronic drum set. So also jazz reminds me there's a big jazz festival at the university near where I live. And so definitely familiar with a lot of different types of jazz. And of course. Just about everybody in the US is familiar with the small little town that I live in here now with the in the news. So a little town of Moscow, I know. So it might even be international news, but definitely everybody in the US and it is a very small town. But it's unfortunately got on the news for bad reasons. So, but that's that's another story. So My pick this week is along the lines of an old pic that I did where I was looking for anonymous email systems so that I could sign up for things and have them go to different email addresses so I could have an email address for conference and an email address for all these other sites that I sign up for temporary things. But then I learned recently that if you use Gmail or Outlook, you already have unlimited email addresses. And what I mean by that is you have unlimited email addresses that come to the same location. So you don't have to open up different accounts and things like that. So if you have Outlook and like mine would be.NET Superhero at Outlook.com. If I signed up for something, I could do.NET Superhero plus blah, blah, blah at Outlook.com. And wherever I signed up, think that that's my email address, but it comes to the same inbox as that superhero at Outlook.com. So and the really cool thing is you can then filter on that. So if you start getting a whole bunch of spam emails from this certain place, you can look at the email address that they're sending to and figure out, oh, that's where I signed up for that. And they sold my email and this and that. And you can just filter it into junk or so on and so forth. So, yeah, if you want to start filtering by all those types of things, just use plus and wherever you signed up for. And that'll tell you where it came from.
Martin_Tirion:
Nice, it's a nice one. So that's the reason you cannot use a plus in your normal email name, right?
Shawn_Clabough:
I guess, I heard you could also use other symbols, but the only one I've been able to get work is the plus. So yeah, I thought that would be really weird that, you know, what if somebody else already had something that had a plus in it or whatever, but I guess
Martin_Tirion:
It got drunk
Shawn_Clabough:
not.
Martin_Tirion:
right at the last sign.
Shawn_Clabough:
Yeah, yeah. All right, guys, great show. Thanks, Martin, for coming on the show. It was nice to
Caleb_Wells:
Yeah.
Shawn_Clabough:
learn about you and meet you and learn about liquid.
Martin_Tirion:
Yeah, thanks for having me.
Shawn_Clabough:
Alright, and we'll catch our listeners on the next episode of Adventures in.NET. Bye.
Caleb_Wells:
I don't know.
Martin_Tirion:
Bye.