S07E01 - LinqPad and Building Developer Platforms with Joe Albahari
Sponsors
Support for this episode of The Modern .NET Show comes from the following sponsors. Please take a moment to learn more about their products and services:
- RJJ Software’s Software Development Services, whether your company is looking to elevate its UK operations or reshape its US strategy, we can provide tailored solutions that exceed expectations.
Please also see the full sponsor message(s) in the episode transcription for more details of their products and services, and offers exclusive to listeners of The Modern .NET Show.
Thank you to the sponsors for supporting the show.
Embedded Player

The Modern .NET Show
S07E01 - LinqPad and Building Developer Platforms with Joe Albahari
Supporting The Show
If this episode was interesting or useful to you, please consider supporting the show with one of the above options.
Episode Summary
Joe Albahari, the author of “C# in a Nutshell” and the creator of LinqPad, joined the podcast to discuss the evolution and features of LinqPad in the .NET ecosystem. He described LinqPad as a high-performance code scratch pad for .NET developers, highlighting its efficiency compared to traditional development tools like Visual Studio. Joe explained how LinqPad started 16 years ago with interactive Linq queries in C# 3 and evolved to cater to various developer needs like experimentation, benchmarking, and script-oriented tasks.
The conversation delved into the challenges of feature prioritization and maintaining a simple user interface without overwhelming users, likening it to driving a vehicle efficiently with only essential gauges visible. Joe emphasized the importance of managing user expectations and ensuring the discoverability of features in LinqPad’s UI. They discussed how LinqPad acts as both a tool and a platform, enabling developers to solve coding challenges and integrate seamlessly with larger projects efficiently.
The interview also touched on the unique runtime of LinqPad, making it conducive to scripting scenarios and emphasizing its focus on additional services tailored for code scratchpad use. Joe shared insights into the advantages of LinqPad over SQL, particularly in generating association properties for querying databases. They discussed the potential development of a cross-platform version of LinqPad using Avalonia, highlighting the challenges in porting features due to the existing codebase.
Moreover, they explored building a debugger in LinqPad, emphasizing the use of asynchronous functions in C# for development. Joe shared their positive experience in building UIs in C# for an AI chat engine within LinqPad, citing enhanced productivity. The interview also touched on incorporating innovative features like a Vim emulator and navigating the evolving landscape of Microsoft’s UI frameworks from Xamarin to .NET MAUI.
They delved into technical aspects of LinqPad, including its utilization of Roslyn APIs and expression trees for method invocation. The interview highlighted the interactive learning approach of LinqPad’s tutorial system and stressed ‘dogfooding’ in software development for better outcomes. Practical advice on using LinqPad, exploring interactive samples, and engaging with the community was also shared, showcasing the versatility and productivity enhancements of LinqPad in the programming landscape.
Episode Transcription
You can use Linq to write database… to query a database and I thought, "well you can interactively write queries in SQL using tools like SQL Server Management Studio, so wouldn’t it be great if you could do the same thing in Linq?" So I wrote a tool to do that—that was LinqPad—to as you can just type Linq queries in interactively. And then once I released that it became quite popular and there were a lot of people using it, including a lot of folks at Microsoft were using it. And I was getting a lot of feature requests
Welcome friends to The Modern .NET Show; the premier .NET podcast, focusing entirely on the knowledge, tools, and frameworks that all .NET developers should have in their toolbox. We are the go-to podcast for .NET developers worldwide, and I am your host: Jamie “GaProgMan” Taylor.
In this episode, Joe Albahari joined us to talk about LinqPad—yes, that LinqPad. The one tool which makes all .NET developers lives easier. Don’t worry if you’ve never heard of LinqPad, as Joe and I talk about why you should use it, and how it can make your .NET life way more productive. We also talked about handling feature requests, and building a development platform.
When something doesn’t work correctly, it can be really hard to figure out what’s going on. Sometimes it just requires experimentation. And that’s something I dislike. I always like to try to understand exactly what’s going on underneath and then try and from that understanding make something work. I don’t just like trying random stuff.
We also round out our conversation by taking some questions from the community, which Joe graciously agreed to answer for us. Don’t forget that you can join the community (for free) over at dotnetcore.show/discord where you’ll be able to connect with other listeners, share interesting links, propose episode ideas, and suggest questions for guests.
After recording, Joe and I spoke in depth about the possibility of a cross-platform version of LinqPad; later that day (we recorded on May 2nd, 2024), I sent off an email introducing Joe to the team at Avalonia, and a few weeks before this episode dropped Joe announced a version of LinqPad which is coming to macOS. How cool is that?
Anyway, without further ado, let’s sit back, open up a terminal, type in dotnet new podcast
and we’ll dive into the core of Modern .NET.
Jamie : [0:00] So Joe, welcome to the show. I didn’t mean for that to rhyme, but it did. So there we are. It’s fantastic to be chatting with you today. I’m a big fan of the product we’re going to talk about. We’ve got some community questions from someone who’s a big fan of the product we’re going to talk about, but welcome to the show.
Joe : [0:18] Thank you, Jamie.
Jamie : [0:20] My goodness, it’s wonderful to have you here. Wonderful, wonderful. Yeah, so we are going going to talk about a little bit about LinqPad and building almost like tools as a platform in .NET and things like that. But I thought before we did that, I wonder, could you perhaps give the listeners a bit of an intro to yourself? Is that all right?
Joe : [0:41] Yes, certainly. Yeah, I’m the author of “C# in a Nutshell” from versions 3 to 12, and the creator of LinqPad, the popular .NET Scratchpad, which is, that’s where I spend most of my time. So if you haven’t heard of LinqPad, it’s, give a really kind of quick summary. It’s, if you think of a .NET code Scratchpad, and a lot of people ask, you know, “what is a Scratchpad and why would I need it? " I guess to, by way of analogy, if you imagine that a Visual Studio, any kind of project-centric uh .NET development tool is is like a a big truck it’s very versatile and can carry a lot of stuff um a code scratch pad it’s like a high performance motorcycle that can weave through traffic get you somewhere quickly; so um yeah in a nutshell that’s what uh that’s what LinqPad does
Jamie : [1:40] Amazing amazing and uh and and you wrote the the “C# in a Nutshell” books as well I can imagine that, because I’ve seen the jokey images of like “JavaScript, just the important parts” and JavaScript.
Joe : [1:54] That’s right.
Jamie : [1:55] Like they’re really thin and really thick books.
Joe : [1:57] That’s right. And the nutshell is a coconut. It is a nut. It’s just a really big nut. It covers the language and the CLR and the BCL. That’s why it’s so big. If it just covered the language, it would be a third of the size. So it’d be actually okay. okay but people you know they they want lots of they want lots of value for you know by the book, there’s a lot of stuff in there so it’s ended up being big because it’s takes on all these extra topics Sure.
Jamie : [2:25] Sure. And I like, um, I feel like C#, the language can’t easily be divorced from the CLR, right? Because obviously, you know, so I say this, there are, there are listeners who are of different levels, right? In their, in their .NET, the C# journey. Um, for those who don’t know, obviously C# is compiled to, um, a, an intermediary language when you hit build and when you run it it’s then sort of recompiled just in time to the bytecode for your machine and the CLR is the thing that runs all of that stuff for you uh that’s like a super 10,000 foot low uh detailed view of it. But the point I’m getting at which I’m doing really badly of getting at, um is I suppose that C# and the other CLR languages can’t easily be divorced from the CLR because you kind of need to understand a little bit, not a great deal, but at least a little bit of how the CLR works in order to write optimized C#, F#, as well as VB?
Joe : [3:28] Yes, even VB. That’s a really good point. There isn’t – and if you’re writing a book on this, you can’t completely segregate them. You kind of got to dovetail them because there is overlap, right, between those things.
Jamie
:
[3:47] 100% yeah um I think is it isn’t it um Scott Hanselman who says that, “it’s always good to know a little bit about the next layer down,” um so that then you know kind of where your code is going before it’s running um and if you that’s right you know if firstly if you know there’s another layer down that’s great then if you know a little bit about how your code runs on that next layer down you can then figure out, “oh cool so this loop will you know because it’s a simple loop maybe Maybe it’s a for loop. This can actually be, by the compiler, can be turned into a series of statements that just, because if all I’m doing is a standard for int I = 0
and just iterating over an array using brackets notation, you know, if the compiler already knows how long the array is, then it could probably convert that instead of having a for loop that loops around a million times. " It could probably say, “well, I’ll just write a million lines of code that just instead of using i, it goes 0, 1, 2, 3, 4, 5 until the end of your counter, " right?
Joe : [4:49] It does a remarkably good job of that kind of optimization. And interestingly, in LinqPad, there is an IL tab. So any code you write, you can click that IL tab, and it will give you three windows side by side. On the left, it shows you the conversion into to C# 1.0. On the middle tab, it shows you the IL translation. And on the right-hand side, it shows you the x64 or x86 translation. And as you move the mouse through it, it then highlights each of the corresponding statements. So you can see everything from the lowering to C# 1 to the IL right down to the machine code. Right.
Jamie : [5:34] Right. Okay. Yeah. And, and, and yeah, I’ve used that in the past and gone, “wow, this is crazy,” that it’s just to see that journey. Uh, I suppose we’re jumping a thousand steps ahead. So, uh, but that’s that, yes, you’re absolutely right.
Jamie : [5:50] You need to know that stuff and it’s great that LinqPad includes it. So let’s, let’s step back a little bit, um, and talk a little bit about LinqPad then. Um, so, uh, for those who haven’t used it, I wonder could you give us like a an elevator pitch I know you talked about how it’s a bit of a scratch pad but I wonder could we dig into less of an elevator pitch I suppose dig into the weeds a little bit; like um you use that motorcycle analogy right, “you can weave in between the traffic, “so you you know I’m seeing that if I want to test out how do I get this information from a collection I don’t actually have to write a massive app that gets a collection into memory so I can and I can mess with it. I could probably, you know, I’ve used LinqPad, so I’m going to assume a lot, but I can use LinqPad, point it out in my collection, and then just start playing with that collection, right? I don’t have to write the code around it.
Joe : [6:38] That’s one of the things it does is it has a powerful visualizer. So it converts pretty much any kind of .NET data into, gives it a nice presentation. So it will present it as tables and expands all the properties of objects. So it’s one of its use cases is to do that. I guess it’s probably interesting to think about the history of how it came about. Because when it was about 16 years ago when I first wrote it, and I had one thing in mind, which was that I wanted a way that; a Linq had just come out at that time. A C# 3 had come out and a Linq had come out, and you can use Linq to write database… to query a database and I thought, “well you can interactively write queries in SQL using tools like SQL Server Management Studio, so wouldn’t it be great if you could do the same thing in Linq?” So I wrote a tool to do that—that was LinqPad—to as you can just type Linq queries in interactively. And then once I released that it became quite popular and there were a lot of people using it, including a lot of folks at Microsoft were using it. And I was getting a lot of feature requests
Joe : [7:57] What was interesting is that people weren’t just using it for Linq queries. They were using it as a general purpose code scratchpad. So rather than creating kind of a new console project in Visual Studio, they would use LinqPad to run like test scripts to do experimental explorational code or to figure out how to use an API for benchmarking or build scripts, automation tasks, data mining, data cleansing.
Joe : [8:28] And people were also using it to write new code. Because one of the things that happens if you’ve got a large solution, a large software project, you end up with a solution with lots of projects, and there’s inevitable build time involved. So you make a change where you want to write some new code, you’ve got to then hit F5 or Control+F5 to run it, and you’ve got to wait for this thing to compile and there’s this lag before you can see the outcome so what people were doing to get around this they were going to LinqPad they would reference the output assemblies of their VS projects and then start writing new code that uses those types and then they could get instant feedback, no build times, and all the ergonomics and visualization features of LinqPad. And then once that code was working, they’d paste it back into Visual Studio and save a whole lot of time.
Joe : [9:29] And that was kind of how it came about, this code scratchpad, because the whole idea of a code scratchpad is it’s all program-oriented, not project-oriented. So, for instance, with a single key press, you can clone a query and test out two or three variations of your project at the same time, without having to save anything to disk. You don’t have to save any of those. You can just press it again and again and create all these variations, test them out, see the code alongside the results. And yet there’s no creating project folders, no creating project files. And it makes it, it’s really quick and easy to get the stuff done. So once I discovered this, this is how people were using it. And I spent the next 16 years adding features and optimizing the ergonomics of LinqPad, just for that kind of scenario, for where you want something that’s program or script oriented rather than project oriented. So that kind of comes back to that analogy, like having a big truck as Visual Studio or any tool that’s project oriented versus having a motorcycle. And I figure that if you can, anytime you want, you can switch between the truck and the motorcycle, you can get off one and get them to the other, anytime you want, you’re going to be a lot more productive
Jamie : [10:57] That makes sense right because then you’re effectively “Indiana Jones"ing your way through the the code base right you’re in the truck for when it makes sense to be in the truck and then you you know you see the bad guy on the motorcycle you jump out the window kick him off the motorcycle and speed off down the street right that’s that’s exactly.
Joe : [11:13] It yes truck
Jamie : [11:14] Eventually catches up to you.
Joe : [11:17] Hopefully you don’t fall off your motorcycle
Jamie : [11:20] Absolutely. Ao then so uh one of the things that I’m interested in then if you’re if you’re building this tool um and and you’ve been building it over 16 years and it’s a brilliant scratch pad then I can imagine that there are, it has lots of different features and that for every single user there’s perhaps a different either either killer feature or set of killer features. Like, I wonder if you can talk to like how you go, if there’s someone listening in going, “I’ve got this great idea for a tool and it’s going to be a wonderful tool. It’s going to have a bunch of features, but I don’t know how to like prioritize, which feature to build or perhaps how do I prioritize supporting users if they all prefer different features”, right? Because I feel like that’s something that you will have probably had to deal with whilst working on LinqPad, right? it so uh can you speak to that at all.
Joe : [12:14] Umthere is a challenge when it comes to um when a project reaches a certain size and you add a certain number of features um you need to make sure that uh those features are discoverable but they don’t overwhelm the user interface. I think it’s a big trap when when you uh you try out a new product and it’s It’s so cluttered and there’s so much going on, it just scares you off. You want to create a user interface that draws people in, that all of the major use cases are there and obvious. It’s simple and clean. At the same time, you’ve got all these features that people have requested, these very useful features. They’re there, they’re discoverable, but they don’t get in the way, they don’t clutter the user interface. It is a challenge getting that right, Right. And there’s a lot of tricks that you learn along the way on how to do that. Excellent.
Jamie : [13:14] Excellent. And I guess of that, um, so there’s, there’s tricks to, to building a user interface that doesn’t get in the way. Um, and I suppose there’s also tricks to, um, perhaps managing the expectations of those users, right? Um, there’s, there’s, there’s a, it’s come up recently. So we’re recording this, uh, 2nd of May, 2024. And I think it was only a few weeks ago. It came up on X or Twitter or whatever we’re calling it; “the artist formerly known as Twitter, " I suppose. And somebody had posted a screenshot of an app called the bulk renaming utility and you know this is a fantastic piece of software you know it’s a Windows piece of software you open it up you say, “rename all of these files,” except that it looks like there’s about a million different controls that you can do that you can use in the UI to change how it renames things. And this isn’t me trying to shade on that app it’s a brilliant app it’s just for my personal tastes the ui is a little bit busy um and I feel like what you’re kind of saying here is you have to make sure that the UI isn’t as, [that it] is as unobtrusive I guess as possible right
Joe : [14:21] Yes. Everyone is going to ask for their favorite feature to be to be made very prominent and to have menu items and toolbar items and so on but um you need to think of the the bigger picture and and make sure those features are discoverable. But generally, I think a good toolbar in an application expresses the essential state of what’s going on. So by looking at it, you’re getting information and the most important use cases, the operations are there. And yeah, that’s an important, yeah, it’s important to keep those two things balanced together.
Jamie : [14:58] Sure, sure.
Jamie : [14:59] And I guess using your analogy earlier of like a truck or a lorry and a motorcycle, the user interface for those two devices, I suppose, will be, there’ll be similar things, right? You’ve got, you’ve got a speedometer telling you how fast you’re going. Maybe if you, you know, maybe if you’re driving manual or stick, you’ve got a rev counter so that you can figure out when you should be changing gear. You may have a fuel gauge and maybe a temperature gauge. But you won’t also have like brake temperature gauges or, you know, weight load, right? Because those things aren’t exactly pertinent whilst you’re moving, right? It won’t have a vehicle height marker. Because you should probably know how tall your vehicle is before you set off, right? And so I think you’re right there that the most important thing is to have, the most important things in the UI are the things that give the user information they need right now, right? Right.
Joe : [15:54] That’s it.
Jamie : [15:56] Amazing, amazing. Because like I’m thinking of uh so I know a fellow uh uh listener to the show, fellow .NET developer, and a previous guest on the show Cliff Aguis works as an airline pilot; and like I’ve seen the cockpits of those things that does not look like they’ve gone with the most pertinent information in the user interface.
Joe : [16:17] Yes. Got very different requirements that go yeah they’re not trying to attract new users so, “come fly our plane and buy one for fun.” They’re not trying to do that it’s a very different set of priorities to have but then
Jamie : [16:30] I suppose if you look at I don’t know if uh folks who are listening or indeed you Joe have had the chance to look into a uh a cockpit for a plane that you probably that a person could buy and fly around as a hobby the the user interface…
Joe : [16:44] I have looked yes. I’ve looked
Jamie : [16:45] Way simpler right.
Joe : [16:49] Yes the ICON A5 think, was was one of the famous examples of that. That they tried to create a fate a plane that would be fun to fly they’re trying to appeal to a kind of a sports and enthusiast uh in that with that plane. A few people have died flying it but the planes actually isn’t that dangerous I think it’s just people you know get overconfident; but um yeah it is possible to create planes like that
Jamie : [17:14] Yeah where that user interface is much more simplified; because perhaps you know a person doing it as a hobby or or as an enthusiast probably doesn’t need to know all of the information that a commercial airline pilot needs to know at a moment’s notice, right?
Joe : [17:30] Yes. Yes, that’s partly the case, but also they can go to a lot more effort to optimize the user interface if they’re creating that kind of plane. In that if you’re a commercial pilot and you’re doing it for a living, you expect it to adapt around the plane.
Jamie : [17:53] Absolutely. Yeah. Excuse me. Um, uh, um, obviously listeners, we have veered away from, uh, you know, LinqPad, but we’ll come back to it. Obviously we’re hoping to use this metaphor to, to just, just to underline the fact that, “yes, you can have every single control ever on the user interface, but do you really need it? " Right. Oh my goodness.
Jamie : [18:17] Um, so, so we’ve, we’ve talked a little bit about, building that sort of user interface out and making it pertinent to the user at the time. And we’ve talked a little bit about the fact that users, especially of LinqPad, will have different expectations of what their killer features are versus what everyone else’s killer features are, right? So for instance, I use LinqPad a lot to figure out the optimum um, uh, query pattern for the data I’m looking at, you know, uh, whereas someone else might be looking at, like you were saying, “I’ve got my binaries, I’ve exported them. I want to build something that interacts with them. I can do that in LinqPad and then copy the code over to another, like a solution area and get to that.” Both perfectly viable, uh, uh, problems to solve; both perfectly viable killer features. But likely both completely different in the way that they’re implemented, right?
Joe : [19:18] Yes, that’s it.
Jamie : [19:21] Amazing. So then, okay. So let’s talk a little bit about, and I hope you don’t mind me, I’m probably not inventing this phrase. I’ve very rarely invented anything new. The idea of building a tool as a platform which is what I see LinqPad as. So I see I see LinqPad as it’s a tool but also like you were saying it’s a platform: you’re jumping on the motorcycle to get you through to the solution quicker.
Joe : [19:47] Yes .
Jamie : [19:47] So then you can then put that solution back into your into your solution. I’m very wary that I’ve just said solution like 15 times, but hopefully everyone’s getting what I’m talking about. So um so we you mentioned a little bit about, you touched very lightly on sort of the history of it and how it came about when Linq came about and how um you started building it in one direction and then you saw other people using it in different ways. But like um I wonder if you could talk about perhaps the original idea um for like maybe was it just a case of you heard of this thing called Linq that was coming out and you were like, “cool that’ll be awesome. I’ll build a a tool to help people do that. Cause it’s kind of confusing. " Um, and then maybe could you talk a little bit how of how it’s maybe evolved over time and maybe the history of it.
Joe : [20:37] Sure. It’s an interesting thing you mentioned as thinking of LinqPad as a platform. I wouldn’t have thought of it like that, but it is in a sense, it is a kind of platform in that it provides a runtime, which you don’t ordinarily get. So if you’re using, doing a standard .NET project, the whole idea is that you’re creating in the end, an executable or a library that can run by itself without the environment, right? Just needs the .NET environment, doesn’t need Visual Studio or code or anything else. But in LinqPad, you do have, you can interact with the host, the environment, and you have this, also this runtime that provides all these extra services. So in a sense, it creates a platform. So, you know, things, for instance, it has things like an integrated password manager, which can look after your protect API keys, so you’d have to store them in your source code and built in a OAuth engine forself-authentication , two-factor authentication so on. So it um the idea is that if you uh code using those things it’s it’s more conducive to scripting scenarios rather than creating standalone applications
Joe : [21:55] so in that sense it’s um it is a platform.
Jamie : [21:58] Right, right . So then um what about the like the history of how it’s evolved over time then? Because I can imagine that um you know uh I’m gonna stand here and say I don’t really know a great deal about Linq itself um and I don’t feel like that has evolved. It’s just gotten more optimized like has LinqPad evolved because Linq has evolved or because there’s just been new tools added and new things and, “hey would be great if I could have a secrets manager,” and “it would be great if I could have a connection string manager,” and things like that.
Joe : [22:33] Yeah it’s um Linq hasn’t so much hasn’t changed uh fundamentally that much of editing methods and so on. But um it’s LinqPads evolved around all of the extra scenarios involving uh code scratchpad scenarios It’s mainly evolved around those.
Joe : [22:52] And in terms of Linq itself, and some people still ask, “what’s the advantage of Linq over SQL? " And there’s a number of them, but I think probably the killer one is that all your association properties are automatically generated. So you don’t need to join. You almost never need to join tables. So you can just query right through those association properties effortlessly, and that’s one of the reasons that Linq is more productive for querying databases.
Jamie : [23:26] I see. I see. Um, excellent. Um, no, I, I, I agree completely that, um, that Linq is way better than using, well, okay. Right. I think, um, for the average .NET developer who maybe has a little experience with SQL, then in my opinion, Linq is way better, more effective, more productive for that developer than going away and scripting out a, a, a series of SQL statements with a whole bunch of joins to be able to extract that data and “go oh right yep nope that’s why the problem is there is a null in that column and it shouldn’t be null; but it’s nullable what have we done how did we do it?” Whereas you know in LinqPad or indeed in Linq I can just go select you know either table table name dot select dot where column name is null or something like that right it’s it’s super simple it then joins everything together. No I i agree with that um uh no I I absolutely agree with the fact that it’s way more productive for those who have experience with it. Like there might be .NET devs who are maybe long in the tooth SQL DBAs as well. And they may be like, “actually doing the SQL is more productive. " And I’m very much a case of, “hey, use whatever tool works for you, right? If you want to go ahead and write the SQL and do it yourself, totally fine. Go do that.”
Joe : [24:44] Yes. I mean, I use both because sometimes it is better to use SQL. There’s some cases it does work best. So I just use whatever works best in the scenario.
Sponsor Message
The following is a paid advertisement.
Welcome back, .NET enthusiasts! This is another episode of The Modern .NET Show and today we have a unique collaboration with industry expert Jamie Taylor. Known for his insights on our show over the past seven years, he now brings those expertise to your doorstep as an external contractor at RJJ Software in both B2B and C2C engagements.
Jamie has been instrumental in helping businesses across the UK harness their digital potential through custom software development tailored to their specific needs. For our US-based clients, he's facilitated transformational change by integrating cutting-edge AI technologies into their systems - all while maintaining his stellar reputation as a thought leader in the field of .NET and software consultancy.
Whether your company is looking to elevate its UK operations or reshape its US strategy, Jamie can provide tailored solutions that exceed expectations. Reach out through RJJ Software today, and let's unlock your business' digital potential.
The audio for this advertisement was created with AI
Jamie : [24:51] Excellent okay um so we do… I thought it would be a good time now just to talk about something that one of our community members has brought up: So I reached out, when we had put this episode together, I reached out to the community and said “hey if you got any questions for Joe, please do let me know,” and Devin who is a huge fan of LinqPad has got a couple of questions. And I thought this one might be useful because it kind of fits in a little bit with the history and and how LinqPad has evolved and maybe this is the next step.
Jamie : [25:26] This question is, you’re not, being held to anything. Folks, we are not revealing any information here about where LinqPad is going, I’m just asking into the ether a question from Devin. So Devin has said, “is there a chance of perhaps a cross-platform version of LinqPad? I use it every day but there are a lot of people who can’t because they’re not on Windows. Based on some of the UI rendering features, it looks like you’re already experimenting with Avalonia. Is that the case?”
Joe : [25:55] That’s the case. I’m hoping that Avalonia will provide a way forward with that. A lot of it’s written in WPF, and it’s a relatively easy-ish transition. It’s not easy, but it’s an easy-ish transition from WPF to Avalonia. So I’m hoping that’s going to become possible. But there’s a lot of – because the product has been 16 years of work, There’s a lot of features that all need to be ported across. And so some things are much, much harder to implement than you would think. And something, for instance, like showing the data in grids is unbelievably difficult to get that to work. And to do that, to port that to another, to work on our Macs would be, it’s, I don’t even right now know how it could be done, but there is a, sure, there’s a way, but it’s very, very difficult to port those kinds of things across. It relies on numerous low-level Windows Win32 API calls and all of that has to be done. And it’s something that I would like to do and I’m putting effort into that, But at the moment, I can’t give any particular time frame as to when or if that’s going to happen. But it’s definitely something I consider I would really like to do.
Jamie : [27:21] Sure, sure. I mean, it makes total sense, right? .NET’s gone cross-platform. But again, it’s as and when. And remember, folks, it may just be Joe who’s working on this on his own. One developer, perhaps. And we should always be respectful of one developer’s time. We recently had the um xz was xz and zv I can’t remember the name of it…
Joe : [27:46] Yes I remember that
Jamie : [27:49] …We’re into ssh yeah; which relied on the fact that and that you know I hope not to trigger anyone but that particular attack, which took 14 years to implement relied, oh was it 14 a number of years I want to say yeah the the timeline for it is ridiculoust relied on the fact that the the sole developer who was working on it was suffering from mental health issues, right? That’s how that attack happened.
Joe : [28:15] Yes. You also don’t know really who that developer was. Yes. Yeah. Yes. I don’t think we know entirely who that, who that, who even if it was a person or an organization. So it was a bit of a mystery as to, as to what was actually going on with that. But it was, it was clever. I’ll give it that it was clever, but obviously very malicious.
Jamie : [28:36] Yeah and and the point that I’m getting at here folks is: obviously you know if Joe’s working on this by himself you know cut him some slack right. He’s a normal person too, he needs to have some time off and figure some things out himself.
Joe : [28:51] Sure
Jamie : [28:53] So, okay. So we’ve talked about, uh, Devin’s question. We’ve talked about, perhaps there might be a cross-platform version in the future. If some of the WPF stuff can be ported across easily because it’s using some win 32 APIs. Um, what about, um, so let’s talk about, uh, big technical challenges then. Cause I always like to, um, talk to people about some of the challenges that they’ve, they’ve seen and overcome. And maybe if, you know, if you’re willing to share some of the clever things that you’ve had to do to make LinqPad evolve over time rightSo I wonder what were some of the biggest technical challenges you’ve faced when you’ve been developing or indeed in maintaining LinqPad?
Joe : [29:34] One of the hardest things to write was a debugger because LinqPad itself doesn’t, for LinqPad a debugger is not as important as it is in Visual Studio you can manage to do a lot of stuff without a debugger because of the way it works. But it’s still sometimes really useful to set breakpoints in single step through and have a watch window. And writing a debugger is really difficult because it’s a kind of an arcane API. There’s not many people using that API, not a lot of documentation on it. It’s very difficult. And the only thing harder than writing a debugger is debugging a Debugger.
Joe : [30:16] When something doesn’t work correctly, it can be really hard to figure out what’s going on. Sometimes it just requires experimentation. And that’s something I dislike. I always like to try to understand exactly what’s going on underneath and then try and from that understanding make something work. I don’t just like trying random stuff. But sometimes with debuggers, you have to sort of, with those arcane APIs, you sometimes have to try random stuff. of. It’s also, debuggers, it’s a bit like a kind of a sausage factory in a way: you don’t really want to know how it’s made. So with the stuff the debugger has to do in order to work, it’s pretty horrific. It has to spin a particular thread in isolation and get that to execute a function just to get the value of a property. And there’s so many things that can go wrong, and it has to abort threads as well and suspend threads. So it’s a lot of fun getting that to work. And the debugger I wrote, I wrote it just when the C# 5 was coming about. So I was able to use all of the asynchronous functions in C# to do that, which was really good because the whole debugger is completely asynchronous, so it never freezes ever under any circumstances. And that was very satisfying, writing that.
Jamie : [31:37] Nice. okay um can you talk a little bit about like your… I know you said they’re like the high level stuff about you know building a debugger is hard and you know debugging debuggers is you know, “Quis custodiet ipsos custodes” which is fake Latin for “who watches the watcher?” so who “debugs the debugger?” and like playing around with threads and aborting and pausing and halting and all that kind of stuff; is there any um advice you can give to folks who are like, “i want to build a debugger” or is like the advice, “don’t build a debugger”?
Joe : [32:11] Most people won’t need to build a debugger, but I mean, I guess to look for other, if there’s existing code or libraries that can, that could help with that, but it’s, yeah, I mean, there’s no way around some of that pain, you know, involved in that, in that, but it’s, it’s fun. I enjoyed it. And I mean, some of the other challenges I’ve had are is getting, being very, I need to produce a lot of code quickly to, to be very efficient in how I code. So, and there was a feature I needed, I implemented recently to create an AI chat engine, which I’ve integrated into LinqPad. So it connects to your ChatGPT account and it uses the OpenAI API, or it can use the Azure OpenAI API. And so you can ask questions about your code and then it will give you responses and then it lets you then merge those responses, those changes into your code and shows you what like a source control different style to show what it’s going to do in writing that I needed to write quite a lot of UI and write it quickly and efficiently; so um I used a um I did actually I wrote it in LinqPad I wrote that whole uh ai user interface in LinqPad and because I’m using wpf, wpf normally you use xaml to create a user interface.
Joe : [33:36] And XAML is… It’s, in a sense, it’s easy. In a sense, it’s hard. XAML, because it’s not a programming language, you end up with a lot of repetition and you end up with an impedance mismatch between the XAML and the C#. So I wrote a handful of extension methods and I was able to create the whole user interface entirely in C# without using XAML, almost not at all. And what that did is it’s it’s way more productive; so because that everything can be a variable they don’t have to put constants in there for things like margins and so on. So it makes with that kind of slightly out of the box approach I was able to probably get at least double the productivity I was able to get things out twice as quickly and I was also able to develop it in LinqPad so I got instant feedback right without needing a designer for that so it’s a bit of out-of-the-box thinking but um there’s no impedance mismatch anymore it’s all just C# and it had exact C# has exactly the same shape as a xaml if you just add a bunch of extension methods. So you define the whole user interface fluently um and that’s a you know I think having kind of another language. Having a domain-specific language to define a user interface, I don’t think is an efficient way to work. I think it should all be done in the same way.
Joe : [35:05] If you’re using C#, you should be doing the user interface in C# too, because C# is now really expressive. It wasn’t in C# 1. Fair enough, they wrote WPF back with C# 1 was around and C# 2 was around the corner. But nowadays, it’s such an expressive language, You can easily define a user interface in that language and then have all of the compositional qualities and the abstraction power of C# in that language. And it can make you a lot more productive.
Jamie : [35:37] Oh, I agree. I agree. I just want to, before I bring up a point about building C# UIs in C#, I just want to rewind a little bit and focus on the fact that you used LinqPad to build the UI for a new part of LinqPad. I think that’s brilliant.
Joe : [35:54] That’s right. I also used LinqPad to, there’s a VI emulator, Vim emulator, and I wrote that whole Vim emulator in LinqPad. And it was really productive, but there was one problem I ran into, because if I introduced a bug into it, I wouldn’t be able to fix the bug because I’d break the editor.
Jamie : [36:15] Wow. So then how did you get around that?
Joe : [36:18] I just had a robust undo facility in there. It didn’t happen that often, but that was really, really quick because I actually hooked it in so that it actually hooked into the live editor. As I was updating it, it would change the editor. So I got that Vim emulator implemented really quickly.
Jamie : [36:41] Right, right. That makes total sense. Uh yeah um your your point about um C# ui is being built in C#, I completely agree; yeah you’re absolutely right when C# first came in the scene in version one it wasn’t very expressive it could do a bunch of stuff but you know there wasn’t a great deal there but now we have the evolution of the language, the syntactic sugar, um all of the wonderful um uh extension methods,and stuff that sits on top of C# that allows us to do…
Joe : [37:12] That’s right.
Jamie : [37:12] You know I don’t I don’t know if you’ve looked into it recently, but .NET MAUI has this ability where you can define your UI in C# notation rather than using a version of XAML.
Joe : [37:23] Oh, that’s good to hear. I didn’t know about that. That’s good to hear. Because with object initializers and extension methods, you can do it really well in C#. It’s good that the MAUI are taking that on.
Jamie : [37:36] Mm-hmm. Yeah, yeah. Because that was… I remember um I got to about five years ago and realized, “hang on wpf is something that i’ve not really ever used for anything.” So I went away and tried to sort of go, “right okay so I’m going to build something with wpf in xaml.” And then somebody went, “which version of xaml?” And I’m like, “what do you mean?” [and they said,] “it’s like there’s all the different flavors and stuff,” and I’m like, “it shouldn’t be this hard folks this shouldn’t be so difficult it’s a ui framework what are you doing?” So I totally feel the pain that you that you’re talking about there about how the ui should definitely be describable in C# if you need it absolutely 100%.
Joe : [38:20] I guess one interesting side note to that, a little bit of a tangent, is the fact that Microsoft haven’t invested that much in WPF, has meant that the API is saying really constant, hasn’t changed much at all. So if you want to find a solution to any problem, it’s there on Stack Overflow, and it doesn’t vary depending on which version you’re using. It’s a canonical API, and it was in many ways a very good API, and it stayed that way. So there’s this wealth of knowledge on the internet on solutions for every problem. One of the things that makes it really, I think, good to use overall.
Joe : [38:56] Absolutely. Absolutely. It’s like one of the longest lived UI frameworks with a rich API, for sure. Not the longest, but one of the longest lived.
Joe : [39:07] It’s one of the longest. And I think Microsoft would have preferred if it wasn’t that way. I think they’ve been trying to get us to use other APIs. But developers have decided that what they’re going to use right?
Jamie : [39:17] Well I mean we’re actually recording this uh the day after um xamarin has been sunsetted so yeah uh,
Joe : [39:28] I did not know that.
Jamie : [39:28] Yeah um my own personal opinion is that the announcements weren’t made that um “loudly” um and I think that’s partially you know just because there’s so much going on in the Microsoft space. And also it requires members of the community to go, “hey, did you read this yet? " But yeah. So May 1st, 2020, I see. Xamarin is now sunsetted.
Joe : [39:54] That’s not, but [.NET] MAUI is still going. Yeah.
Jamie : [39:58] Yeah. So [.NET] MAUI is the evolution. Yeah. Yeah.
Joe : [40:02] So that they’re sunsetting, like the old version of effectively of [.NET] MAUI. They’re not. Yeah. Yeah.
Jamie : [40:09] Yeah, so .NET MAUI is still a thing. I just want to make that really clear because some people online mistake a lot of stuff to do with .NET MAUI. So in case folks clip this: .NET MAUI is still a thing, evolving, moving on, continually growing. Xamarin has been sunsetted and has fallen out of support, that kind of thing. No more support from Microsoft for Xamarin. Please do your own due diligence. But there was a blog post, and I will Linq it in the show notes, um, from a few days before we recorded. Now this will probably go out in about a month’s time, but a few days before we recorded, uh, there were a series of blog posts about, “hey folks, just so you know, Xamarin is being sunsetted. " So if you, if you’re not sure, do definitely do some Googling, read the Microsoft sources, not the community sources. Cause sometimes the community sources get a bit hyperbolic and say things that aren’t exactly true.
Jamie : [41:04] So just to clarify on that, I always feel like I need to, because I feel like Like the .NET MAUI team get a lot of shade thrown at them because, you know, maybe they’re not innovating as fast as other people would like. And so they keep saying, people keep saying, and this is me, this is not me saying, this is people saying, people saying, “.NET MAUI is dying, blah, blah, blah.”
Jamie : [41:23] No, it’s not, folks. .NET MAUI is a going concern. In fact, the day after we recorded this episode, there was a brand new episode of the podcast interviewing someone from the [.NET] MAUI team. So there you go. They wouldn’t be on the show if they were killing it off, would they?
Joe : [41:38] Makes sense.
Jamie : [41:39] Absolutely. So yeah um long story short xamarin has been sunsetted by the time you’re hearing this uh folks and .NET MAUI is the future, so. But it’s interesting that WPF is still a thing that’s it’s interesting that they’ve kept it around.
Joe : [41:54] If they could make it cross-platform, that would be really great.
Jamie : [41:58] Yeah. Yeah, well, I suppose that’s what Avalonia and Uno Platform, and I think there’s a couple of others, that’s what they’re trying to do. That’s what they are achieving, sorry. It’s not that they’re trying and not being able to do it. They are achieving it. But I suppose it’s slow work because of things you had mentioned, like some of the Xamarin, sorry, I said Xamarin again. Let me retract that. I’ll leave it in, but let me retract that. that some of the WPF APIs rely directly on Win32 APIs, which haven’t been cross-platformed. And so they need to create like a binary compatible layer that sits between your app and the underlying Windows 32 API, which doesn’t exist if you’re running on a Linux machine, right?
Joe : [42:41] Yes. I think also they need to pay homage to some of the things that are specific to each platform. So I think if you’re going to, you know, if they were to go down the path of something like Avalonia, the idea is you, rather like a web app, you want to create a user interface that’s going to look pretty much the same everywhere. You don’t want to make it kind of different for each platform. You want to kind of a similar user interface, but there are some little details, like things like menus and taskbar and so on, where you need to specialize it. So finding that That balance is not simple. And to get everything working smoothly, flawlessly, and performing well, it’s much harder. I can understand it’s much harder to create a good cross-platform, rich client user interface framework than it is to just, say, create the core non-user interface to make that non-platform.
Jamie : [43:43] Oh, 100%. 100%.
A Request To You All
If you're enjoying this show, would you mind sharing it with a colleague? Check your podcatcher for a link to show notes, which has an embedded player within it and a transcription and all that stuff, and share that link with them. I'd really appreciate it if you could indeed share the show.
But if you'd like other ways to support it, you could:
- Leave a rating or review on your podcatcher of choice
- Head over to dotnetcore.show/review for ways to do that
- Consider buying the show a coffee
- The BuyMeACoffee link is available on each episode's show notes page
- This is a one-off financial support option
-
Become a patron
- This is a monthly subscription-based financial support option
- And a link to that is included on each episode's show notes page as well
I would love it if you would share the show with a friend or colleague or leave a rating or review. The other options are completely up to you, and are not required at all to continue enjoying the show.
Anyway, let's get back to it.
Jamie : [44:33] I often sit and think to myself that is it… okay so this is “Jamie’s personal opinion corner”: um I wonder sometimes whether it’s even worth trying to create a single cross-platform ui that looks the same elsewhere; because like you’re saying you’re not paying homage to how the apps are meant to look on that platform right. So like
Joe : [44:07] Sure.
Jamie : [44:07] The way that an iOS app looks is different to the way that an android app looks because they are different user interface paradigms, different design systems, different design languages, which i
Joe : [44:19] Yes To some degree yes
Jamie : [44:20] Yeah and it’s different to how say a windows app works; and let’s just sidestep around the linux’s for a moment. A million different desktop environments and a million different ways that linux apps can look, so we’ll just sidestep that one because that’s the difficult one that’s the one that we hop over. You know we’re coming to a point with MAcOS where it’s slowly converging and iOS apps are looking a bit like MacOS apps, and MacOS apps are looking a bit like iOS apps totally…
Joe : [44:48] Yes but then again and I think yes, Sorry.
Joe : [44:53] One factor that’s happening is that with so many apps now becoming web apps, if you run an app in a browser, it’s going to look pretty similar no matter what machine you’re on. So in that sense, we have become much more accustomed to having a more kind of a homogenous environment. It’s a sense we don’t need necessarily to make, certainly with a “desktop” anyway, with desktop apps, We don’t need to make them to follow all of the local bits of Chrome exactly. If we create something which kind of looks a little bit like a web app, which pays some respect to the local controls, but overall, we don’t want to put too much burden on developers. And a lot of people are using things like Electron to develop apps. If people are happy with ElectronApps, there’s no reason why we can’t have a
Joe : [45:54] rich client UI framework that delivers a similar kind of cosmetic experience to an ElectronApp. And that will take a lot of burden off developers for cross-platform applications.
Jamie : [46:07] 100%. 100%. You know, the web browser is the cross-platform UI, right? Right. And I feel like a lot of a lot of software developers don’t want that to happen. And yes, there is some like you said, “if you’re happy with using an electron based thing, then use it.” Right. It’s about what gets you from zero to productivity as fast as possible. All right.
Joe : [46:34] Yeah.
Jamie : [46:35] Excellent. Well, I mean, we’ve had a bit of a dalliance about UIs. That’s pretty cool. Cool. So jumping back to LinqPad then, I’m interested to know, but obviously I’m very respectful of the fact you may not want to give away the secret source, but I’m interested to know about how you’re evaluating what the user is typing as they’re typing into LinqPad. Are you using expression trees? Are you using some other thing? How does that all work?
Joe : [47:03] Um LinqPad uses the Roslyn um APIs which is the C# code as a service that Microsoft have published. So um and that way it can get full compatibility with uh the all the whole uh the C# compiler but it doesn’t use the um MSBuild tool chain at all so it does it all just using the lower level Roslyn API. So that way it can optimize the performance.
Jamie : [47:38] Right, so are there…
Joe : [47:40] So in a sense, there are expression trees, but they’re Roslyn expression trees. They’re not the kind of Linq expression trees, if you like.
Jamie : [47:48] Right, I see, I see. So then does that mean that they’re, like, what are the potential pitfalls for doing that then? Because, like, I’m now thinking, “I can type anything into LinqPad and it’s going to run arbitrary expressions within LinqPad in that contained space. Is going to potentially run that against my data? Can I reach out of LinqPad and reach into the file system? Can I, you know, is LinqPad now on attack surface?”
Joe : [48:18] Well it’s it’s um no different to visual studio in that respect:in that um the processes that you’re it creates a process for each query, in fact creates one in advance and warms them up so it doesn’t, there isn’t a lag. But it uses a separate process to run each uh query and those processes are running in the same trust environment as the host just like you would if you were using visual studio. So um it’s not designed to be a sandboxed environment um there’ll be kind of very special cases where you could possibly benefit from a sandboxed environment but it’s it’s not really designed for sandboxing it’s just designed to that you get stuff done.
Jamie : [48:57] Sure okay. S,o and this is a terrible example, it’s a really bad example, but if I load up LinqPad and I probably can’t do this and I write some code in there that deletes everything from one of my drives and I run it that’s my fault I should have known what I was doing it’s not like yeah it’s.
Joe : [49:14] Exactly like visual studio in that regard yeah yes exactly like visual studio yeah
Jamie : [49:19] Code just like any other programming tool right that makes sense that’s right yes so I just wanted to get to that just so that then people can’t say, “oh well I downloaded Joe’s tool, LinqPad, and I wiped my computer, and it’s obviously his fault.” And it’s not it’s you pushed the button right you typed the code um you know I’m not trying.
Joe : [49:37] To yeah that’s what you tell us yeah
Jamie : [49:39] Absolutely right. I’m not trying to throw shade on this person but there was a number of years ago where someone had logged aissue with Visual Studio Code because they’d done some work um, and they’d hit the um the uh “undo my changes” button in the the git extension, and it undid their changes, and he said “that’s not fair it shouldn’t have done that!” It’s like, “well…”
Joe : [50:00] I see.
Jamie : [50:01] “You pushed the button dude.”
Joe : [50:03] Yes I mean that’s yes that’s very interesting because um undoing in git um is… I mean git has this kind of a very interesting model of where it’s a it seems it’s append-only right so um and that undo would almost seem to violate that append-only, except I would put money on that still being recorded in the ref log. So I reckon if they looked at the ref log, they would be able to redo what they’d lost.
Jamie : [50:34] Sure, sure.
Joe : [50:36] That’s a bit of a tangent.
Jamie : [50:38] Absolutely. Absolutely. You know, the, the, the, I think the, the problem was that they, they didn’t, they may… perhaps it was user not understanding what the button did. Perhaps it was documentation was not included for the button. Perhaps even this was, there was no confirmation, but even so, right. They pushed the button.
Jamie : [50:56] It did what it was supposed to do. And they were complaining that it did what it was supposed to do. Maybe because their understanding wasn’t correct. I’m not trying to throw shade at them. I’m just trying to say, “look, if I download LinqPad and I do the equivalent of format C inside of LinqPad, it’s going to format my C drive because it’s just running Rosalyn as a service.” It’s not doing anything extra. It’s not going to intercept that and say, “hey, do you really want to do that? That seems like a bad idea.”
Jamie : [51:23] So I know that when we were initially discussing this interview… I’ve said it before on the show, but ahead of the recording, we sometimes do a discovery call. Have a chat about what kind of things we want to talk about… you’d mentioned that you were using uh expression trees outside of LinqPad on other things, and I was wondering just because you kind of piqued my interest is that something you can talk about?
Joe : [51:48] It’s I’m using them within LinqPad but not for the uh compilation path. So um expression trees it’s it’s a interesting interesting feature of C#, and it’s the feature that makes it possible to make iQueryable useful. So iQueryable is an interface that allows you to basically wrap up an expression, right, or a Linq query. And then send that, convert it, say, for instance, into a SQL statement. So that’s how you can query a database.
Joe : [52:28] But what it does is that if you have a lambda expression, lambda expression can either evaluate to a delegate, like a func of T, or it can evaluate to an expression of func of T. Right. So it’s a bit kind of low level. But if you do put expression of func of T into that, you will end up with a something which is like the compiler creates an object model that describes that expression, that lambda expression. So it’s a powerful feature, and it has other uses besides querying a database. And one of the things that I need to do in LinqPad is to have the host communicate with all of the query processes. So every time you execute a query, there’s a whole bunch of other things that LinqPad needs to do as well, where it creates a separate process to run something in isolation. isolation, right? Your query has to run on its own process because it can be debugged and you can’t debug your own process, right? Also a process can run things like a stack overflow exception, right? It takes out the whole process. It has to be separate. So that process now needs a way to communicate with the host process, continue to talk to each other. And there’s a lot of elaborate communication that needs to go ahead for some features such as, you know, results in data grid right that requires an elaborate dance between the two processes.
Joe : [53:57] So that communication has to occur. And there’s a whole bunch of methods that you need to call in another process. So in order to come up with something, you need some kind of remoting framework to do that. Now, Microsoft pulled the plug on .NET remoting, and it had its problems anyway. So I needed to create my own kind of better version of remoting that I can use to allow those processes to talk. And that’s what I did. And that relies heavily on expression trees. So what expression trees allow you to do in that instance is that you can call a method in another process just by giving it, like providing a Lambda expression that says, “this is the method I want to call,” with all the parameters. So it’s all strongly typed, all compile time checked. And by doing that at runtime, it converts into an expression tree that you can have a look at. And then you can serialize that and convert that into ultimately a series of bytes that you’re going to send across a pipe into another process or pick up at the other end. And I think it’s one of the nicest features of C# is that it provides these really powerful things Things like expression trees and lambda expressions and Linq expressions and asynchronous functions.
Joe : [55:23] But at the same time, it also provides really good low-level stuff like pointers. And that’s something else that I needed to actually get this done, because in order to get the two processes to talk to each other at the low level, you also need some way to create a kind of pipe between them. And it’s very demanding, the kind of pipe that I needed to get the performance and also to be friendly to a debugger, which does some really nasty things. So in the end, I had to write my own pipes, and I did that using pointers. So I ended up having the same kind of the same stack of layers of software. I had stuff at the bottom using these low-level pointers and at the top using expression trees, and it’s all done in one language. In the past, without C#, we’d have to go to use, you’d have to write that in C++ and use some interrupt or something, but we’d all do that in one language. Um and that’s something you know I really like about C# is it’s it’s it’s you know it’s got that huge range from low level stuff up to the very high level high level stuff.
Jamie
:
[56:33] Yeah I think that’s something that a lot of… um how do I put it? I don’t want to say C# detractors but that’s kind of the phrase I’m looking at lot of the people who sort of poo-poo C#, don’t kind of realize that. They, for one reason or, another see C# as, and .NET as it’s a Windows thing they you know they maybe don’t know that it’s cross platform. And they see C# 1 and they say, “hey this is the language, and it’s never evolved from there.” Whereas actually you know we’re on, what are we on now, C# 12. Yeah so you know it’s evolved at a rate, an average rate, it isn’t this, but at an average rate of, you know, it’s evolved one major version every two years. That isn’t the actual rate that it’s evolved at. That’s like an average. It’s been 24 years. We’re on version 12. So it’s averaged out two versions a year. And we get great strides when that happens, right? It’s not just like, you know, a couple of years ago when they brought out IAsyncEnumerable
and a whole bunch of other features. And all people talked about was IAsyncEnumerable
, which is a great thing. But there’s loads of other features involved, loads of other cool things, you know, know select uh what what is it it’s not select it’s um um pattern matching and you know being able to um slice into uh select ranges of arrays and collections and stuff it’s really cool.
Joe : [58:03] Yes to continually develop the language
Jamie : [58:10] And that’s something that they that the folks over on the C# language team are are actively involved in doing. And I feel like, you know, I’m not saying that other languages aren’t being left behind but you know there there is some stagnation I suppose with with this. But then
Jamie : [58:24] that’s because things move slowly it’s fine.
Jamie : [58:26] And I figure um just before we sort of um wrap up um I wanted to ask this other question that came from Devin who’s in the community, because I feel like it’s a really cool feature that’s included in the documentation, and I feel like it’s something that It doesn’t get talked about a great deal. So just before we wrap up, we, you know, hopefully we’ve got a few more minutes to cover this. Devin had said in his question, “please make sure you dig into how the included documentation, tutorial, and reference information works. It is super cool that it’s all done as native LinqPad runnable queries. It’s a really neat way to learn. If anything, it’s similar, but not the same structure, but the same idea to things like like Jupyter Notebooks and .NET Interactive, but predating either of them by a long time. I guess that’s less of a question and more of a, here’s a cool thing you should talk about. I’m not even kidding when I say it’s my favorite development tool, hands down, " is what he’s saying.
Joe : [59:24] That’s very nice to hear.
Joe : [59:26] Yeah, the whole tutorial and reference is just a big tree of LinqPad samples. And you can search those. It’s Control F1 and you can search. And that’s the help. So it gives you an interactive sample that you can run that demonstrates a feature. And it’s also Linqed from a lot of the auto-completion tooltips. So if you use a particular feature of .NET or LinqPad, the auto-completion tooltip will often have a Linq to take you directly to an interactive sample to demonstrate how that feature works. And that is one of the ways you can make, you can add x-lot of features to your program without cluttering the user interface, because that is a discoverability point, right? For that feature.
Jamie : [1:00:13] And that loops back around to what you were saying towards the beginning about making the user interface such that the user can then discover things that are pertinent to them at that time, right?
Joe : [1:00:25] That’s right, yes. Yes, that’s right. Interactive samples, it’s a great endpoint to get to.
Jamie : [1:00:32] Right. Excellent. But, yeah, that’s really cool. And, yeah, folks should definitely check that. If you’ve got LinqPad and you’ve never used it, should definitely jump into the help system and just search through that just run things from that It feels very much like, from what we’ve talked about today ,um LinqPad has very much been used to build the LinqPad…
Joe : [1:00:55] That’s right good dogfooding. Yes yes that’s a good dog fooding in it that’s how you create good products here
Jamie : [1:01:03] Yeah yeah.
Joe : [1:01:05] Because if there’s anything wrong with this I’m the first to feel the pain
Jamie : [1:01:08] Absolutely absolutely. And you know like for those who don’t know where that that term came from, it’s uh quite literally from selling dog food to people. “Would you sell, would you give the dog food you are selling to people to your own dog?” That’s what it’s that’s where it comes from right yeah.
Joe : [1:01:27] Something like that, yes.
Jamie : [1:01:29] Joe as we’re wrapping up now, because I realize we’re rapidly running out of time, um uh what’s the best way for for folks to learn about LinqPad? Is it just, “go to the website and check out the free version,” and then go, “hey, this is really cool. I’m going to give you some money and pay for a paid license”?
Joe : [1:01:46] Yes, just download it and have a play with it. It’s a very lightweight product with a lightweight installer and an xcopy version as well. The premium license, which unlocks the extra features, is $125 at the moment. So it’s not a hugely expensive product. And you have a play with it and see see how you get on
Jamie : [1:02:11] Amazing amazing. What about if folks are like, “hey i’ve got a question for Joe,” is it something they can, like are you on the artist formerly known as twitter or is it more…
Joe : [1:02:23] Yes, I’m on Twitter. And yeah on twitter at linqpad and um there’s also there’s a on the website there’s links to it there’s a forum as well
Jamie : [1:02:34] Excellent okay. So we can get questions out to perhaps other users of LinqPad as well and get some community response, too .
Joe : [1:02:44] Sure.
Jamie : [1:02:44] Amazing, excellent. Well thank you very much Joe this has been a lot of fun; and like I said
Joe : [1:02:50] Thank you Jamie
Jamie : [1:02:51] I’m a big fan of LinqPad and I feel like people should more people should be using it because it is a fantastic tool. It’s another one of those tools in the toolbox that I reach for when I need to use something right.
Joe : [1:03:02] Sure.
Jamie : [1:03:03] Amazing amazing. Thank you very much Joe.
Joe : [1:03:06] Thank you Jamie.
Wrapping Up
Thank you for listening to this episode of The Modern .NET Show with me, Jamie Taylor. I’d like to thank this episode’s guest for graciously sharing their time, expertise, and knowledge.
Be sure to check out the show notes for a bunch of links to some of the stuff that we covered, and full transcription of the interview. The show notes, as always, can be found at the podcast's website, and there will be a link directly to them in your podcatcher.
And don’t forget to spread the word, leave a rating or review on your podcatcher of choice—head over to dotnetcore.show/review for ways to do that—reach out via our contact page, or join our discord server at dotnetcore.show/discord—all of which are linked in the show notes.
But above all, I hope you have a fantastic rest of your day, and I hope that I’ll see you again, next time for more .NET goodness.
I will see you again real soon. See you later folks.
Useful Links
- LiniqPad on X
- LinqPad
- Supporting the show:
- Getting in touch:
- Music created by Mono Memory Music, licensed to RJJ Software for use in The Modern .NET Show
- Editing and post-production services for this episode were provided (in part) by MB Podcast Services