Episode Kickoff in Europe
00:00:24
Speaker
Okay, Dethin, episode 8. Ray MacDermot here in Belgium. Vijay Kiran, over in Holland. How are you doing, Vijay? I'm doing pretty good. We had a pretty decent weekend. I think we had fireworks nearby, so we enjoyed it a lot. And today I'm having some bit of a lisp because I just bit my tongue and I was bleeding for half an hour and now I'm putting some ice and it's going to be lit pee.
00:00:53
Speaker
The things you do for love, the things you do for this podcast. I mean, you know, I think it's impressive. I think you'll be, you'll be, I must do it myself next week. We keep cutting our tongues every now and then. Yeah. Well, I try and bite my tongue, but it's very difficult.
Gratitude and Upcoming Guests
00:01:10
Speaker
Yeah, but anyway, but first of all, I'd like to thank our listeners. We have around almost a thousand people listening to the podcast. That's fantastic, isn't it? I mean, you know, it's exceeding our expectations, especially that it's sticking with it. We're sticking with it. I think it must be the fact we're having a lot of guests. I can only imagine that's the reason why people are actually bothering with us.
00:01:35
Speaker
Of course, otherwise, in a couple of episodes, they'll stop listening. And they're like, oh, God, we can't take these guys anymore. Especially our self-deprecating humor. But in any case, we were very fortunate to have all these guests. And we are lining up some other interesting guests in the upcoming episodes.
00:01:57
Speaker
So hopefully we'll have very interesting discussions with a lot of topics and enclosure. So stay tuned. Yeah. Well, I think it's still, I mean, there's so many topics, aren't there? So much innovation going on. It's actually like you're trying to cherry pick at this moment. You know, there's so many things to talk about. Obviously we're going to talk a little bit about a few of these things in the news now, but just at a general innovation level.
00:02:21
Speaker
I think it's still true that closure is still the king of innovation as far as computing is concerned.
Clojure's Innovation and Stability
00:02:28
Speaker
I still feel, I don't know about you, I still feel like whenever I fire up closure, I still feel like I'm at the kind of, at an innovative place, a leading edge, at a place where things are still evolving. I'm still learning a lot every day. Every time I open up code, I'm learning something new. Yeah. I mean, for me, of course, I completely agree with you. It's like cutting edge stuff and, well, not completely
00:02:51
Speaker
cutting but you know very interesting things happening especially on the front end, on the back end and with specs and all that stuff and distributed computing. We are clearly on the forefront and the advantage with the podcast for me is that we get to talk to these amazing people and we are just learning from them.
00:03:09
Speaker
This is like a free coaching session. Yes, yes, it's excellent, yes. The other thing as well that I think is really interesting about closure actually is that despite the fact that there's a lot of, and maybe it's because of the LISP aspect of this, but despite the fact that there's a lot of innovation around the community and in the core as well, it's still remarkably consistent and stable and you don't feel like you're having to
00:03:36
Speaker
you know like rethink everything every time a new innovation comes on it seems like it's often most of the innovations are very let's say sympathetic to the the overall concepts behind closure and those core concepts seem to be bringing around that innovation i think that's really uh a phenomenal thing you know and we all bow down to to the hickey you know yeah the guy the guy made a lot of good choices um where does he live by the way somewhere in colorado or something i don't know
00:04:07
Speaker
I have no idea but and don't and don't stalk him okay every now and then whenever you open Emacs or something and then you just turn towards that side and then bow down
00:04:23
Speaker
OK, that'll be really, I don't know, fundamentalist, but let's not do that. That's for future generations, that one. Exactly.
EuroClojure Highlights and Onyx Updates
00:04:32
Speaker
But anyway, our first segment of the podcast, news and events. So what is happening?
00:04:36
Speaker
First of all, Euroclosure. The talks are announced and the lineup is fantastic. Of course, without me because my talk got rejected. Too sad. Let's just talk about that because this is harsh. I could have kick-assed it.
00:04:56
Speaker
Anyway, never mind. I believe they have this model for accepting and rejecting talks, don't they? That's all about awesomeness. Obviously, they're screwed up this time, big time. Anyway, I can imagine it's a couple of best talks, but there are fantastic lineup already. David Nolan is coming, and Karen Mayer, and there are a couple of very interesting talks that I see already, especially with
00:05:26
Speaker
big data stuff, not big data, but Dragon, or I'm sorry if I'm pronouncing his name correctly or not, but he's working on this Neanderthal, the GPU-based library that I'm really excited about.
00:05:41
Speaker
And there are other fancy talks with Docker and one more talk about spec. But anyways, I'd encourage everybody to take a look at the speaker lineup. And of course, we will be there. We will. Yes. So by hook or crook, I'm going to give my Onyx talk. I'll be standing outside, like in the back in the, I think, Roman days or Greek days, shouting, hey, Onyx is awesome, and then giving pamphlets away.
00:06:08
Speaker
like the street corner the street corner profit yeah exactly well we're gonna do a meet-up aren't we we're gonna start organizing this soon we'll do a meet-up as well i've got a few things planned as well so we'll have something good at that meet-up that's for sure yeah yeah speaking of onyx uh onyx got funding that is a big news this um this week our last week yeah that's ridiculous yeah these guys are uh i mean we talked about how incredible their vision is also and i think it's fantastic news
00:06:37
Speaker
Yeah, it's amazing. And they are teasing us a bit, especially on Slack. I think Michael and Lucas are teasing the kind of product that they are working on and they want to give some sneak peek pretty soon. So we are pretty excited. And hopefully, Mike or Lucas will join in our broadcast and then we can pick their brains a bit and maybe get a peek into their future plans.
00:07:01
Speaker
We'll see. Yeah, well I must admit I'm about to get started on some big data distributed processing and I'm looking forward to it because this is something which is going to go on for quite a few months, even years. So I really would like to get their vision because I think
00:07:22
Speaker
given where it is so far, I think it's very, very promising. And I've already got a lot of the fundamentals spot on, I think. And again, it's very close to that day to first vision and that very, I mean, come on to the kind of closure at scale stuff in this episode.
00:07:38
Speaker
But I think they've got very many things right there. Obviously, whenever you go up to scale, you've got all these tooling issues. So I'm sure that's what they're kind of working on. But great news to them. Congratulations to them. They've obviously worked really hard. They've put a lot of their skin in the game. And so all congratulations. And I'm sure they're going to do an awesome work. Yeah, and great luck. Yeah.
00:08:04
Speaker
And I think I just read on Twitter that Reframe has a new version available, Reframe the reagent-based framework. And this is probably one of the most awesome read-me's ever on a GitHub page. The tutorial, yeah. It's incredible, too.
00:08:22
Speaker
It's pretty awesome to read. So I haven't seen what's new in that yet, but that is something that I'd like to mention. I think the guys from Refam, I've just got to be careful
Clojure in Large Application Development
00:08:34
Speaker
that they avoid Mischa launching the nukes. Yeah, that's true.
00:08:43
Speaker
That's Reframe. And Ambrose was the core-typed developer. He has been checking along nicely, I suppose. And he's now just announced a small project for automatic annotations in Closure Spec. There was an Indiegogo Kickstarter. You can't call it Kickstarter because it's Indiegogo now. Oh, crowdfunding.
00:09:05
Speaker
crowdfunding campaign. Unfortunately, it didn't reach the target. I don't know how it is going to affect, but I'm really curious what he's working on, and we should see some interesting things coming out from him soon. And he's another target for us to bring on to the podcast. Definitely, yes. Very interesting work he's done so far on the core type stuff, also on the logic stuff as well. Yeah, yeah.
00:09:33
Speaker
Okay, so let's get on to the main discussion for today. So this is episode as you can, well, as our audience can imagine, we don't have any guests in this episode. So we're gonna put our ignorance out there. Is the village idiots once again? Yes. So today we want to talk about closure at scale. It's always a
00:09:55
Speaker
interesting discussion around this because most of the people keep complaining or worried about how it is going to scale in terms of code, in terms of how do you manage large code bases in dynamic languages, especially how do you design large scale programs in functional programming and other issues like, yeah, distributions and team sizes, all sorts of stuff. All right.
00:10:23
Speaker
So the first thing that, well, I started with object-oriented programming. There was a bit of a Pascal in my life at some point, which I don't want to talk about. Did you really start with OOP? You didn't come in before that? No, I was doing Pascal first. And I did some cobalt as well, but that is only during the university. And I used to learn and teach cobalt simultaneously. So that must be spectacularly painful for my pupils. Jesus.
00:10:54
Speaker
Wow. That is a learn by teaching method. I think I wrote one COBOL program and that was it. That was enough for me. But like you, I did Pascal as well. But I spent many years as a C programmer actually. So I was doing that for a long time. But anyway, so you mostly started with OOP. But you're younger than me anyway. Yeah.
00:11:21
Speaker
I'm not sure though, but maybe. So I did start with a bit of Pascal, and then a bit of Delphi, and then first commercial stuff was in C++ with the Windows programming. The horrible HW, ND, PTR to something, and that shit. MFC and Windows programming. So that was completely object-oriented thing. And then I started doing a bit of a Java back in 1.1, AWT.
00:11:52
Speaker
And it quickly turned to 1.2. And one of the interesting books that I read during that time was Bruce Eccles thinking in Java. He had thinking in C++ as well, I think. So designing large-scale programs and designing bigger programs, I always started thinking in terms of object-orientedness. So first you think about what kind of classes that I need and what kind of actions I need. And pretty much all the program design was
00:12:22
Speaker
guided by the language that I'm using, which was Java. So then we had UML and object-oriented analysis and design. So that's how I got into large-scale programming, I would say. And I think one of the biggest programs that I ever wrote, well, not me, but essentially with the team of six other people, that was for, I think, advertising management for Quark some time ago.
00:12:52
Speaker
So when you design a large-scale program, those are mostly driven by the language that you're using.
00:13:01
Speaker
Well, I wanna, yeah, sort of, but I wanna sort of pick up on that a little bit. Let's maybe just go back a little bit, you know, like the closure way, you know, of defining the problem. So kind of like, what do we think scaling is actually? You know, what do we actually mean by scaling? Because I think, you mentioned a few kind of metrics there, like team size and stuff like this. But in terms of design, what do you think about scaling? Because I tend to think of,
00:13:31
Speaker
of scaling as sort of in a number of dimensions, you know, like you can think about, well, how big is the problem that you're trying to address? And sometimes a relatively small problem can still have a big code base, you know, because I don't know if you've seen how many to do list God damn.
00:13:48
Speaker
Things out there. Well, you know, apparently this is a big problem. It needs a lot of solutions. And I'm not just joking about that, you know, because obviously the Nord frameworks do a to-do list as a sort of joke. I think make a to-do list app is on everybody's to-do list now. Yes, yes. A bit of recursion there, yeah. We'll come back to that one.
00:14:12
Speaker
But yeah, what I was thinking was that, like, actually people complained, aren't they, about, oh, well, you know, we made this to-do list, but actually our framework is so nice and so wonderful that this to-do list only shows off like 10% of its features. But anyway, so it doesn't matter. But what I'm trying to say is, well, maybe it doesn't matter because that's kind of the size of the problem, you know, that people say, ah, okay, well,
00:14:38
Speaker
if you've got a small problem then you can kind of just do it from code with one person out of your head if the problem gets bigger then you need something to constrain that something something where you can make some decisions so that's what i'm wondering about i'm wondering about what is it what are the actual things that um because what things actually
00:14:59
Speaker
do you flex on? What are the decision points that you need to make when you want to scale something? Because I often hear this from framework authors that, oh, you know, the reason why we did a framework was because you've got too many decisions to make. You've got too many choices. And I wonder what you thought about that, because I think that seems to be the beginning of it, or the heart of it, is that we're essentially just, you know, we're kind of rinse repeating this problem. So in order to kind of
00:15:28
Speaker
to scale it out, if you like. Well, we just put a framework together or we put some kind of application server together or some other kind of, you know, big lump of stuff like an ERP system or, you know, I find that
00:15:43
Speaker
I find that a really interesting discussion point, actually. I know we're just starting this. But let's think about that. Let's have a chat about that. So where are we talking about scaling here? We're talking about a to-do list. We're talking about web application. We're talking about a whole line of business application. Well, I think the most common thing these days is the web applications. So when I say scale, at least in my viewpoint, the major thing is that
00:16:12
Speaker
How do I design a big application or an application that has a lot of use cases and everything? And how do I start? Because when I switched from Java to Closure, or the first time when I picked up Closure, because I'm so used to this, the first thing that I do is class person, and then just create a class, and then think about what is the model layer, and then design the whole model layer, and then the data access objects, or data transfer objects. And these kind of things, all this ceremony,
00:16:41
Speaker
I'm starting in new applications because I thought web applications are most common thing these days. So if we start with an application, I'm thinking about all the classes, all the data models. Can I just stop you there, though, because does the phrase web application mean anything anymore? Well, nowadays it's
00:17:02
Speaker
I don't know what the difference is anymore, but obviously if you're building desktop or any kind of large applications. What I mean by that is that if you're doing like an ERP system or a CRM system or whatever system, it's always going to be a web application.
Scaling Challenges in Server Applications
00:17:17
Speaker
So it's kind of like a given interface on the server side, isn't it? Yeah, of course.
00:17:24
Speaker
But anyway, let's say some big server application. Because where I work, the big ones are things like ERP, CRM, all these kind of e-commerce style applications as well. So you have e-commerce platforms, CRM platforms. I mean, I think those are really, those are big things which you need to scale, aren't they? Because there's a lot of use cases, like you say, around, well, how do I manage the product catalog? How do I?
00:17:53
Speaker
manage the content, how do I do the inventory, you know, blah, blah, blah. Yeah, I mean, I'm not saying that web applications are a bit different when you're designing because I worked for
00:18:06
Speaker
building desktop applications that are fairly complex for clinical trials and stuff. So that is pretty, you know, for the big pharmaceutical companies that was built in Java and swing and those kind of things. But the thinking behind building this application, that is fairly similar, right? When you start with thinking about how I'm going to design my model layer and how I'm going to design my data access layer and data transfer objects and all sorts of stuff on the front end.
00:18:35
Speaker
that the thinking is so much tied to object-orientedness. Do you think that's true, though? Because maybe I'm just old school, but I always think the beginning of this stuff is talking about user stories and talking about what's the data, actually. And then as soon as you get the programmers involved, they start talking about all these classes and stuff. But that's the beginning of the design process of what are we going to do? It's mostly about, well,
00:19:02
Speaker
What did we want to capture about the customer? What, you know, we're trying to sell these products. We're trying to, you know, or do this thing, whatever this thing is. Um, and then it starts to go into the thing you're talking about. Yeah, of course. I mean, I'm not talking about the functional side of it, but once we move to the technical side of it, then, then we end up with, um, all these discussions. And anyway, the biggest conceptual jump that I had to make when I started with closure is that, okay, how do I start? You know, what is the,
00:19:33
Speaker
first step because it was just a function and then I write a couple of functions in a namespace. Is it done? So with that knowledge, when I made my first application, I think it was around a thousand lines of code for generating PDFs or something in Clojure. And that was pretty okay. It worked. Obviously, like everybody else, I'd love tests, but I didn't write any of them.
00:20:00
Speaker
You had this like thousand lines in a REPL to load up every time. Yeah, it's more or less like that, but saved into a file. But later, of course, it's divided into multiple namespaces because you want to separate similar functions together into different places. It's not a large code base, but one of the problems with my code that I saw is that after three months or something, I go back to the code. Now I'm completely lost because
00:20:30
Speaker
There was no spec, there was no schema, every function seems to take a map and give a map. And I was super confused. Maybe it's just my stupidity, obviously, but it took some time for me to remember what happened. That's what I mean by scaling it up. Now, if I imagine the project being worked on by multiple programmers,
00:20:55
Speaker
So how do you communicate the intent? How do you communicate these things? There is documentation, obviously. These are all standard problems. So that is one kind of scaling that I'm really interested in, how large closure programs are large, any other functional programming things. So what you're getting at here is somehow is that, and again, it's a very interesting thing, is that with functional programming, we tend to be doing these map, like you say, these functions that
00:21:24
Speaker
that take a map, give back a map, you know, whatever, or take a function, give back a function. However we're gonna do these things. And what's, I think what's confusing about it potentially is the fact that the data that's gonna be piped through these functions is not there. Whereas with the object-oriented model, you're kind of, you're essentially, you're putting the data shape and the data model concretely into your programs, aren't you?
00:21:53
Speaker
And that's maybe the biggest mind switch, like you say, is how do you rid yourself of this desire to constantly want to enforce a rigid shape on the program itself and to have that visibility? Yeah. And also the whole data modeling thing, because I think the book by Alex Miller, and I forgot other author's name, I apologize, there is closure applied.
00:22:22
Speaker
Very, very nice book, by the way. I'd really recommend it. And they start with the data modeling and then giving you strategies of how do you model the data. Because obviously, data is the king in the closure world, or queen, depending on how you see. So Her Majesty, the data, you need to treat it how you're going to model it. So they have some discussions about whether it is going to be a map, or a record, or when do you go for
00:22:50
Speaker
records versus maps. So that is something I think records versus maps is one of the fundamental decisions that you need to make when you're starting up a large scale closure program. What do you think about, okay, but what do you think about that then? I mean, I know we've got different opinions potentially in the community about it. But I see these deaf records and all these kind of things as
00:23:19
Speaker
It's generally pretty annoying, actually. I prefer the maps, personally. Yeah, I mean, maps are very, very, very flexible, right? I mean, that is the entire nicety of using maps. But the records are going to give you some sort of, I don't know, kind of a communication of your intent, like, okay, I have to have these things. And the nice thing is that you have these helper functions that are automatically generated for a record.
00:23:47
Speaker
you can always use maps versus records and also I think there is a kind of a performance benefit as well if you're using records because they're backed by a proper Java class in the back end instead of a hash map compared to maps.
00:24:02
Speaker
Don't say that. Don't say it's a performance benefit. Ah, no, no, no, no, no. That's a desperate measure, isn't it? It's like, oh, we're going to get one nanosecond throughput better for a type versus a map. Of course. That's the last bastion of optimization. That's true. That's true. But at the same time, the major advantage is that you have it
00:24:32
Speaker
you have a specific structure and you know which keys are there and that is the kind of thing. And on the other hand, you have less flexibility. So you cannot just add whatever the keys you want. Of course, if you add a new key to the record, then it will be an additional map inside the record. Well, I'll give you an example of where I, for instance, concretely wanted to do this. If you want to persist data and then
00:25:02
Speaker
read it somewhere else. As soon as you put it into records, or Java classes or whatever, it becomes an absolute nightmare, in my opinion, because you have to then, on the other side, on the reader, the reader of these things, has to understand that that object existed, that that record existed. And that is essentially poisoning the data.
00:25:28
Speaker
If you happen to be the one that's reading and writing all the time, no problem. Of course, you can do that. But if you're ever going to share that data, or if the intention is ever to put that data on the wire for somebody else, then putting objects around it is just the worst thing you can do. Yeah, that's true. I think that the chapter also talks about the same stuff as well.
00:25:53
Speaker
the flexibility that you get using the maps is essentially that, what you're pointing out, that is the advantage. So you can safely transmit the data between different systems. And there is no additional type that you need to know to read this one back. So that is one of the things. Anyway, so that is about designing the data. And the second thing when you're writing larger closure programs is how do you come up with
00:26:23
Speaker
different layers or that's a that's a big big word probably but how do you organize the code you know that the only logical way of organizing the code enclosure is the namespace okay so that there is no other higher level module or i don't know what is the right word for it though well let's let's say this compilation unit yeah i know but
00:26:50
Speaker
somehow you can think of it as a
00:26:54
Speaker
as I can't, yeah, names are good because you can think of it as a distribution model, can't you? You know, if it's a way of just doing the nice, the things that object-oriented thing that is good, which is to separate function A into a namespace, that's obviously a good thing, isn't it? You know, if you're talking about naming problems, that's how you solve that, isn't it, essentially? Yeah, yeah.
00:27:22
Speaker
But I think we talked about this before, didn't we? But you have to get this kind of org.closure.com.core thing, this reverse domain name stuff to do that. And if you're not careful, if you just pick up random names, then you're bound to have this, what's the thing in Node? The left string, left pad, the left pad problem. So,
00:27:53
Speaker
Yeah, but here I think in the closure world we're a bit lucky because we're piggybacking on JVM stuff.
00:28:00
Speaker
And there is some sort of a convention there already, and everybody kind of agrees on that one. So I haven't seen anybody saying, OK, I'm going to use the same package name like everybody else. Well, no, it does matter. I mean, we had this problem. We had a sort of bug or a kind of funky thing at work recently where there was a library, a Java library.
00:28:20
Speaker
that was JDOM. So we all know the old JDOM library.
Handling Java Dependencies in Production
00:28:26
Speaker
So obviously to take things from XML and put it back into XML, etc. And this is all fine. But they changed their name from, they used to have a library in the Maven, it was JDOM slash JDOM, that the organization was JDOM and the artifact was JDOM.
00:28:44
Speaker
And then they changed it to the organization or the group, sorry, being org.jdom and then the artifact being jdom. And that caused all kinds of problems because, you know, then all of our dependencies got a bit messed up and we had different, you know, the jdom was the same thing and it got everything. The class path was messed up.
00:29:05
Speaker
And we ended up having a production bug through this. And it's like, yeah, people have a lot of head scratching. Why do they change this? So you have to be careful. You're right. There are conventions. But even in the Java world, people don't always follow them. And then because of that, oh, then they catch up later. But not all of their consumers.
00:29:31
Speaker
are aware of that. So I'm just saying that we're certainly not living in a perfect world. Of course, of course. This is something that is a problem in every ecosystem. How do you manage packages? How do you share code? So I think a couple of days ago, I was talking to one of my colleagues like, OK, this has been a big issue for every language and every
00:29:57
Speaker
community, how do you share code with each other? So that's something, at least in Java world, I think there is some level of sanity already established. Of course, we have all these transitive dependency issues and all the crap, but still slightly better than just pulling random scripts from the outside and running them. So coming back to the object-oriented thing, I think one of the interesting things
00:30:24
Speaker
with object-oriented programming is that the design patterns, right? I mean, that has been one of the biggest things people still learn how to organize their code or how to think about the problems, how to solve common issues. So in functional programming, because there are so many problems that are not there, so there is no equivalent patterns in functional programming.
00:30:48
Speaker
The only patterns that you see are the functor or applicatives and these kind of things. But you don't see similar ones like creation patterns or behavioral patterns. So I was... The Monad. Of course, the Monad. Oh, Jesus, the Monad. Once you know it, you can never explain it. I love those things.
00:31:09
Speaker
It's it's it's yeah, maybe we should we should try to explain monad in one of the episodes. Yeah, not now We should have a drink first, you know, yeah That should be the the subject of the deaf and meetup, you know Let's all just get drunk and explain monads and record it for posterity. Yeah Yeah, I think we should talk about all sorts of monads like the free monads and state monad and all this stuff and
00:31:33
Speaker
That'll be cool. But anyway, let's not tell. All right. But you're right. There are kind of like a different, it's a different order or a different thinking of patterns, isn't it? Because those, all of those patterns, if you remember the sort of Gang of Four book, they were, the funny thing about the history of that book, I don't know, I kind of was fascinated by that book, so I did actually read it.
00:31:57
Speaker
You wouldn't do it these days. You wouldn't read a book these days. But of course, I did. The only book that I read is the How to Copy, Paste from Strike Overflow. That's a short book, that one.
00:32:13
Speaker
Yeah, because there was a, you know, the IM developer Twitter account, you know, that guy tweets all this fake, so he tweeted this how to copy paste from Stack Overflow and somebody went ahead and actually wrote a book of 10 pages with licensing issues and how do you copy paste and how to give attributions.
00:32:35
Speaker
There is a good book by the way. The history of it is a little bit that the authors, they were experienced authors themselves obviously, but they also went round and talked to a lot of good programmers, programmers where people had had success.
00:32:55
Speaker
And they've tried to say, okay, well, since you've had success, what kind of tricks of the trade do you have that you can try and teach us? And while they were doing this, they were cataloging all of these practices, these so-called best practices.
00:33:10
Speaker
And I realized that certain of these best practices were common amongst a lot of these people. And it comes back to what you said at the very beginning, actually, Vijay, is that a lot of them are rooted in the language environments and they ended up being hacks or tricks that they used to get to a particular end point in the language that they were. I'm going to say suffering, but let's say they were working in, you know.
00:33:36
Speaker
Yeah, but one of the things that I
Design Patterns in Dynamic Languages
00:33:40
Speaker
wanted to mention was Peter Norvig had a small presentation about how to actually write these or do the same kind of things that you do with the design patterns and translate them into a dynamic language like Lisp. We'll post the link in the
00:33:58
Speaker
in the show notes, by the way. There are some patterns that have no meaning in functional world. For example, all these creation patterns, because there is no new enclosure, right? You're not constantly creating new objects. Of course, when you're interoperating with Java, then probably there is... Back to your Jeff record again, dude.
00:34:20
Speaker
Yeah. But there is an instance, and there is, of course, you can treat that as a factory. But most of the patterns, you don't have the same problems here. You have different kind of problems. So that's why you have these monads and all the crap.
00:34:35
Speaker
and all the shiny stuff, I should say. Well, a lot of it, like you say, is creation, and then it's how do you iterate over things, and how do you change things. You're absolutely right, because there are essentially three things that really hurt your head when you don't do them anymore.
00:34:54
Speaker
I remember somebody at work was asking me the other day, he says, I can see why you guys, there's a lot of you guys, you know, guys, he was from another vendor, he was from A vendor, in fact, and he's saying, oh, the guys at our place, they love functional programming. I know you love functional programming.
00:35:10
Speaker
So, but you know, and I just don't get it, you know, what's the big deal, you know? And I was saying, well, if you try and think that you can program in a language without variables, you know, try and think about that because that's a big difference. That is, you know, something which non-programmers can kind of try and understand a little bit. It's a difficult mind shift, isn't it? Because if you don't have variables, then all of these design patterns are a bit meaningless, aren't they?
00:35:40
Speaker
Yeah, of course. I mean, I think that's the another way to say it. Like, um, just think about without assignment, but there is no change of values so that you can't constantly assign new values to the thing. But that's a, that's an interesting thought by the way. Yeah. But there are assignments, aren't there? You can say, let something be something. So yeah, but that's, that's just a binding. So that's not assignment as in the equal operator in the, in the mathematics, right? You just say,
00:36:06
Speaker
OK, now I'm going to have this value, and then it is going to change after some time. The change part is separate, obviously. Yeah, yeah. So that's the interesting part. Anyway, so coming back to the architecture of large scale applications. So I think Stuart Sierra
00:36:26
Speaker
is the guy who made the component. So that is one way to look at or organize your code. I think there is a lot of support in the community to use the component. I know a lot of people who are using component. I tried using it one time, but I felt
00:36:46
Speaker
somehow it didn't fit, maybe I didn't spend enough time with it, so. I think the thing about component is that, again, it's maybe one of these things where probably where, let's be honest, we're not writing, you're writing a thousand line closure programs, but we're not writing ERP systems in closure. As if you're the guys at Walmart, they were saying they used it.
00:37:11
Speaker
to sort of commonize their model for continuous integration and for these kind of things. And I think you need certain common patterns that the team will follow for how do you build your code and how do you test your code, how do you bootstrap your code.
00:37:31
Speaker
And I think those are the kind of things that the component is aimed at, isn't it? I think there's a bit of a scope creep in some respects on that thing. But I think the concept of being able to organize your code and the building of your code and how do you bootstrap your application? Because that to me is what that program is there for, is to say, how do I start my server?
00:37:59
Speaker
And that's definitely a very, very laudable and decent and proper thing to want to do, you know, to commonize that aspect. Yeah, and also the dependencies between different modules. It's a sort of orchestration style thing, isn't it? Exactly, yeah. So that is something that I think that's the reason why community adopted component, because everybody was trying in their own way how to solve this problem, because of course you have the modules,
00:38:28
Speaker
and I have this, I should call namespaces. So I have a database namespace, I have a web server namespace, I have templates namespace, I have mailing namespace in my application. I have all these things, but there is an interdependency between them. How do I manage them? How do I arrange them? And how do I specify that this layer requires the other one, the visibility? So when the code starts to grow bigger and bigger, these are going to be bigger challenges.
00:38:57
Speaker
Component is probably one of the interesting ways to organize your code. We call that architecture, you know?
00:39:06
Speaker
Yeah. That's funny, isn't it? That's funny to think that it's like the ISO seven layer model. And to your architecture. Oh, God. I mean, you get some of these Java things where everything has to have an interface and an implementation. And you have seven layers with three interfaces and three classes. There's only one line of code, for God's sake. And so, yeah, we can go crazy on this stuff. And thankfully, we don't do that enclosure.
00:39:35
Speaker
Yeah, of course. By the way, speaking of architecture, there is, I think, an open source book or something. There is a book called The Architecture of Open Source Applications. I think it is available online. OK. It's a very fantastic book, because there are lots of very, very smart programmers explaining how they built large systems, like people who built LLVM, people who built Hadoop, and Eclipse. OK.
00:40:04
Speaker
Well, it's still a big program that a lot of people use. I'm not a fan of it. I've used it for a few years, but I'm more of an intelligent user, but it's definitely a complicated program, that's for sure. Of course. I built RCP applications on top of Eclipse framework, desktop applications, and I've seen the hell, and I came back.
00:40:32
Speaker
But what are we talking about here? We should put the link to that book in the show because I definitely would like to have a quick glance at that. But you're right, in the object-oriented world, it tends to be front-loaded with all this stuff.
00:40:48
Speaker
And of course, if you go back to the Java Enterprise edition, that was all a load of blueprints and patterns, like you were saying. Well, we laugh at them now, but it's kind of like there is something that we want as humans. I see this a lot of work where we want the kind of template, we want some guidance, we want a bit of leadership or a bit of vision.
00:41:15
Speaker
Having a kind of free-for-all is scary to many people, you know? Some people really want that. Other people would rather have a kind of everything layered up for them, you know, and served with a golden spoon in their mouth.
00:41:30
Speaker
Yeah, I mean there need to be a right balance, right? Because you don't want to have complete free range stuff. Now the code is essentially running free range and you don't know what is doing what. And on the other hand, you don't want to have a rigid framework which you cannot escape on rigid layers.
00:41:46
Speaker
But what do you think about that? Because if we bring ourselves up to
Developer Anarchy and Scaling Practices
00:41:51
Speaker
date, and this is not something which we've really discussed properly before, but there's a kind of, there's a whole waterfall stuff, and then there's the agile stuff, and now there's this movement called Developer Anarchy. Have you heard of that?
00:42:08
Speaker
No, it's true, it's not a joke. Is it like a programming motherfucker thing? No, no, no, it's really, it's really, it's really, there are serious people. I'm not joking. There's actually a guy, Fred George, I think he's called. I think it's Fred George. He's a guy with two names anyway. Anyway, the notion of developer anarchy is exactly that, is that
00:42:35
Speaker
is that actually, if you link your business people and your developer people together, and your developers can do something quickly, will give your developers the freedom to operate and to do things in the way that they want to. Funnily enough, many, many people choose closure in this kind of developer anarchy style thing, because it gives them a lot of freedom
00:43:03
Speaker
But it's all this kind of stuff where people are looking at, well how do I write something that can be written in like less than 20 lines or less than 100 lines of code, deploy it onto a server, try it out, see if it works for a business like on a campaign or on a financial site or whatever.
00:43:24
Speaker
and then if it doesn't work out, obviously track some numbers on that thing, see if it works, if everyone's happy with it, that's great, keep it going. Tweak it if necessary, but it's only 100 lines, or 50 lines, or 20 lines, or whatever, so tweak away at it.
00:43:41
Speaker
and then just keep it going. And these kind of things are meant to live for three months, six months, or a year or whatever. They're not meant to be 20-year things. So they're all small things. And that's why this developer anarchy thing is there. It's like extreme programming. It's a kind of label for
00:44:02
Speaker
for giving developers, the actual programmers, more control than people like me who work in enterprise architecture. And I'm a fan of it, actually, because I'm one of the cool dads.
00:44:18
Speaker
Yeah, kids, get out there and do anarchy. Right closure. But it's one of these things, it's like, actually, anarchy would be fine, I think, in general, if you could trust all the people. Yeah, of course. It's kind of like one of these funny things, we're talking about scaling, and of course, anarchy typically, the anarchists will tell you it scales, but we haven't seen it in practice.
00:44:45
Speaker
Anyway, my point anyway is that there's a whole kind of bunch of practices that influence these kind of designs and the scalability. It's not just a code base or a kind of OOP stuff. It's kind of like, well, how quick do you want things to change?
00:45:05
Speaker
how much functions have to be, you know, is it something which you're making for APIs, or is it something which you're making for unknown users? So there's a whole load of parameters, isn't there? Yeah, of course. And also, because we're talking about the functions and sizes of the code base, then there is always a discussion about, when I was working in a bigger project, which has the Angular front end and the closure back end,
00:45:34
Speaker
The discussion was, hey, should we add this as a dependency because it seems to be like 40 lines of closure. Should we pull in the jar for it or should we write it ourselves? So there is always this friction between, is this generic enough to be a library that I can pull in from external code?
00:45:53
Speaker
Well I hit that this week actually, this week or last week I remember I've been fiddling with this proxy for Kafka in Clojure and I started off with, I was looking at this thing called Fast Kafka or something which is a library for, on top of Kafka, it's in Clojure, it's a Clojure sort of library and you can use it from Clojure very easily but it has all these built in things for Redis and
00:46:22
Speaker
I think again it's one of these things where if you've got a very large scale problem, applying that framework to it is probably very good. But honestly it's too much work to adopt it.
00:46:33
Speaker
I just want to write 20 lines of code and suddenly I've got this whole thing to grok and I don't want to do it. I looked at actually what the Cognitech guys did. I think it was on the Roomkey blog. Maybe it wasn't the Cognitech guys. Maybe it was the Roomkey guys. That's a big project enclosure.
00:46:55
Speaker
And what they did was they basically just used the Kafka Java client and just did interop and just coded directly from closure directly into the Java. They didn't do exactly what I wanted, but I just followed that pattern, actually. And I ended up writing this proxy. Okay, it's not finished yet, but if it's quite kind of, it's functional, it works, I can use
00:47:24
Speaker
I can transmit service and events for a topic on Kafka and it's fast and it's fine. But it's literally 20 lines of code and there's no libraries. Well, there are libraries for doing... Yeah, but the standard. But not for interfacing with Kafka, yeah. Okay. Yeah, but that's the advantage with... Of course, you can always fall back to Java pretty quickly. And I think that is one of the advices that I heard some time ago. Like, don't start to...
00:47:59
Speaker
trying to invent new abstractions on top of it, so. Exactly, yeah. Maybe it was from the Boeing guy's presentation, I think. I'm not sure though, I need to look it up. I think it's in the air actually, I remember hearing that from, I'm pretty sure I heard that on the Cognitech actually. I think it might even have been Craig Andera that said it, not one of the guests, I think he was talking about his experience, because he was saying that
00:48:21
Speaker
make your own things as much as possible just use the interop because you're not
00:48:25
Speaker
You know, he often does this now. And there's obviously a, there's a breaking point, you know, once you get to us. And again, it's, this is one of these funny things actually. And it's very, it's very slippery actually. It's like you say, it's always a discussion amongst the team. It's where do you move from the Java interop to the library, to the framework?
00:48:44
Speaker
to the module systems. I don't like the fact, but I'm open to the fact that there isn't a single answer to that. And actually all of those things are good, they're all possible, and you want to be aware of all of them and use each of them appropriately.
00:49:07
Speaker
So, like you said, I think the big thing is about communication. That's what you said at the beginning about how do you communicate your intent. And I think that's one of the things that we're really coming up with in closure, actually, isn't it?
Managing Codebases with Clojure Spec
00:49:23
Speaker
Our goal is to communicate our intent via data, actually.
00:49:27
Speaker
Yeah. Yeah. And also that the newer tools like spec, for example. Yes. That's giving us all the niceties of specifying what this function means. And when the code base becomes larger and larger, you know, you don't need to keep all these things in your mind. You know, you can reason about the code easily and then follow the specs.
00:49:48
Speaker
Yeah, I think spec is really gonna help us a lot in terms of being able to use, again, this data first approach to be able to say, okay, this is what our data looks like. This is what the function is meant to do. This is meant to produce this kind of result. It's meant to take in that kind of shape of data. And honestly, I don't know of any type system that is as powerful as this thing.
00:50:18
Speaker
Yeah, of course. Well, the type systems are only telling you what is the type of the data, right? I mean, they can't tell you what is the shape of the data. And they're not helping you in terms of like generation, generative testing, for example, automatically generating the tests and validating them. So it's a kind of a choice, again, as we are talking, I think it has been the theme of this episode, like you have at every point, you have a trade off that you want to make. So
00:50:47
Speaker
I'm making a large application, how I'm going to design my application, and how I'm going to specify the dependencies. And the next question is, okay, the types versus specs.
00:50:59
Speaker
And that is a whole different discussion. So there is some dependency typing can solve some of the problems, but I'm not sure how it is going to solve the same problem with specs. Well, the thing about spec which is really nice is all these testing things, you're right. The other thing we should talk about coming back to that, though, is
00:51:25
Speaker
how do we expose APIs to each other? And the thing that I've been working on recently is looking at, well, essentially why are APIs good, but why also are APIs a kind of failure as well? And they're good because if you want to give people access to a certain set of functions like Google Maps or whatever, then having it as an API is a huge win.
00:51:52
Speaker
So that's excellent. If you want to integrate with Stripe or something, you need an API. So if you want to give people a function to grapple with, then obviously an API is fantastic.
00:52:09
Speaker
But often, in the corporate world, APIs get in the way, actually. They get in the way of interoperability, and they get in the way of integration. Because people want to write these APIs. They want to make them nice and generic. But they're not reusable services half the time. And so we're fighting with this concept of reuse in the corporate world, where actually, there is very little reuse.
00:52:39
Speaker
Just give the guy the data. Which is why I'm liking these event streams a lot recently. Because you can start to put data on event streams and allow different clients to interpret and form different views of that data according to their own needs.
00:52:59
Speaker
And they don't have to hook round and go round to each of individual domains and say, okay, well, what's your API for this product? What's your API for that inventory? What's your API for? No, just give them the product information, give them the inventory information, give them the sales data. Don't make APIs around that stuff.
00:53:17
Speaker
But did you look into the microservices stuff then?
Microservices Architecture Essentials
00:53:22
Speaker
How that fits into the architecture in general? Yeah, well, we are looking at microservices, absolutely, yeah. And it's always a kind of funny question about what's the difference between a service and a microservice, you know? And it's a total joke, and I was kind of like one of the
00:53:41
Speaker
one of the kind of eyes-rolling guys as well at the beginning of this. But I think there are some specifics around microservice architectures that are interesting. And I think the biggest, the most important one probably is this discovery thing. If I've got a microservice architecture, well, I've got 20 microservices. So how do I look them up? And how do I make sure that they're all online? They're all available in what version they are.
00:54:09
Speaker
all this kind of stuff. And I think that there's some nice bits of tech around that. So there's this thing called Console from HashiCorp, which is very nice for registering services and for managing them. And you can get networked apologies from it and all this kind of stuff. It really is a very nice thing. But obviously DNS is the ultimate one of these things. That's a very nice way to do registration.
00:54:36
Speaker
So I don't want to go back to kind of the cobra days of objects registrations and all this kind of crap. JNDI. Oh God, yeah. You know something about JNDI, which is a bit off topic, this one, but what the hell, I'll just say, is that I think if you look at JNDI today, I haven't looked at it for a while, but I looked at it about, I don't know, five years ago, four or five years ago. I very much doubt it's changed.
00:55:01
Speaker
is that the packages, if you look at the packages, the Maven packages for JNDI, there's at least two of them, which are beta. And they've been like that for about six years, at the time I looked, so it must be more like 10 years now. So yeah, that got a lot of love, yeah.
00:55:22
Speaker
This is a perpetual beta. What's wrong with that? It's a continuously improvement. It never changed. It was a continuous beta that never changed.
00:55:34
Speaker
Anyway, back to the microservices. So those guys, the discovery stuff is definitely key. And then there's other stuff which you see the Netflix guys doing is what they call a circuit breaker pattern. If you somehow can't find a connection to that other application, what's your fallback strategy? Do you kind of look somewhere else? Or do you look to a different service? Or do you have some kind of default behavior in you?
00:56:03
Speaker
if that thing, you know, if you OK, you know, unhappy sort of four or four style thing, which is nice because that means that then, you know, in terms of your your architecture and your design, the things that you're thinking about is right. Well, all the stuff that's behind me on the network is essentially fragile. It's essentially unstable. And I need to acknowledge that, which is which is good. That is a good thing because we were with
00:56:32
Speaker
There's too much in our industry of pretending that there's a lot of certainty out there. Well, it's true, isn't it? It's laughable. It truly is laughable. But this is more of an acknowledgement that things will break. It's a given now, things will break. So think about it up front. Don't just cross your fingers.
00:56:53
Speaker
So I think that's how ultimately, if we're talking about scaling, those are the kind of thoughts we have to have, isn't it, about how do we actually make things survive failure? And all this kind of stuff that... I'm not going to go into all the Chaos Monkey stuff, but that's all the big data center stuff. But the main thing from a programming perspective is that you need to think in your code, well, I'm making this call to this service, out to this URL, out to this network thing.
00:57:21
Speaker
And most people's code just says, right, what's next? Or exception, meh. There's no recovery. There's no intermediate thinking there. And of course, actually, what's interesting about that is that that whole hysterics thing, that whole layer of circuit breaking is another kind of friction, if you like. Because as soon as you admit that things can fail, then you have to have some
00:57:51
Speaker
kind of framework or some kind of library or at least some kind of approach that you want to put into place. So I like that. I'm kind of getting used to what microservices actually mean. I mean, microservices, services, blah, blah, blah, blah, blah.
00:58:09
Speaker
There's some organizational size stuff that microservices are, but I think the main movement of our microservices is just to say, hey, we've got a lot of services on the network that are collaborating, so we need to find them. We need to deal with failure. I think that's really what microservices is turning out to be. I haven't tried writing any microservices yet, but
00:58:32
Speaker
I'm still waiting for the nano services and femto or auto or whatever and then there is going to be a service that is going to give me bites every now and then. Yeah, but they're coming out there actually, you know. The Lambda. The Lambda, yeah. The Lambda is your nano service, isn't it? But actually it's even worse than that because you know the Docker thing, yeah? You know they bought this company recently. It's like, it's an old camel company actually.
00:58:57
Speaker
And I come with a name now. I will look it up and put it in the show notes. But they bought this company. And this company was basically a uni-kernel company. So you're familiar with uni-kernels, I guess? Yeah. So this was the original uni-kernel company who wrote their own TCP IP stack and had this Mirage project.
00:59:20
Speaker
I don't know if you've heard of the Mirage project, but just for the people who haven't heard of it, it's this concept that instead of taking the Linux kernel and putting a container on top of it or a VM on top of it, that what you do is you basically take the bits of the Linux kernel that are necessary for networking or for file system access or for
00:59:45
Speaker
for some limited set of process management and then you compile them together with your application code and you drop that into the desktop or the application or the web server environment putter
01:00:02
Speaker
put a kind of port out there, and then what's interesting about that is that they did some experiments with it, and what you can do is you can use this services, what's it called, the services daemon where if you get a call, it starts your program up, what's that called again?
01:00:28
Speaker
Anyway, look it up. Yeah. It's some sort of service team in any way in Linux. And what happens is that when you get a request on the web server, there's no web server,
Serverless Computing with Clojure
01:00:43
Speaker
in fact. You just get a request on the router. And as soon as that port number gets some ping on it, it starts up the uni-kernel process. Bootstraps the whole thing.
01:00:54
Speaker
the code runs, it makes the return of the bytes and it dies. So it's like, instead of like a thread per request, you get a whole machine per request. Per request, yeah. Okay, that's pretty interesting. Yeah, but this serverless thing is something which we've found very interesting at work because I was very taken by this Lambda presentation when it was first done at Amazon and we got access to the beta
01:01:24
Speaker
during the Christmas after it was announced in the October and we started playing with it and it was really great because you could run an event driven system on the back of these lambdas and we designed this system for managing requests for information
01:01:48
Speaker
It's turning into quite a big system now, it's called a customer engagement system. It's a kind of putative CRM actually, but what's interesting about it is that you can start very small just by taking some web forms and managing the kind of reaction to the web forms in an event stream.
01:02:07
Speaker
And then you can start to add integration. So we have integrations now for Salesforce and for various other kind of sales support activities and dealers and retailers and all these kind of things. And eventually you get this kind of
01:02:24
Speaker
evolution of these things and because it's a serverless environment you're just dropping lambdas in you just drop more lambdas in we have a dashboard that shows the progress but these lambdas as you add more functions
01:02:39
Speaker
you don't need to disturb the other Lambdas. The actual, like the continuous integration problem almost goes away because everything that you're doing still stays valid. You just put the extra function on a completely separate infrastructure because there is no infrastructure. And it's actually what I call functions as a service because that's really what it is. But did you try with the closure on Amazon Lambda yet?
01:03:09
Speaker
I've tried it, and it all works fine. We haven't done it at work yet, but I've done it both with ClosureScript and with Closure. The Closure one works fine, by the way. I know there's a lot of talk about
01:03:26
Speaker
the closure script one is faster for the startup and all that kind of stuff and I think that's kind of true if you're getting a lot of churn but actually the way Amazon works is that the Lambda stays around for quite a while so you don't really
01:03:42
Speaker
Yeah, I need to boot up every time. If you're not getting much throughput then I guess there could be some small benefit, but also depends on the problem you're trying to solve. Anyway, but they both work and they both work really easily actually. You just uber jar it and off you go.
01:04:00
Speaker
You just write that one up with one bit of code. In fact, I think the USwitch guys made a little demo, that's what I used, they made a little demo wrapper around the Java thing. And it's literally five lines. So, bam, off you go. And it works really well, yeah. So yeah, so closure, I mean, honestly,
01:04:19
Speaker
maybe as we're coming back to this kind of scaling things because like you were saying before we keep on nodding we keep on sort of tapping each other on the shoulder and say an hour's nearly up and I think it is already so we probably should start to wrap this up now yeah of course I mean so anyway coming back to the I think we have
01:04:36
Speaker
started from all the way and then we went to the lambdas now. So my current toolkit, or at least the new project that I started last week, so right now my toolkit is essential. I never tried component, but I'm planning to use mount this time. And then see how it is gonna go out. And obviously I'm gonna use spec for this one. So I'll report back what I find, and it'll be fun, I think.
01:05:04
Speaker
Definitely. Yeah. Just before we go with the component mount discussion, I had a discussion. Actually, it was with Hoplon, the Hoplon guys. Mischa wasn't involved in this discussion, although the guy you was talking to was
01:05:21
Speaker
was saying that this is what Misha tells us is that actually all these component frameworks and mounts and stuff like injections and all these kind of things are doing the wrong thing and you should basically explicitly pass in database handles and server handles and all these kind of things into the functions and not hide them behind these component systems. So what do you think about that?
01:05:49
Speaker
Yeah, I mean, there is always a, again, this is the standard discussion about dependency injection, good or bad. And, you know, because when I started writing a program in Scala some time ago with our characters, and we had the similar discussion about the design choices, like should we use injection or should we just pass all the things like a builder pattern, you know, just pass the whole thing. And I think we ended up doing passing the whole stuff because then each function becomes
01:06:20
Speaker
a function, it's not dependent on external crap. So that's why I didn't even, well component is not actually a complete dependency injection, it's not a runtime dependency injection, you still need to specify this is what I need so that needs to be passed around. So I'm kind of in between I would say, so I'm gonna write down a reasonably big program to see how it feels
01:06:49
Speaker
and then beside, okay then screw it, I'm gonna remove the component and then just go ahead with passing the functions around.
01:06:57
Speaker
So no direct answer, no yes or no. And I think the argument typically is, isn't it, that like you say, the transparency of the dependencies is right there in your face and there's no magic so that when you come to run this thing you're not sort of suddenly, oh, didn't read the documentation about this needing a database or a Redis or a blah, blah, blah.
01:07:21
Speaker
Incidentally, just as a final little aside here, is that one of the things that I have looked at over the last couple of years is Heroku. They have this thing where you can now say, they have a little, what they call, it's like a Node.js file, it's not the properties one.
01:07:47
Speaker
Oh, a buildpack or something? It's like a buildpack. Well, no, it's a dependencies. So it's a bit like an NPM file. But what you say is rather than having a module that you depend on, you can say that it's a service you depend on. So it's a bit like this kind of like behind Docker or behind these kind of orchestration engines.
01:08:08
Speaker
So they have this thing where you can say, I require this add-on, I require this service, and then it can be bootstrapped. So that's another kind of interesting modular approach, if you like, is that you want to be able to express in data what your dependencies are and be explicit about that.
01:08:27
Speaker
Yeah. So we should wrap up, I think. So in conclusion, my, my, my toolset right now go with the functions and then use specs and try out component or mount, essentially mount this time. And I think the scaling is essentially depending on how you, how you approach and, and.
01:08:49
Speaker
There is a it's still an open question and we know there is a lot of code out there like circle CI guys building large closure programs and Obviously there is a data omic. I don't know how much of data omic is written in closure though It will be interesting to see but I think that's that's it from that is that's it for us For today. I think we should wrap up with a quick overview
01:09:16
Speaker
So we're going to post the show notes on Deaf and audio. And obviously the episodes will be on, maybe you're listening to it already on iTunes, so tell your friends and their friends. Leave a review actually, that would be quite nice. I haven't seen the reviews. I must write a review myself, but you know how awesome it is. It would be nice to get a few reviews because that helps to spread the word as well, I think.
01:09:44
Speaker
Exactly. And if you have any nice ideas that we should focus on or guests that we should invite, please let us know. We would love to invite them onto the World's Best Vegetarian Closure Podcast. And that's a privilege, obviously. Anything else? Oh, of course. We'd like to thank Pizzeri for the intro and outro music. And you can find more of his music on SoundCloud under Melon Hamburger.
01:10:13
Speaker
Yeah, that's right. So yeah, so yeah, it's been good. Yeah, thanks very much. Hopefully not too much. Well, there's quite a bit of a village going on in this episode. We'll be, I think we'll be back to getting a guest to keep you a bit more amused next time. Maybe it's more, you could be amused on this one and more educated on the next one.
01:10:36
Speaker
So this is the comic relief, everyone knows that. Exactly, exactly, yes. Okay. Alright man. That's it from us. Yeah. Bye bye. Bye.