Transcript
Kevin Montalbo
In a developer profile survey conducted by stack overflow. This year, 55% of the respondents identified themselves as full stack developers. This represents a 7% increase over the last two years alone. It's apparent that developers are becoming proficient in more programming languages. Either that or they're using technology stacks that cross the boundary of both front end and back end development polyglot programming. Whilst not a new concept is becoming increasingly relevant to full stack developers and to microservice architectures. That's because it allows a developer to mix and match programming languages to suit their personal preference expertise or the functional requirements of the project. Today on cocktails, we discuss polyglot programming with the person who originated the phrase itself. We learn how polyglot enables a developer to express his or her creativity, how it is a natural fit for microservices and where low code fits into all of this.
Hello internet. My name is Kevin Montaldo. Welcome to another episode of Coding over cocktails. Joining us today all the way from Australia is of course David Brown. Hi, David. Good to have you on.
David Brown
Good day, Kevin.
Kevin Montalbo
And our guest for today is a director software architect and meme Wrangler at Thoughtworks, a global it consultancy with a focus on end to end software development and delivery. He's also the designer and developer of applications, articles, video presentations and author and editor of an increasingly large number of books spanning a variety of subjects and technologies including the most recent presentation patterns. His professional focus includes designing and building large scale enterprise applications. He's also an internationally acclaimed speaker, speaking at over 300 developer conferences worldwide, delivering more than 2000 presentations. Joining us today for a round of cocktails is Neal, Ford, Neal. It's a real privilege to have you on the podcast.
Neal Ford
Thank you very much for having me. I'm happy to be here.
Kevin Montalbo
All right. So let's begin in 2006. Martin Fowler, your friend, wrote that you coined the term polyglot programming to express the idea that application should be written in a mix of languages to take advantage of the fact that different languages are suitable for tackling different problems. So can you tell us the process that led you to coming up with the term polyglot programming?
Neal Ford
Well, I think it's one of those things that's, it's kind of obvious in hindsight because if you go back to 2006, when I came up with that, that was really the beginning of the, the kind of Cambrian explosion of languages supported on both the JVM and.net, you know.net was specifically designed to support multiple languages. But the JVM came out strong too and, and it was a bit of engineering brilliance. I think on the part of the JVM to separate the run time from the language and have basically an assembly language that runs the runtime because it allowed them to innovate on the run time without affecting the language and vice versa. And so then suddenly you had languages taking advantage of that run time that weren't natively Java and I started so I've been a language geek forever. That was my, one of my specialties when I got my computer science degree was languages and compilers. I've always loved computer languages of all kinds and, and it fascinates me how they're like and how they're different. And so I noticed that and this is part of the beginning of the rise of tools like Ruby on Rails, which is kind of the two, the mid two thousands version of the rapid application development tools from the mid nineties. So my first book was actually a Delphi book which is a rapid application development environment, but way back in the nineties, and there were a lot of similar aspects to Delphi and four GLS and the low code environment stuff that we see now. and the rise of tools like Ruby on Rails. But you've seen even more pervasive versions of this with tools like Gradel, for example, which is a domain specific language written on top of groovy that has become sort of the universal bill certainly for coin and a lot of the Java ecosystem as a replacement for Maven.
And it was an observation that, you know, a lot of these new languages, particularly dynamic languages give you a level of expressiveness that's just not possible in static languages like Java and particularly around things like user interfaces. So I don't know if you ever wrote any swing user interfaces. But there was just an enormous amount of declarations for types and all and it's like their user interface. I don't care about the types and the compiler yelling, I just wanna build quick simple user interfaces and a lot of these other languages allowed you to do that more freely. And because they all compile down to byte code, it made me realize that hey, there's a common language here that you can maybe for the first time, really effectively mix and match languages. And so let's talk for a second about computer languages. I've always been fascinated by computer languages and because computer languages, it's an engineering medium, but it's also a creative medium. And so there's a great debate in the programming world about static typing versus dynamic typing, which is almost as fraught as the V I versus emacs or eclipse versus intel J arguments. And in that there's never gonna be a resolution and what made me realize that. So I've met Martin Odersky, the person who created Scala, I've also met and chatted with Rich Hickey. The person who created closure. Scala is a very strictly strongly typed language with static typing. Closure is strongly typed but dynamically typed.
If you take Martin Odersky and make him write closure, he's miserable. If you take Rich Hickey and make him write Scala, he's miserable. But if you allow them to work in their own medium, they're incredibly productive. And what that made me realize is computer languages can't be objectively evaluated because it's creative medium. Every person finds the creative medium that they like to push against. It allows them to be creative. There's a great quote that I bring up here from William Faulkner, the Nobel Prize winning novelist and he very famously has a quote that said, I started out as a poet and I was terrible as a poet. So then I tried writing short stories and I was terrible at that too. So I guess I'm a novelist, but he discovered what his kind of, you know, the real secret of creativity is not freedom. It's constraint, it's the right kind of constraint to push against. So I have a strong preference in computer languages for dynamically strongly typed languages like closure or ruby. I find that I hate arguing with compilers, particularly when I know I'm right and the compiler is just being a bureaucrat and yelling at me about something is like I got typecast this again. This is the right thing. Stop yelling at me about that. That's frustrating to me. I'd much rather write tests and validate that way than have a compiler. But there are a lot of people who love having the compiler to argue with and you know, to validate what they're doing. And so it made me realize that there is no one true programming language that developers should be able to choose their own. And if you extrapolate from that, there's this idea that we can't do we have environments now that would support this idea. Now you can't freely mix and match because, you know, at the fundamental level, there's still some differences, but it does open up the door for, you know, a team to write Ruby on rails on top of Java. You know, J Ruby was a big thing in 2006 where you could actually deploy your Ruby code on the JVM. And that allowed you to be a Ruby developer, but still take advantage of the good engineering behind the JVM. And so there's a very long explanation for, you know, I realize that, you know, it is maybe for the first time ever possible to allow your creative muse to run wild as you run programming, but still have good engineered solutions that have a fighting chance of being able to integrate with the stuff that other people on your team are also writing,
David Brown
You talk about a creative preference in terms of a language. What about like a functional preference where a language is just better suited to a purpose, you know, polyglot.
Neal Ford
Well, there, there are certainly cases of that. So the only person that I know that has Haskell code in production and that's a pretty rare thing because Haskell is a great way to think about things. But man, you do not want to put that in production and argue with like I and stuff like that forever. But there are CTO Rebecca Parsons actually talks about some code that was production ready that she created in Haskell. And she said, you know, they were doing like signal transformation process and all this really heavy math and it was like a hand and glove fit for that language. And so there's a lot of the affordances the language offers you to get stuff done, you know, at some point, they're all touring complete. And so, you know, anything you can write with assembly language, you can write with Erlang or Ruby or C# but, but it's how difficult it is to write that and what affordances does it give you? And I think that's the thing that developers, the creative side of developers, you know, software development is this weird mix of creativity and engineering. I think that's the real appeal to software development because it's almost equal parts, you know, artists and versus engineering and finding the way to express the artisan part of yourself while supporting the good engineering stuff I think is a quest that every developer goes through. And if you're lucky enough to have utilized a whole bunch of different programming languages, I think you finally settled in on the one that you feel most comfortable in.
Certainly for me, my two favorite languages now are Ruby enclosure for very different reasons and I use them for very different things. So Ruby for me is the language that provides the most developer happiness almost to a pathological degree. So Ruby is so helpful that it will help you right into a snake pit full of vipers and all sorts of bad stuff. And it'll gladly help you right along the way because it's trying to be as friendly as possible and offer you all these affordances, closure is trying to maximize engineering happiness. So it actually tries to get you to avoid bad things like immutability that's discouraged strongly in closure because they've realized that, hey, that's kind of bad. So for building really big well engineered things, I think closure is awesome because it gives me strong but dynamic typing. It's also a lisp which has some distinct advantages but it's not nearly as friendly as something like Ruby. So when I write little scripts, I still use rake all the time, the Ruby Build tool because it uses the ruby language features, but then this beautiful, almost transparent way. So I actually wrote some rake code today for the book project I'm working on because the thing that checks in my book stuff is a rake file. But if I really want to build something that's very well engineered, I'll choose something like closure. So I think it's really contingent on every developer. And in fact, it makes me sad when I see developers who've really only used one language. In fact, I'll tell you the killer interview question. If you ever have to interview someone from a programming job, I do this for every interview I do for a developer. And one of the questions I asked them is so let's say you,, claim that you're an expert in Java. OK? So now you've been made king of Java, which means you can add any feature you want to the language. But in doing so, you also have to remove one of the existing features that you don't like. Go. I don't actually care what the answer is. I want to see the thought process because if you've only ever worked in Java, you'll just freeze up like a deer in headlights because like I can imagine adding or removing anything because it's the only thing I've ever used. But if you've been in a dozen different languages, they immediately kick into., wow. What would I?, generics? You gotta get the, you know, gotta fix that and your serialization, you gotta get rid of that.
But then, and so you see the thought process and it really shows you how polyglot that person is. Because every programming language you learn, you learn some new aspect of programming and you take that into the programming language you're currently using all the time. Everybody here has had the experience of, you know, if you transition from Java to Ruby or closure Scala, the first code you write is just really bad Scala code that replicates the Java code. But as you learn the idioms of Scala, you become more of a Scala programmer. But then when you go back to Java, you take a bunch of those idioms with you and you're more effective Java developer. So I believe that the more polyglots you are the more effective you are in your native language, whatever it is because you've seen lots of different ways to solve problems. And it gives you more tools in your toolbox to reach for in terms of abstractions and patterns and capabilities that you might not have had before. The big shift of course, is the functional programming shift that all these languages have gone through. Java was the last big one. But now we have streams, we have map and reduce and filtering and all those things, which is just another really nice set of tools in a programmer's toolbox that well I can now I can use iteration, I can use a design pattern or use map reduce all within the same language. And if you've got experience in several languages, you know how to better use those tools in your toolbox.
David Brown
Let's talk about architecture. The, the polyglot programming seems to be a natural fit for microservices where you can have multiple teams working on a project, independent project services oriented architecture where you're designing services in independent teams, they're using their languages of choice, whether it's a you know, personal preference or because they find that programming language is a fit for purpose. Is that what you're finding is microservice a natural fit for mixed for polyglot programming?
Neal Ford
It is because there's such a level of isolation. Of course, it's based around this idea of a bounded context. There's a great story from the early days of microservice from a well known to do list application called Wunder List. And Chad Fowler was the architect on that. And it was one of the early microservice success stories. And one of the things he did was mandate that every service be written in a different language, which is a bit extreme. But one of the things that you're trying to achieve in microservices is no incidental coupling between their services, no shared stuff because that breaks the bounded context and one surefire way to make sure nobody's accidentally sharing anything is make somebody write it in.net and somebody else write it in Java. There's no way you're accidentally sharing class files across those. And so it forces that level of decoupling. But the real benefit of that is that it allows developers to not over engineer things and use a language, a database, a platform that's more suitable for the problem.
One of the big so speaking of architecture, one of the anti patterns we commonly see in large organizations is this idea that hey, we're gonna standardize on a single technology stack because that'll be cost savings. So when you think about governance and architecture, there are two philosophies: software is either overhead or it's strategic. What do you do with things in an organization that are overhead, you minimize cost because the more you minimize the cost of overhead, the more profit you make. And so one of the failed strategies that people do is, well, one of the ways to manage overhead is to standardize on single platforms and single technology stacks. So we'll pick Java and Oracle and Mulesoft, et cetera. But the downside of that is OK. So now let's say you're a responsible enterprise architect in an organization like that and you only get to pick one relational database. Well, you need to go find the team that has the worst aless nastiest relational database problem. And you've got to pick a tool that's powerful enough to solve that problem. The problem now is you now force that complex tool on every team because you only get one relational database. If you're like most organizations, most of your projects just need a dumb place to store stuff and get it back. But they're dealing with the complexity of an industrial strength database. If you only have one option in your enterprise, you always have to pick the most complex thing. And now everybody is using the most complex thing. And the irony of that is the motivation behind that philosophy is cost savings. And now you're over engineering everything to the point where you're just burning through money because you're using these crazy complex technology stacks for very simple problems.
One of the great revelations in microservice is like stop simple things can have a simple tech stack PHP, my SQL database done. We'll get it done in a week and we're over versus Java, Maven, Oracle enterprise service. But you know the whole technology stack. The great revelation for this to me was a big enterprise client we're working with at some point and we were asked, I'm a consultant by trade. So we're asked to come in solve this problem. It was the quintessential mid early two thousands architecture where it was AJ two EE they were using Cocoon, which is this publishing framework and this giant enterprise service bus. And, and I was brought in because they were having problems because their application server was getting stack traces because of thread problems and a bunch of other stuff. And at some point, somebody said, yeah, you know, and all this stuff is here and, you know, the 12 users don't like this very much. And I said, 12 users. What are you doing? And it was literally this thing where you filled out this wizard like four pages and then clicked OK to get a project code. And they had built this thing, like it would launch a space shuttle. And I said, look, I'll go home this weekend and Ruby on rails, I'll write the whole bloody thing in like six hours and we'll be done and we did. And that was the revelation for them. It's like,, we have over engineered everything to a ridiculous degree. And if you only have one thing, it dries this massive over engineering. And so part of the giant benefit of microservices related to this idea of polygon programming. Is it freed organizations to say, let's right size the technology choice for the size problem we have. Now this is not advocacy to go crazy with this. And we let a 1000 Flowers bloom. And so in our building evolutionary architectures book, we actually introduce something and this is the hazards of writing a book. We introduced something that we call Goldilocks governance. And then we realized after we published the book that only people in Europe and the US know who Goldilocks was. Nobody in Asia or anywhere else knows the Goldilocks fairy tale. But of course, the idea was finding the just right fit for these things. Not too much, not too little. And the idea goldilocks governance is let's pick a few technology stacks, a simple one, a medium one and a complex one and standardize on those rather than one size fits all or, you know, one unique one for everybody. And I think
microservice really facilitates that because it does have an extreme level of decoupling. And that idea of bounded context which keeps everything local from a technology standpoint and you can integrate with things as you need to without going down that over engineering route.
David Brown
How does the paradigm of low code application development fit into all this and the paradigm of like design patterns?
Neal Ford
So design patterns are interesting in that they've slowly been eaten by programming languages. So if you look at the original design patterns book, I actually just did a talk at a conference in India last night. It was morning for them but night for me because that's the way things work now. But it was modernized design patterns because if you look at the original Gang of Four book, which was written in the early nineties, the two Exemplar languages in that book were C++ and Small talk. Now there's still a fair amount of C++ and it's undergone this revolution. It's a really modern programming language now, but not the version from the mid nineties. And a command design pattern is a great example of that, that is built into every language you will ever use. Now, in terms of closures, as soon as Java finally built closures into the language, the command design pattern literally melts away because it's now a feature of every language you ever use. And so many of those design patterns have been slowly eaten by facilities that are native to compilers. And in fact, there's a whole new set of what we would now call design patterns that come from the functional programming world. If you look at things like capabilities like mapreduce, well, if you expand that into architecture, you have hadoop, which is a big giant mapreduce framework. And so we're seeing new patterns show up that are sort of the next generation of design patterns because in many ways, the design patterns book should have been called making C++ suck less. But now we don't have a lot of the constraints in the languages because the languages are growing toward the expressiveness we need. And the, the latest sort of a board like assimilation of all these functional programming concepts and all the mainstream languages is a great example of that. We're borrowing all these patterns from the functional programming world and adding them to pretty much every language that's out there.
Now, the low code thing is very interesting. I'm a member of the ThoughtWorks Technology Board and we produce the ThoughtWorks Technology Radar twice a year. And we just came out with the most recent edition within the last month. And one of our themes was a theme called Democratizing Programming, which is exactly about these low code environments coming out now. Now I'm an architecture, I'm an architect by trade and I view there's nothing in my world that is pure advocacy because everything is a trade off. My most recent book was Fundamentals of software architecture. And we codified our first law of software architecture as everything in software architecture is a trade off. And the first corollary to that law was if you think you found something that isn't a trade off, you just haven't identified what the tradeoffs are yet. And that's the hazard with low code environments is people go in and they only look at the capabilities but they don't look at the tradeoffs. And so they're useful for a lot of things. But then people believe that they're useful for everything. So one of the things that we codified in my book, Building Evolutionary Architectures is this thing that we call the last 10% trap and every low code environment suffers from this. So I'll describe this and then apply it to the modern world. So this revelation came to me because I used to work for a consulting company that did application development for clients in Microsoft Access and we ended up shutting down that division of the company because we realized a common pattern kept reoccurring that every access project started as a booming success and ended in total failure. And we wanted to understand the dynamic of why that kept happening over and over again and we codified, this is the last 10% trap. So using something like access, the 1st 80% of what the user wants is amazingly fast and it's just spectacular how fast you can get there. The next 10% is possible but difficult because now you're trying to do something, the tool wasn't really designed to do, but you can kind of bend it and hack it and figure out workarounds and other stuff. But that last 10% is impossible and users always want 100% of what they want.
David Brown
Well, this is a really interesting point and this is what we're often telling people is the difference between a low code solution and a no-code solution is. It's that critical last few percent where to get the job done, you really need to code to be able to be able to get there and build it is whatever that custom function is or custom workflow or whatever it is that you're trying to build is you ultimately want to be able to write some sort of script or to some sort of library object, whatever it may be that you can call into your, into your low code application. And so when we're talking about low code, we're not talking about no code. And so that democratizing-
Neal Ford
It's a matter of degrees because you remember, do you remember the four GLS?
David Brown
Yes.
Neal Ford
Access Deboo for Windows Clipper Power Builder? Where are they? Now? Those were all low code environments. They all suffer from the last 10% trap. So I will use your low code environment if you will give me the following things. I want the ability to diff it. I want to be able to diversion it. I want a first class IDE that gives me refactoring support. I want to be able to test it at the unit functional and user acceptance level because I get all those things with code. And so if you're gonna make me go to a different low code environment, I want all those things because that's a trade off and I might not want to trade those things off because you know exactly where am I gonna go. So here's the thing that I've realized most recently if you are going to choose a low code environment. So your normal architectural approach when you're using something like that is build the simplest, you know, front to back vertical slice to make sure it works. That is not the correct approach in a low code environment. The first thing you wanna do is do the most difficult thing because you know the easy stuff is gonna be easy if it's not. Then what are you doing? You need to make sure how far you can push it to see where that 10% is gonna fall. And so the first thing you should do is the most difficult thing because that's where you're gonna find out that the transactional doesn't work or the scalability doesn't work or you can't get enough access to the underlying data to make it work. That's the way to vet a low code environment is not a simple hello world because that if that's not simple, then you've picked the wrong low code environment. It's the really complex things because the first thing you need to find out from an architectural standpoint is how far can I push this? And now that becomes your decision criteria.
This is not to say you shouldn't use it, but you should go to your stakeholder and say, OK, we've experimented, we can do 93% of what you want. Are you OK? Never having that last 7%. Because if you're not, then we can't use this environment. We've got to choose something else. If you are, then we're gonna go into this wide open. So when we get to 93% and say we're done, you can't say no, no, I want the next seven. It's like no, no, no. We told you way back when this is what you're gonna get. So spreadsheets are the perfect example of this because if I look at a spreadsheet as a programmer. What I see is a real time IDE with functional programming built in. It's a matrix manipulation. It just turns out accountants are matrix junkies. They just don't realize it. And the way that spreadsheets have been so effective is people understand their capabilities but they also understand their limitations. So you don't try to push a spreadsheet further than what it'll go. You realize that,, I can go this far with a spreadsheet, but then I'm gonna hit the wall, but that's ok because I knew that going in, you got to apply the same rationale to these low code no-code environments that are all the rage right now because it's exactly the same decision criteria. Can I live with the compromises? This is forcing on me.
David Brown
I think we're totally on the same page. You know, our approach with Martini was to empower developers with low code, not restrict them. So we're targeting enterprise class market with enterprise problem sets. You need the power of code when you need it. And so we'd looked at empowering them in terms of making them more productive, getting rid of those cookie cutter functions that they need to do over and over again, particularly for application integration or APIs or, you know, creating services and having them automatically restful or whatever it may be. consuming data, transforming data. These are a lot of cookie cutter functions which can be cut down into a low code environment. But when it comes to that proprietary function for your particular business process, it may be that you need to write some code or and you, you need to be able to slot that code into that low code environment. And so that's exactly the process philosophy we've taken with our local tools is that we're not trying to limit yeah, put a firewall, the developer in terms of the scope of the application that they can build. The objective is to make them more productive as a result. The solution is not designed for a citizen developer because you know getting the blend where you having a low code environment, you can either go for the citizen developer and make it no code. And, and you're gonna have those limitations that you know that Excel spreadsheet type limitation, which can be perfectly fine, can have a very wide market as spreadsheets do. But if you're targeting a professional developer, then there's no point putting those boundaries on them.
Neal Ford
Well, there's a spectrum here. So almost everything in software is a spectrum too, which is why I believe we keep going back to fourth generation languages and these fundamental architectural styles like micro kernel, modular monolith, microservices because those are indeed flexible enough to solve any kind of problem and any level of abstraction, we try to build a of that always has some sort of limit built in. And I think it's the job of an architect. So one of the things that I try to instill in junior architects at ThoughtWorks is don't become a blind advocate for anything because by definition, if it's an architectural component, it has tradeoffs. And so your real job as an architect is, can I objectively evaluate the tradeoffs on either side of this decision and make an informed decision going forward and realize that some of those decisions are in fact nonreversible. But you're OK with that because using a low code environment will get you to the the intermediate finish line or close enough finish line faster.
And that's more value to the organization to build it in a more traditional kind of software stack that will take much longer. But you have that ultimate degree of flexibility because it moves so fast now, it's often very strategic to choose an environment that gets you to 90% there and don't worry about the last 10% just like a spreadsheet rather than spend the time to get all the way to, you know, 100 or 99% using something more traditional. So it's always about evaluating tradeoffs objectively, one of the things that I tend to say is I try to never let architects use words like best or worst. It's a different sets of tradeoffs that's the thing you have to evaluate as an architect is what are the real tradeoffs here and then make an informed decision going forward. Because in many cases, I try not to make architecture decisions. I try to evaluate tradeoffs and go to stakeholders and say, OK, here are the menu of tradeoffs, pro and con you decide because it's your money, you decide and then we will build as much as we can in the approach that you pick, knowing that we have these pros and cons going in.
David Brown
Look, I think we can keep on going and going. There's so much to talk about and there's a whole bunch of topics that I would love to have addressed with you. Which I just don't think we're gonna have time for maybe in another series we can talk, I noticed, for example, you have a training program on services oriented architecture and where the microservices are now the ultimate iteration, you know how it fits into services based architectural styles and how SBS fit into all this and all of the stuff. So I would have loved to have an opportunity to talk to you about all that-
Neal Ford
We can always do it again.
David Brown
Yeah but we’ve run out of time today. Neal, how can the listeners find out more about you, the book you've written? And follow you.
Neal Ford
Ultimately, my website is nealford.com and it's N-E-A-L F-O-R-D because my parents thought it would be a fun practical joke to give me an unusual spelling for my name. But I was around on the internet early enough to get my name as a vanity site. So that's my website. Obviously I work for ThoughtWorks. I've been there for 15 years. And the ThoughtWorks Technology Radar. If your viewers are not familiar with that, that's a great resource. I'm also part of a semi regular host of the Thoughtworks Technology podcast. In fact, we were just talking about democratizing programming. Right after our radar came out, we actually did an entire podcast with several of us talking about the pros and cons of tradeoffs of low code and no-code environments called democratizing programming. So that's another great place to find me. But you know, conferences, I do a lot of stuff with my publisher o'reilly.
My most recent book is Fundamentals of Software Architecture and the co-author on that book, Mark Richards. And I are currently working on my ninth book, which is going to be called Architecture of the Hard Parts sort of a play on the javascript, the good parts. But it turns out there are a bunch of difficult things in software architecture and the most difficult thing right now is how do you assess tradeoffs in modern architecture? So it's an entire book about what does 21st century trade off analysis look like in architecture toward what I was ranting about earlier that everything in software architecture is a trade off. Well, how do you evaluate that stuff? So we're writing an entire book about that because that it turns out is the most difficult thing we encounter in the software architecture space. So we hope to have that out in July of next year. But fingers crossed, we'll see if we can actually make that date. I was writing books is kind of a slog, but we'll see if we can get it done.
David Brown
Amazing. Congratulations. We look forward to talking to you about that in the future. Neal. Thanks very much.
Neal Ford
Great. Thank you. Enjoyed it.
Kevin Montalbo
All right. That's a wrap for this episode. Thank you very much, Neal Ford for being with us. How about you listener? What are your thoughts on Polyglot programming? Do you have any stories that you'd like to share or any podcast guests and topics you'd like us to cover? Let us know in the comments from whatever podcast platform you're listening to. Also, please visit our website at www.torocloud.com for our blogs and our products. We're also on social media, Facebook, LinkedIn, Youtube, Twitter and Instagram, talk to us there because we listen, just look for Toro Cloud again. Thank you very much for listening to us today. This has been Neal Ford, David Brown and Kevin Montalbo at your service for Coding over cocktails.