The Changelog: Software Development, Open Source - Go, Martini, Gophercasts (Interview)
Episode Date: April 16, 2014Jeremy Saenz joined the show to talk about Go, Martini, Gophercasts, and more....
Transcript
Discussion (0)
Welcome back everyone.
This is the change log where I remember supportive blog podcast and weekly
email coming up with fresh and what's new in open source.
You can check out the blog at the change log.com.
Our past shows can be found at five by five dot TV slash change log and
subscribe to the change log weekly.tv slash changelog. And subscribe to the Changelog Weekly.
That's our weekly email we send out every Saturday covering everything that hits our open source radar.
Subscribe at thechangelog.com slash weekly.
You're listening to episode 117 where Jared Santo and I talk to Jeremy Sines about Go, Martini, the Go ecosystem, and even a little bit of Node as well.
Today's show is sponsored by digital
ocean new relic and top towel we'll tell you a bit more about new relic and top towel later in the
show so stay tuned but our friends at digital ocean they're a simple cloud hosting provider
dedicated to offering the most intuitive ways to spin up a cloud server you can spin up a cloud
server in 55 seconds with full root access,
and it just doesn't get any easier than that.
Pricing plans start out affordably at $5 a month for half a gig of RAM,
20 gigs of SSD drive space, one CPU, one terabyte of transfer,
and if you only need a server for a few days or to test an app, you can even rent that server basically by the hour. So it's super inexpensive,
just.007 cents an hour.
That's like,
it's hard to even say,
but it's less than a penny per hour.
It's.7 of a cent.
So super affordable.
But we have an awesome promo code
for you to use.
Use the promo code CHANGELOGAPRIL
to get a $10 hosting credit when you sign up.
Head to digitalocean.com to get started, and now, on to the show.
We're joined today by Jeremy Saenz, also known as Code Gangsta. We had a quick laugh there for a
bit, but he's known as Code Gangsta on Twitter and GitHub, and I guess probably everywhere else,
right, Jeremy? That's right. Pretty much everywhere else, except Skype. My Skype name has not changed yet, as you guys see.
Yeah.
He's here to talk to me and the managing editor of the changelog, Jared Santo, about the Go
programming language, his fun with it, what he's been doing, specifically his web framework
for Go called Martini and a bunch of other fun stuff.
So, Jeremy, welcome to the show, man.
Oh, thanks.
I'm really glad to be on here.
So I know that you've been a fan of the Change Log, right?
I do.
You tweeted it to us a couple, maybe a week back, and we wanted to get you on the show
anyways, and you just kind of fast-forwarded that a little bit.
Yeah, yeah.
I've been catching up on episodes. Um, the first one I watched, I'm not a long time fan, but I, uh, I started watching, uh,
Katrina, Katrina Owens podcast and I started catching up on all the other ones since then.
And, um, yeah, I think it's a great podcast.
I personally love the idea of podcasts.
I try to listen to as many as, as possible.
And, uh, yeah, so I'm super glad to be on here.
I'm glad I was able to just totally get in your face
and be like, put me on the show.
Yeah, that's cool.
But Jared was on the Katrina show as well.
We had fun on that one, didn't we, Jared?
Yeah, that show actually probably has a lot of similarities
to this one between the Ruby and Go influence.
Yeah, and you've been doing different, what are they called? Exercises
in, uh, exorcism? Oh, me? Oh yeah. Uh, I don't know. I guess exercises is the fair term. Exorcism.io
was, is Katrina's project. Yeah. And yeah, I've been having a lot of fun, uh, getting my code
reviewed up in there and nitpicked, as she likes to call it.
That's right, yes.
Learn a lot. You learn a lot.
Yes.
Well, Jim, where do we begin for you?
Let's start with Code Gangsta.
Oh, man.
Let's hear it.
Like what?
Code Gangsta.
So the cat's getting out of the bag now.
I just want to get it out of the way here.
Yeah, so this goes all the way back to me starting in the industry.
I actually started in the Flash and Flex world doing front-end development.
And the way I got into it was I was graduating high school, and I didn't really know what to do with my life. So I ended up going to this conference about programming that I didn't really know too much about.
And to break the ice and to kind of meet people there, I entered into this video contest.
And I was like, do you know what?
I have a background in music.
I have a background in audio.
I'm going to make a technical rap song.
And I made this rap song called Flex Gangsta, and that was my name for a while.
I did a couple rap songs after that,
and I don't really talk about it too much anymore,
but I still have Code Gangsta floating around,
and it's kind of fun to see people every once in a while be like,
oh my gosh, you're Flex Gangsta or you're Code Gangsta.
And it's funny seeing certain implementations of the song.
Like some people have it.
Some people have one of the songs, which is titled Who Broke the Build.
It's tied in with their Jenkins server.
So if somebody actually breaks the build, they like send the video or send the song to them via email or it plays in the office.
So these tracks are out there to be heard right now on the website?
Yeah, they're on YouTube.
If you search Flex Gangsta, you would find them on YouTube.
Nice.
So then you switched to Code Gangsta because you just figured you're going to get more
abstract and just genericize your name or something.
Oh, yeah.
Yeah, I left the Flash world quite a while ago.
And so it's not as relevant anymore.
Flexgangsta.com.
Did you know there's a.com?
I think that is my flexgangsta.com.
There you go.
I haven't updated in a very long time.
And you got Who Broke the Build on there.
That's awesome.
We'll link out that in the show notes,
but you can go to flexgangsta.com right now if you want to.
In the show notes, we'll have some links out to it.
Yeah, if you find me at a conference and buy me a drink,
I might do some raps for you.
Fair warning.
Wow.
Have you ever seen Chris Anderson's Couch DB song?
It's probably not quite as epic as your rap.
You know what?
I have not.
He did it on the channel a while ago.
We met him and Jan Lennart, we met them at South By.
And we had Chris Anderson right there.
They were there, obviously, for South By.
And he was just like – he's a crazy guy anyways.
He was just riffing.
And it's like, bump, bump, Couch DB.
It's just like a little thing.
I'll have to point back to the episode so y'all can listen to it, but it's pretty funny.
Oh, man.
It must be a thing with coders.
We like to rap.
That's right.
It's the way we communicate.
So Code Gangsta.
Who would have known?
Who would have thunk?
Who would have thunk?
So, Jeremy, I think the first time I saw your name and I saw the code Gangsta Handle was on your blog, and you wrote a post that ended up kind of making the rounds, at least in the tech community, around your switch from Ruby to Go.
Specifically, I think it was around command line applications.
Yeah. Oh, yeah, yeah.
So this is kind of how, like, Hacker News operates.
If you write a post that is even remotely,
could even possibly be somewhat controversial,
it will be on the front page and stay on the front page.
And that's precisely what happened, basically.
I wrote a post titled,
On Distributing Command Line Applications, Why I Switched from
Ruby to Go. You know, that sounds very, it still sounds very nice. It still sounds very civil.
But instead, Hacker News chopped off that front part and just titled it,
Why I Switched from Ruby to Go. Oh my gosh, flame bait. And yeah, definitely got a discussion going.
There was no intention to be controversial
whatsoever um i i simply came from a place where i was writing a lot of command line apps in ruby
um specifically like production facing command line apps that we were distributing to users who
were not who are not rubyists um so to uh one we didn't want to distribute it as a Ruby gem because why be like, just use Ruby gems
to a guy who's not writing Ruby.
And so we had to do all these crazy things
like vendor our gems and, you know,
distribute our own version of Ruby,
package it up in an installer,
and, like, cross your fingers and hope it all works
on, you know, somebody's distribution.
And that was just a very, very painful process
to work out just to get Ruby running on somebody's machine. So I looked into some other alternatives
and it seemed like Go is very, you know, very Unix focused. So it means it's probably pretty
good for the command line. And I just loved how simple it was to construct really good command line applications that ran fast,
that were compiled into a single binary
and could be cross-compiled to multiple OSs.
So that's mainly why I wrote that blog post
and wrote a library called CLI.
And it seems to be, people seem to be following
in that same sentiment that it's like,
if you're not writing a tool for Rubyists to use while they're developing ruby you probably don't want to write a command
line tool in ruby it's just it's too painful which i think i mean just we're hearkening back
to katrina again she had a similar experience with her exorcism command line client where
she wanted exorcism to be not just Ruby focused but there's Python
exercises, there's
Haskell I think now, CoffeeScript
there's all sorts of languages and so
she wanted to remove that dependency for people
to use her tool
from the command line, the Ruby dependency
so she ended up rewriting her
command line piece in Go
So let me ask you this then, if you're moving from
distributing it as a Ruby gem and not this then if you're moving from distributing as a ruby
gem and not requiring ruby you're distributing as go but is it still required then is go required
uh no go allows you to cross compile um basically to a standalone binary which is really great um
because it'll it'll basically work on any OS that has libc pretty much.
So drop it into your bin folder.
Hopefully you got that in your path and you're good to go.
Yep, exactly.
And the great part I mentioned, cross-compiling.
In general, it is dependent on what you do,
but in general you can cross-compile most applications,
meaning like on my Mac box I can compile for Windows and different flavors of Linux and my Mac as well,
and even stuff like ARM.
That way I can just, here's a distribution, here's a release,
and I just build it all on one computer, which is really great.
Nice.
The fruit of that came your project CLI.go.
Are you still maintaining that?
Is it ongoing or is it kind of a finished
thing? And maybe explain exactly what it provides. Yeah, so I am maintaining it. There are going to
be small little additions to it. The way the API is structured, it's not meant to be changed a lot.
And it kind of falls in line with the philosophy behind Go packages currently, which is keep master always backwards compatible.
And there's been edge cases, obviously, to try to fix and some edge case problems.
But in general, most people seem to be pretty happy with it.
And it seems to be a very good starting point for creating command line apps and generating help docs and everything like that.
But I'll be honest. It's not the most extensible framework in the world.
It was really just meant to be like, I don't want to think about, you know,
help docs and parsing subcommands and parsing flags.
I just want to start writing the actual meat of the code.
And so that's what it does, and it tends to do it pretty well.
And so I think that's where the popularity of the library came from.
Right on.
So you just kind of triggered a tangential question that I've been waiting to ask somebody who's in the Go community.
What's the package management story in Go?
How does that fit into, like, if you're building a command line application or even with Martini?
Is there – I know there's GoGet the is that the whole story yeah so uh right now the package solution or the the the package management solution for
for go is it just a very simple one it's a very primitive one you use go get you can import uh
libraries with go get the the great part about how imports in GoGet works is that a path is a path
is a path, meaning my library when I import in my code is github.com slash code gangsta slash CLI.
That way, it'll first check locally on your computer if you have it. And if you don't,
it will go and pull it down. So it's cool to have that kind of uniform identifier with your code.
So that's why you've got to keep master good?
Yes, that's why you've got to keep master good is there's no – as of right now, there's no built-in idea of versioning. because a lot of the Go maintainers want you to build packages that are useful
and that are small, that do a certain set of things very well,
that aren't going to be completely innovated and iterated upon
during this development cycle.
There are some initiatives for bringing in things like versioning
because we realize
that's like theoretically a really cool idea, but in practice it's, it can be harmful depending
on, you know, how many dependencies you're pulling in and how you're managing those.
And I know there are external tools for doing them that I use for certain projects.
And there's some other solutions that I've been uh working on as well uh specifically with regards
to martini and cli um to be able to iterate on those packages for people to be able to pull in
versions uh that are different so you mentioned jared you mentioned go get and are you going to
the fact of like go unget because i don't know how to not get long story short i don't need it i mean like if i if i
if i go get something i want to like let's say uninstall remove it how do you uninstall things
um you remove the folder where it's at see that's what i thought and that's what i was doing i was
like am i an idiot or something so at least i'm not an idiot hey man you're doing it right
is that the i mean is that really the way that is it just because
go is somewhat new and the things are still kind of evolving how things should work and
yep i think i think we're since go is still a fairly new language fairly new technology
and it's very grounded in unix philosophy so a pure unix guy would be like yeah there's no
problem deleting a folder that's what you. That's what folders are for.
That's what directories are for.
And that's what the file system is for.
But I could understand it being a roadblock for people who are used to having tools take care of a lot of things for them.
I think even the folder it comes in has a bunch of other stuff in it.
So I'm like, should I delete that stuff? I guess as someone coming in with lack of experience in it,
I'm like, you kind of have an immediate bit of fear.
Should I do that?
What's the cause of it?
What would happen if I do do that?
And then next thing you know, you've got your Go directory
that's got bin, package, and source in there,
and you've got, do I just delete it all?
Delete some of it?
That's where I was like i'm not sure adam i think the answer for you is you keep jeremy available on skype okay and then you just throw these
questions at him as you go that's right you'll just right i'm here all night
so you so so you do this command line app and you enjoy distributing command line applications with Go.
Are you doing this for your work as well or is it all for play?
For command line stuff, it's all for play in general.
We do use some of the tools.
One of them I'm working on is called Envy.
It's an environment bootstrapper. And if you're used to working with web frameworks like, you know, Express and Node.js or Rails and Ruby, there's a concept of a.env file, which is basically saying we want to store our configuration in our environment.
We don't want to, like, run a shell script every time to, like, bootstrap our environment and we obviously don't want to like have anything checked into the repo for that stuff because we're dealing with passwords and you know tokens for authentication
for certain services so you have a dot env file that declares all that stuff and it's local to
your machine so you can set it up and manipulate it however you want so this this env bootstrapper
called envy allows you to do this in a generic way.
Most.env implementations are tied to the language you use them in, like Node.js or JavaScript for Node.js or Ruby for Rails.
This one's very generic.
All you do is you call Envy, and then you pass whatever command you want after it, and it will bootstrap the environment and then run the command.
That way you have all your environment variables
present to you,
and they're all declared inside of a file.
So it's really, really cool for running servers.
It's great for development,
for web development,
for command line development,
for any of those things.
Nice.
So you do that one for work.
Where did Martini come from?
Was this just a natural extension of building command line applications?
And now you said, okay, now I want to build my web applications and go.
Yep.
So Martini came out of I do web work for my day job.
And I wanted to – I was building some Angular front ends,
and we were looking at a new project,
and we were looking at doing more distributed architecture. We're usually a Rails shop. And in these new projects,
we're writing Node.js, we want to write Go, we want to write some more, you know, Ruby and Rails,
and we just basically want to find the best tool for the job for each particular section of our
application. So that made me excited because I was playing with Go for command
line stuff already. And so I started playing with Go for the web and I played with a bunch of other
frameworks and I built a couple of projects in different frameworks just to get a feel for them.
And I was having a hard time finding just a sense of reusability among those web frameworks. I know like Ruby has Rack and they unify on Rack in general,
all the web frameworks in Ruby.
And Node.js, they have quite a few frameworks that unify on Connect.
And so I wanted to create some sort of middleware stack
that, one, gophers would like,
that wouldn't be too far flung from the original Go net HTTP library,
and two, stuff that people would actually build value on a big, um, big proponent on, on building value.
When you're writing code, you should be writing something that's valuable.
Um, and so I started martini as kind of a container for that.
Uh, martini itself doesn't do like extremely useful things.
It's, it's mainly just architecture and a lot of
sugar to be able to create a lot of valuable components that are reusable across multiple
types of web applications cool just pausing a second on the name and i i believe i i i read
you say this on the mailing list but i don don't recall. The name Martini and the tagline is Classy Web Development in Go.
It just calls to mind that kind of epic spilled martini error page of Sinatra.
Is Sinatra like the primary inspiration for Martini?
Yeah, Sinatra is definitely one of them.
Express from Node.js is another.
Those are both fantastic frameworks.
They focus on simplicity and modularity
and elegance and martini sounded really cool. I mean, it's a, a martini is obviously a mixed
drink. Um, you know, in this time there's like so many, you can call any cocktail martini nowadays.
It's not just gin and vermouth. So like, when I think of a web app, I think,
you know, there's different requirements for, for any kind of web app or service. And, and I can't
just make a set of like middleware or a set of components that everybody's going to use. They're
all going to create their own. And that's when I thought of like, okay, it's like a cocktail. It's
like a martini. Like, sure. I don't like appletinis, but the person next to me really likes
appletinis. And I don't believe in appletinis a real martini, but that doesn't matter. The guy still likes his appletini.
And I feel the same way about the web. Um, you can have whatever opinions you want, but
martini tries to be a good container for, uh, creating kind of your own cocktail, your
web cocktail of sorts.
Cool. So martini provides, um, uh, just the core martini. um just the core martini we'll talk about martini
contrib which i believe is like you know provides way more stuff but the martini proper library
basically it's a middleware stack that has a routing layer in it and some sort of dependency
injection is that is that the gist of, or is there more that I'm missing?
No, that's pretty much the gist of it.
Okay.
So then the Contrib libraries were all the other,
because, I mean, beyond that,
most web apps are going to need session handling,
CSRF protection,
a whole host of things that kind of people become used to.
Yep. Is that what stuff lives in contrib? Yeah. Yeah. So, uh, to, to go back to Martini for a sec, I was building, uh, I was mainly building Martini for, for two different kinds of web apps,
uh, for my application. It was, uh, rest based, you know, services that they're just serving Jason.
So, and they're talking to other services, not even talking to a browser. So there, there is even no use for like cookie based sessions or
anything like that. So that's, that, that might be the answer to why some middlewares are in
Martini Contrib rather than Martini itself. And, um, I kind of just wanted to elaborate more on
the dependency injection. Some people really shy away when I use the word dependency injection because they're like, oh, my gosh, Java, IOC containers.
Oh, no.
Yeah.
This is going to be terrible.
I was thinking just that.
Yeah.
Okay.
So I actually have a love for dependency injection when it's used well. And it's actually my, it starts to become, whenever I'm picking up a new language,
I tend to be like,
okay, I'm going to write a dependency injection system
to see how I can make modular code with this language.
So if you look at my GitHub,
I have one in C Sharp, one in ActionScript,
one in JavaScript.
I've written, not on GitHub,
but I've written one for Objective-C
and obviously Go and Ruby.
So I've kind of played a lot with how to manage dependencies within applications,
and I try to find the best fit for one.
In this case, and a lot of people absolutely love it
because it really extends the modularity of Martini,
the way the dependency injection works is you map something by a type in Go.
Go is strongly typed. It's statically typed.
So you can, you have types everywhere, right? And you map something that's a type. Let's say it's
like a database. You have this database connection and you map it to Martini, either on a global or
a request level. And every one of your Martini handlers, which is really just a function,
they can ask for that dependency in their argument list. So it's very close to if you're used to using Angular
for front end stuff, their dependency injection works kind of the same way on functions where
you just ask for it and it gives it to you. It's so brain dead. It's very intuitive. It's super
easy to test because now you have functions
that don't actually reach outside of itself. It all just goes in through its argument list.
So that's kind of how the dependency injection works and why I try to encourage people to not
shy away from that word as much. And it's hard to try to say like it's something else because
it really still is dependency injection, just not in the way that most people would think.
Let's pause the show for just a minute and give a shout out to our sponsor, TopTile.
For those of you out there who are freelancing or maybe you'd like to freelance or even kind of try out a freelance-like project where you're maintaining your full-time position, you have to check out TopTile.
TopTile is a new, rapidly growing network of some of the most elite engineers in the world.
They're distributed all across the globe.
Their primary focus is connecting their ecosystem of top engineers and top companies.
You work on special projects with companies like Airbnb, IDEO, Zendesk, and many others.
You can work remotely remotely on a beach
or anywhere in the world
to get started
head to toptal.com slash developer
and click join
toptal
that's a nice big old green button you cannot miss it
that's toptal.com
slash developer
I think
Angular is kind of
warming up more people to the idea and the benefits that dependency
injection provides.
So I think Martini fits in nicely there.
You know, there's a whole host of options in the Go community for web development.
In fact, we had even a roundup post late last year, a guest post that laid out a whole
bunch of options. Where does Martini fit into that ecosystem? Were you aware of a lot of the
options when you started building it? And what do you think its advantages are?
Martini has a couple advantages, and it also has some disadvantages. From a pure benchmarking
standpoint, Martini is not the fastest framework. And it's not supposed to be. That wasn't my goal in writing it.
There's part of me that believes that Go is fast enough for most applications. And if somebody is
just looking at hello world benchmarks, they're not doing their job as far as
analyzing a framework. But that's another topic for another day.
What Martini brings in is because of how the dependency injection works and how dynamic it is in that nature, it is backwards compatible with all Go net HTTP handlers,
which is a really, really cool feature because things like Gorilla HTTP and other handlers that
people have published kind of that work around the GoNet HTTP interface, they can just throw
those in Martini and they just work.
And that's kind of, that wasn't necessarily an intended thing.
That was like, I was writing Martini one day and it popped up in my mind.
It's like, this needs to be like a bullet point on the martini feature list because it's actually really cool yeah and so that's one of the features
and the other feature is just that kind of tags along with that is reusability um you know the
middleware stack the routing stack the fact that you uh there's this kind of you you ubiquity between
handler functions whether or not it's middleware
or whether or not it's handling a route, like it doesn't matter. It's all the same.
It's just kind of the elegance of that. And it's, it's really just building blocks. People
find out like the core features of Martini and they come up with some really creative ways.
I love looking at the mailing list. Cause somebody is like, I'm writing code like this. And I look
at it. I'm like, wow, that's so cool.
Or somebody goes, this is how I do content negotiation with dependency injection and
how I like observe, you know, what people want to render out as a struct.
And based on, you know, the header, I can then like, you know, throw it out as JSON
or throw it out as XML or throw it out as HTML or whatever.
And so like people solving real world web problems using those core
building blocks that I didn't necessarily build myself, you know, I didn't build content
negotiation into martini. Somebody figured that out through the building blocks that were laid
out. So I find, I find that awesome. It's just super awesome to see. That's kind of neat how
you can lay down a set of breadcrumbs and, you know, kind of walk away because your needs are
different, but others pick it up and take it there. Yeah, absolutely. Yeah. So I'm looking
at the list of available components in the martini dash contrib repository. You got auth, binding,
gzip, render, accept, blank, sessions. It goes on and on and on. I'm assuming you didn't write
all these and these have been community contributed. Is that fair? Yep. A lot of them have been community contributed. I've contributed to,
um, I wrote render and sessions and auth and, uh, contributed to a couple others,
but for the most part, all the rest are, um, you know, fully community community contributed.
Nice. So did you expect this, this amount of contributions or were you kind of surprised at the mart say, I know that's like, sounds like such a petty thing to worry about, but, um, some communities could be really hardcore about
use of reflection. And I have gotten a little bit of friction, but in general, people,
people have come to be pretty understanding and be like, yeah, martini is not the fastest thing
on the blog. And me saying that is like, we're talking about nanoseconds here. It's nanoseconds
slower than, you know, the next framework or whatever.
But man, you can write some awesome code with it
and very clean code.
One example...
I was just going to ask you for an example. Go ahead.
Oh, cool.
So one example, and this could be linked in the show notes,
is I wrote a blog post for the Go Advent Calendar,
which is a really awesome event put on by Brian Kettleson over at Gopher Academy and Eric St. Martin.
And they organized this 25 days of Christmas kind of thing, and each and every single day was accompanied by a blog post by a community member in the Go community. Unity. And I wrote for day 11, I think, about how to build a simple Christmas list app in Martini
using some Martini contrib packages like render, which is for HTML templating and rendering.
And what else did I use? I also created, I showed people how to create a MongoDB session
and use that. And I also used bind to bind form,
post form parameters to a struct in Go
and to use those to declaratively do that.
And all in all, it was this full,
kind of crud-like wishlist application
in like 150 lines of Go.
It was surprisingly concise and extremely readable.
And it's a,
it's a really cool example to point people to because they're like, Whoa, like you're,
you're mapping a database and it, and it works concurrently and it does all this cool stuff.
And it's, it's really readable. Very cool. So as I mentioned in the pre-show, I had opportunity, um, kind of right when Martini first came out to use it at a local hackathon.
We have an event here.
I'm from Omaha, Nebraska.
We have an event called Hack Omaha, and our team got to kind of expose some civic data via JSON API,
and we chose Martini and had a lot of fun using it.
One of the pain points, perhaps the only pain point I can remember at the time was there was no live reload, which you just kind of come to – you get spoiled and you're like, man, I want to make my change and not have to restart my little app server.
Is that still the case with Martini or are there options to get live reload or was it already out there and I just didn't find it?
Yeah, so there are options out there. Um, there are two, one of which is written by, uh, by me. Um, and the other one is
written by, I'm going to totally butcher his name, Andreas France. And he is, um, he's an Italian,
uh, Golan community member. And he has a, he actually has a web framework called traffic.
That's actually quite good. Um, he wrote a project called Fresh that is still generic to a lot of web applications.
And that's a command line app that simply does live reload.
And that's very good.
I've looked at the source.
He's a very good programmer, and I really like his stuff.
The other application is called Gin, which you can go find it at github.com slash code gangsta slash gin.
And it's not fully documented. I still have to put together a readme and we're still kind of in
the growing pains phases of it because it's still fairly new. But I use it every day for martini
and it does a couple of really cool things. It sets up a proxy server to actually serve the
requests. So we can do cool things like if there are compile errors, we can show them to you in the browser. And we can also compile instead of rerunning the
app every time after a compile, we actually only rerun the app after you've compiled, recompiled,
and when a request comes in. So it's very much like how the Play framework does their live reload. And it also adheres to
the silence is golden principle when it comes to compiles. So you can keep saving your files
anytime you want, and it won't actually output anything until you have a compile error. And
then it will let you know that the compile has been successful. So it's a really cool tool. It
doesn't bother you too much. It's so transparent. You don't even need to pass any configuration it works with martini out of the box you just hit gin and it just works
nice yeah looking at that repo now and uh the readme says gin the web development server for go
and that's all that is it so yeah definitely fresh would be nice to get uh when we can get
a little bit more up there so
i can at least try this somehow pretty cool yep you're putting the fire under my butt now
by the time this gets posted you'll see a readme it'll be like all fleshed out i'll be like ah
nice yeah that's a light readme yeah shame shame so how How have you handled or dealt with or
enjoyed the community
contributions?
You seem like you have a very active mailing list.
You have very active repositories.
Has it been an adjustment period?
Has it been pretty easy?
What are your philosophies around community?
It was really,
really busy at first.
As far as GitHub Stargazers go it really shot up in popularity and there's a time where i was receiving a lot of issue requests
a lot of pull requests and um the last thing i wanted to do was just like be lazy about and be
like i'll just merge this i'll just merge this. I'll just merge this. Uh, cause part of Martini
is about writing clean code. And, um, I really pride myself on that. There's many, I got a lot
of feedback from people and there was just, uh, an immediate surprise that like, you know, Martini,
it's probably not the case anymore, but when, within the first couple of weeks of release,
it was under a thousand lines of code and it did so much and it had the possibility to do so much, um, through, through extending it. And so I wanted to keep the code
clean. I wanted to keep the code concise and I was receiving a lot of pull requests. So, um,
it was good. I mean, you don't want to turn people down when they're, when they're writing
code and they're passionate about a project and they want to give the code to the
project. So my philosophy behind pull requests is you don't have to accept every pull request.
It's okay. People will understand, but you've got to communicate it. I mean, you have to,
you have to, rather than just saying, no, I'm not going to merge this in in it's better to take that passion that they put together
into that code because everybody kind of puts their heart
into code I believe you
really you know you have to do something
if you're contributing to open source you're definitely
you're definitely passionate about it in a way
I want to
steer that passion into something that
in some place where it would be more useful
so if martini is not the best fit
for this piece of code or this, um, API that somebody wrote, I want to be like, you know what,
this would be awesome as a third party library. And you know what, I'd be happy to link it in
the Martini read me if it's great. Um, and so that's kind of been my philosophy with,
with Martini specifically, because it needs to be such a clean, lean code base. Martini Contrib, I'm a little
looser on accepting code, especially from just philosophical reasons. Like if somebody puts up
a package that I wouldn't necessarily use, but it's very well-structured code and I will definitely
accept it in because it seems useful for other people. And that's just kind of been the case. I'm a little looser. I also give
martini contrib package owners. I do give them ownership of the package by adding them as a
collaborator on the repo. So I'm not the only one directly contributing to martini contrib. Like
once somebody puts together a package, let's say binding, I gave those two guys collaborator
privileges so they can update
that package without having to put up a pull request all the time that's why you should have
that in your readme too where you say if you're if you contribute a package yourself you can so
well so you can so you can fix it you say i will automatically add you as a contributor if you
contribute a package that's a good way to do I mean, it seems like that approach does make sense, too, as a maintainer
because you kind of get to set some of the ground rules and the guidelines,
which, you know, let's be honest.
Jared, I know you have kids, but, you know, when you have kids,
it's kind of like having kids in this case, kind of taking us far on the left,
but follow me here, is that, like, if you're doing something like this,
like this is your baby, right? So you want this to go a certain direction and without that discipline and and
whatnot i'll just go and actually like a bad teenager so you got to kind of keep them in order
and let's kind of put down some um you know some fence poles to say you know don't go beyond these
areas and that would work better as a as as a external library or whatever. So you're kind of setting some ground rules for how the ecosystem can play out.
Yeah, absolutely.
Um, and, uh, so far it seems like the community's really been great.
I was telling my wife this this morning when I was just talking about Martini and I'm really
excited to see that, um, that community has reciprocated in a way.
Sometimes I look at GitHub repositories and I look at mailing lists and there's a little bit of hostility.
And I think part of that is contributors can tend to look up to the owner of the repository as an overall attitude for the repo.
So if people are asking questions, it, you know, it, it will,
it's kind of a reflection of the owner. Um, so when I see things on martini, somebody asking
questions, seeing other community members coming in and being extremely nice about how to lay out
questions for people who are new or, or, or guiding them in the right way. I like, I just, I have a lot of hope, um, for,
for the actual project because people are extremely nice, not only in answering other
people's questions, but also, you know, putting together an issue. I love when people, and this
happens so often and where they're like, Oh, I'm having a bug with this. And they describe their
bug. And then the last sentence is by the way, Martini is like, so, so awesome. Thank you so much for putting this together. And that really, as a, as a maintainer,
that just really brightens up my day. And it's cool to see that that's a reflection of
that part of the community as a whole.
In the, uh, I guess, I guess we'll call that pre-show. We were chatting before the actual
show. So that's the pre-show, right?
You were kind of talking about some of the things you're doing at Kajabi,
which is your day job where you kind of get to hack on stuff,
and you're doing some things in Go there,
but you've also done some other things in Node,
and you kind of have this Go versus Node kind of Wild West mentality.
Can you talk about that a bit?
Yeah, and honestly, I'm a pragmatist.
I use a bunch of different tools, so I'm not necessarily tied to either one. I just look at the problem and I find what the best tool for the job is. And the sentiment around the office here at Kajabi is that Node is good enough for the most part. Uh, meaning, yeah, you can write web apps in it and you can grow web apps
in it and that's perfectly fine. It's not, it's not like it's a horrible technology. Um, I would
just say it's probably not my preference. If I were to write a personal project, I probably wouldn't
go to node first, um, unless there was something I absolutely needed from that community and from that ecosystem. But yeah,
like you mentioned, it kind of feels like the Wild West out there, things kind of breaking
silently. And it seems to be an accepted part of the community, and that's fine. I mean,
people focus on certain aspects of a language and disregard others.
I know there's blind spots in every single language community.
It just bums me out sometimes when I'm using some sort of package or library in JavaScript and it's just,
oh, I failed and I'm not going to tell you why.
Something just went wrong.
And that seems to be an accepted debugging practice is to find out what goes wrong.
It's just not my style.
Technologies like Go will pretty much tell you straight out what's going on.
There's not a ton of unknown, like, what the heck does this mean kind of errors.
Since we're talking about Node and Go a a little bit um this last show episode 116
we had aaron hammer on he's from walmart labs and he obviously just had this great success story with
node and black friday and um you know you know hailing banners balloons everywhere confetti all
that good stuff it's like you know super wild party um because know there's some awesome stuff for them and black friday are there any stories
um i guess similar or somewhat the same that happened in the go ecosystem that you know of
that you can tell i mean there's the obvious google one where they replaced their download server with Go, which was basically NetHTTP's file server.
That source is right there in the Go standard library.
So there's that obvious one, and there's a good blog post on it.
You'll probably be able to find it and stick it in the show notes by Brad Fitzpatrick covering it.
And there's a couple others that I know of.
I might have to give you links after the show.
But in general, it's a lot of SaaS companies.
I know Iron.io uses a lot of Go. I know Matt Amanetti at Splice.
They've converted a lot of their backend tech to be using Go and very successfully.
And I think if you even watch sites like Hacker News almost daily, you find some sort of Go hate and Go success story kind of paired together.
It's kind of wild.
I mean – and I think that's what some of the listeners listen to this podcast for is kind of like get a heartbeat on which technology is kind of maybe leading the way or going to lead the way and and maybe that's part
of our role here which is to have guests on that can kind of help at least somewhat field those
kinds of questions but it seems like node and go or they're both i mean go as a language and
node is um you know i guess not really a language it's is JavaScript. It's sort of a framework on top of VA, but, um, you know, they're going both in a good direction and you've obviously don't really
have ties to one or the other. You're kind of like whichever tool best fits it. But a lot of
people in the node community seems to be, seem to be like, um, very, very pro JavaScript, you know,
like forget everything else, write it in JavaScript, everything is JavaScript.
And there's a merit to that,
mainly from, I would say from a training perspective,
some might disagree with me,
but I'll tell you this,
the junior developer at my,
here at Kajabi,
we can teach him how to write a Node app
and he'll feel productive in it,
even though he's been only writing Ruby and maybe some front-end JavaScript, and he'll feel productive in it. Even though he's been only
writing, you know, Ruby and maybe some front end JavaScript, but he'll feel comfortable in that.
And I'd say Go in the same respect is very similar to that. Go is not a difficult language to pick
up. Actually, one of the criticisms of Go is that it's too minimal. It's too simple.
But that's not necessarily a bad thing in every case. And I think it really depends on what part of the industry
you're in. My side of the industry, we're a very small shop. We're very consumer facing.
We build real products for real people. And we deal with that's at our forefront every day.
So if the technology is a means to an end for us, we're not doing a ton of bit twiddling.
We're not doing extremely high scalability, crazy, um, computing.
So for us to write our systems in Haskell would be like very counterproductive.
Um, no doubt that like, there's a, there's an extreme use case for Haskell and there's
a very good use case for writing a correct program, but I'm not going to sit down and
teach a junior developer here at Kajabi Haskell.
It's just not going to be productive for our use case.
Let's pause the show for just a second and give a shout out to our sponsor, New Relic.
New Relic is a software analytics company that helps make sense of billions of metrics across millions of applications all in real time. One thing developers are really
focused on this year is seamless application performance across multiple platforms on all
their devices. It sounds simple, but making an application work consistently well on lots of
different devices, all with different operating systems, running different types of software,
that's super complex. And you might be going through this right now.
Well, how complex is it?
Back in the old days, like 2007,
it was basically impossible to know how your application would perform
once you shipped to production.
If you remember those days, we'd all spend a ton of time doing internal bug hunts
and eventually just cross our fingers and hope for the best.
We'd ship our code and we'd sit around monitoring Twitter and whatever other comms traffic we could
do to kind of see how well our apps were or were not performing. And thankfully, those days are
behind us now. New Relic lets us track our application performance down to the end user
level all in real time. This means that we can spot problems spot problems find bugs and fix our code fast way
before our users even notice anything is wrong so go check out new relic by visiting our special url
it's new relic.com slash a changelog learn more about what they're doing how they can help you
use our special offer code the changelog to take advantage of a special 30-day extended free pro trial available exclusively
to our listeners head to newrelic.com slash the changelog so speaking of teaching we would be
remiss not to bring up gopher casts yes which appears to be a fledgling project, but very cool. This is gophercasts.io. And you could imagine it's
screencasts for learning and teaching Go. Can you talk about it?
Yeah, so I started this up with my, with my longtime buddy, Nate Beck. And it's, it's basically,
you know, what it says it is, I when I released Martini, I also had a accompanying demo video
to go along with the source code. And that demo video was way better received than I thought it
would be. And a lot of people watched it and a lot of people got interested in the project because
of it. And still to this day, I look at GitHub recently released statistics for repositories.
So I take a look at those. I'm like, wow, there's so many people that are coming from the video. Like there's still people watching the video, which is, it blows my mind.
And feedback from that video was very positive. People loved the pacing and it was suggested a
lot to me and asked a lot of me if I would start creating screencasts just to teach about Go in
general and about the technologies and the projects that are out there. So that's why we started, that's why we started GopherCasts. And
I have a background in audio, Nate has a background in audio and video. And so we have very,
very particular needs when it comes to producing screencasts like this. So if you go to go for casts.io, you'll see very high
production quality. Um, they're very, uh, very well-paced videos in my opinion. They, um, they're
very digestible. They're all three to five minutes long. Um, and, uh, like, like it was mentioned,
it's, they're very, very, the site is very young, so you'll probably only see a few videos up there, but we plan on releasing at
least weekly episodes. And I guess since we're talking about the site itself, is it written
in Martini? No, the site is not written in Martini. And let me tell you why. At first,
I wanted to write it in Go. And my buddy Nate, he is not a Go programmer. He's picking up Go and he's learning Go and he's asking me all these questions and we're kind of trudging through it together.
We actually ended up writing the service in Rails. them, one of the reasons why was kind of prompted by Joel Hooks, who wrote a blog post on how he
converted Egghead IO, which is an AngularJS screencast put on by John Lindquist and Joel
Hooks now. He mentioned why he wrote his site in Rails and why he didn't use something like Node.js
and Angular or something like that. And, you know, it goes back to a lot of my philosophy with building things
is you use the best tool for the job.
I'm going to be transparent and say like,
GopherCast will not always be all free, everything free.
We do plan on feeling out the community,
seeing what it brings, what people like, what people don't like.
And we want to offer something that will keep us going to keep us producing super high quality
screencasts and to see what people are willing to pay for it, because I think people are willing to
pay for quality content. So building things like a, like a publishing pipeline for video and,
you know, tying in with like subscription services like Stripe and dealing with payments.
We already know how to do that in Rails. And for us to do it in Go is possible, but it's not
the most productive at the time. Martini was built, you know, to make tiny services and smaller
websites and in a more distributed computing fashion. And so that was the reason that we mainly chose to write it in Rails.
And it's been fine.
We've had a couple of people that are like,
oh, it's written in Rails and not Go.
But overall, I mean, it's useful for people.
Well, I think what you said earlier with Martini,
when you first started it out,
like your point wasn't to make a Rails web framework.
It was meant to be like a web services web framework to kind of interact between different services.
So in that case, you're totally on point.
Yeah, absolutely.
It's using the best tool for the job.
We don't have to just like one technology.
I like a lot of technologies.
There's a lot of things that bother me about Rails, but I still use it every day.
And you know what?
It's really productive.
I know Jared and I have been talking about some different stuff we want to do with the change log.
And he always, I'm going to call you on this, Jared.
He's like, I'll do it if you let me write it and go.
And so I don't know if that's the inner desire of Jared who just wants to write it in Go or what or if he thinks that's the best tool for the job.
We'll see.
Yeah, I'm the same way.
I want to just write stuff in Go and Nate had to calm me down and be like, let's pull this back.
And kind of in retrospect for the site, I'm glad we have it in Rails.
Will it maybe be in Go eventually?
Probably.
It'll probably be in Go eventually.
But right now we are able to ship and show people our screencasts and
most importantly we're able to show people content and that's really what it's about yeah
just to defend myself slightly here
sorry about throwing you in the bus there sorry about that the reason why i want to do that is
not some sort of idealism it's because i was saying that let's learn something as we build
this you know it's kind of a side thing and let's let's learn something as we build this you know it's
kind of a side thing and let's let's learn go and these different things as we build it and then
adam's saying this thing's going to be a production you know like this is going to be our next version
we can't we can't put you know newbie code out there so yeah ultimately he's going to win that
that argument but that was some of my thinking behind doing InGo.
I was mostly just looking for new projects to start InGo.
And I was like, oh, sure, let's do it, InGo.
Well, hey, some things are best learned in production, right?
That's true.
I don't always test my code, but when I do.
I test it in production.
That's cool.
What else do we want to talk about, Jared?
I know we talked about Go for Cast.
I'm super excited about that, by the way. I'm really glad that you listened to the community and decided to do that because I do think that Martini video was well done. and keeping them under five minutes is definitely perfect. I mean, sure, seven minutes, eight minutes, that's okay.
But five minutes is like a quick idea, enough to get them running,
whomever is listening, and it's just like in and out.
Like let me take a break from whatever I'm doing
and just maybe listen to something brand new.
Go from maybe design to listening to a Gopher cast
and kind of get some new knowledge.
Ideally what you want to do is you want to trigger that spark in somebody's mind to start creating instead of just copying and pasting the source or figuring out some sort of quick fix.
They're watching the video so they can get inspired, and that's kind of what it comes down to.
Well, let's loop back around.
I got one more question about Martini,
and then maybe Adam can do his closing questions.
But you kind of got started in Go
because you like the deployment
of these distributed command line applications.
How do you deploy a Martini application,
a web app, to production?
It's in a similar fashion, and there's a couple different ways you can deploy it.
I know Heroku, if anybody's used to working with Heroku, it's a very easy deploy process for Martini.
It's the same as any other Go web app.
One really cool thing about Martini is, and this was a point for contention among a couple people,
but Martini uses, to configure the port, you have to configure the port environment variable.
You actually don't do it inside the app.
And the reason for that is for deployment purposes.
In a lot of environments, especially around kind of shared hosting or neighbor hosting,
you have the port set in the environment automatically by the service provider.
So deploying a Martini app using the Go Buildpack and Heroku is brain-dead simple.
You don't do anything different.
You just push up your code with the Go Buildpack via Git, and it just works.
How about non-Heroku style?
So non-Heroku style would be uh simply
compiling your app for the platform that you're in or pushing your code to the the box that um
the box that is going to be hosted on and compiling it there and just making sure that
any sort of asset folders you have um are are existing you know right next to where the binary
is run at or uh there's another project
called go bin data which actually can compile your assets in as go source code so it's all one fat
binary and there's a couple projects that actually do that yeah yeah one of which is and i don't know
if you guys use this tool but i'm gonna totally uh pimp it out because it's an awesome tool. It's ngrok. It's a tunneling service and tool built in Go.
I think we covered that.
We linked to that on the changelog a while back.
Oh, okay.
I've seen it, but I haven't used it personally.
Well, it's a fantastic tool, and it has its own web interface that uses Bootstrap
and pulls in all this JavaScript and stuff.
But the rad thing is all that stuff is hosted you know locally but it's all
in one single binary it's still one binary for all the assets um so that's another cool way depending
on what kind of assets you're serving and if you want to just pull them off of you know memory or
pull it all into memory when you run the program like it depends on what you're really doing but
there's kind of something really uh there's there's a lot of excitement around thinking
oh i could just drag and drop this one file onto a computer and it's deployed yeah for sure and then
would you suggest behind behind a proxy like nginx or a proxy or would you just throw it on port 80
and let the thing roll you could you could certainly throw it on port 80 and let it roll
and there's some services that i've deployed that have that. But NGINX is such a huge boon to really any sort of web app
that for things like caching and even static file serving,
I would recommend probably in production using NGINX
over Martini's static handler just because of efficiency,
the knowledge that's out there, the documentation that's out there, and speed.
So future Martini, big plans, little plans, what are you thinking?
Probably little plans. Again, I want to keep Martini consistent and small. There's not a
whole lot left to add to it, but there's certainly a lot of value that can be built up over in packages and handlers and middlewares, especially in the Martini contrib repository.
There will be a point where Martini contrib will hit critical mass, but I'm hoping by that time Martini will be popular enough to where it's valuable for somebody to publish a separate package on GitHub that people will then recognize, oh, it's for Martini, and they can actually pull it in and use it.
It hasn't reached that point yet because the Go community is still fairly small,
and so Martini Contrib kind of acts as that curation,
one place where everybody can go to see what are the latest cool packages to use.
But in general, I'm excited to see what 2014 brings in terms of Go and their versioning story, because that has come up a couple times with Martini.
I have some solutions of my own that I'm kind of working on in secret.
Ooh. I'm hoping I can bring Martini to a version 1.0 where obviously the API won't have any breaking changes.
And I try my best not to break most changes, but there is one change in particular which will break one little thing that nobody really uses.
And once I bring it to 1.00 it's not going to break from there
so I'll probably apply the semantic versioning principle
to that and be able to
develop the code from there
Cool
Chair, with your question I guess on the future of Martini
do you think you meant from a contrasting difference
between say a framework like Rails?
Is that what you meant by that?
Because I was kind of curious if, you know,
more genius expectations to be something like Rails ever in the future
to be that kind of web development framework.
I was mostly just trying to get just a general idea
of where he was going to take it next.
But I think probably, and Jeremy, correct me if I'm wrong,
I think the answer to that is probably not going to, is no.
Yes.
I'm sorry, I mean, yes, no is the answer.
I think I said that sentence oddly, but.
Yeah, that's okay.
Yeah, I mean, I think there's, I mean, there's Revel,
which is, you know, kind of in the spirit of a framework like Rails where its goal is to be very productive and it does a lot of things for you.
And that's not the space that Martini is trying to occupy at all, which is good because the way I structured Martini, I was kind of being lazy about it.
I was like, I don't want to like spend a million hours, like maintaining this. I don't want to have like a
million like to do's, um, on this project. And so, and that's been, that's been somewhat
successful. I haven't had to contribute a whole lot of code to Martini, you know,
relatively a whole lot of code. So what's the, what's the end users say then whenever they think,
okay, Revel or Martini, how do they make their choice?
What are some of the things they should ask themselves?
Really, what kind of app are you building and what you want your maintenance to look like?
Because building something off of a minimal framework and then a full featuredfeatured framework, they both have different maintenance stories.
I'm not saying one is worse than the other in particular.
I'm just saying there's different ways to maintain it.
Something like Rails, I feel like we build layer on top of layer on top of layer on top of layer.
With a minimal code base, maintenance looks a little different. It's a little easier to rip stuff out and to rethink the problem if, if requirements change. And, you know, you, you kind of mentioned it
earlier and you hit the nail on the head earlier. Martini was built out to solve some of the
problems in distributed web applications where you have multiple services that, you know, do one
thing really, really well.
And you have those intercommunicate between each other. And the industry is trending,
trending to that as a whole. And so that's, that's the space and the little niche that I
think Martini will really fill is building these small applications that, you know,
the code can be really small and concise and reusable across, you know, different applications.
Gotcha.
Cool. Jared, anything else for, uh, for your, your, uh, your questions?
No.
Yeah. You know, if, if Andrew here, which he's, uh,
which he's not at this at this moment, uh, I don't think so. Andrew,
you here? No, he's not here. Um. I don't think so. Andrew, you here?
No, he's not here.
He would say, we have three questions we typically ask at the end of the show.
This is one of my favorite questions we get to ask,
which is, who is your programming hero?
It could have been somebody that was just influential in your life.
It could have been a mentor.
It could have been a teacher.
It could have been your dad, whomever.
But who is the programming hero for you oh man that's gonna be a hard one um oh i would have to say um at the moment and this is gonna sound super cheesy because i'm
on a podcast talking about go but uh a lot of those Unix guys,
like Rob Pike and Rob Kernighan,
they're pretty awesome.
I'm a self-admitted Unix lover.
I love just the way,
the philosophies around it and how it's structured.
And there's obviously flaws around it.
But in general, it's very in line with how I like to build applications.
So a lot of minimalism, a lot of build apps that do one thing really well, I fall in line with that philosophy.
So those old school guys that have done a lot to influence modern computing as a whole. I love it.
So if you were not coding Go, or I guess Go is not a language.
I guess, sorry, Go is a language.
I was thinking of martini, my bad.
If you weren't coding in Go, what would you be coding in? I guess you kind of do that by day.
You don't always just code in Go.
So what else do you hack in?
So, I mean, Ruby, kind of whatever language is possible.
I do some C and C++, some Ruby, some every once in a while I'll dive in and do some Objective-C with iPhone apps, JavaScript, more Go stuff, touch some C Sharp on multiple projects.
So I'm kind of willing to dive
in and, uh, I kind of have a pretty open mind. I think of a community is somewhat successful that
there's gotta be some, uh, there's gotta be some hope in and some, some little golden nuggets in,
in how they operate. Um, so I think every, every community has at least something to say as far as how software should
be developed. And so I'm adventurous in that way where I like to find out what those answers are.
Let's try a different angle at that. What's on your radar? What's some fun open source
projects that we haven't quite talked about on the show? Maybe something you haven't even
written yourself, but what's out there that's interesting that we haven't quite talked about on the show? Maybe something you haven't even written yourself,
but what's out there that's interesting that you want to hack on
whenever you have a free weekend or something you have four days,
you've got nothing to do, what would you hack on?
Probably I would take a deep look into what the ecosystem looks like
for functional languages right now and start to find some real use cases for me.
Obviously, as a programmer, we're hearing that we're running into this paradigm shift where
we need to do more parallel computing and having side effects is just a hindrance to that.
And so functional languages are going to become more popular. But I don't think it's hit that mass yet to where imperative
programmers or people like me who have, you know, grown up as a developer that's, you know,
programming imperative the whole time. We haven't found the like practical use cases for
for functional languages, everything I I try to see with like a Haskell
implementation just seems so academic. And I was like, okay, well, so like, how can I write
something for Kajabi like this? So I, I'll probably, I probably have that on my radar.
If I, yeah, if I were to go to a cabin for four days, I'd probably look at Haskell and be like,
I need to, I need to find a way to make this useful for me.
What do you think you would write maybe?
Because, I mean, you would have no internet, right?
I would have no internet, so I'd probably have to write some command line apps and do some craziness.
But I don't know if I'd exactly be able to tell you what I'd write. Cool.
Well, why don't you take that trip someday and get back to us?
That's right. I might suggest if you're in a cabin without any internet and you're on vacation, maybe have a beer, sit out, enjoy the outside.
Come on, guys.
We can put the computer down for a few days.
Oh, yeah, totally.
And then we get back.
Get a glass of whiskey and a cigar.
I mean, that sounds way better than programming Haskell.
You're not going to learn some Haskell without the internet.
Come on.
Yeah, that's what I was going to say.
That's cool, man.
Jeremy, it's been fun having you on the show.
I know that you kind of get to bounce around quite a bit in your working with the web and programming.
And obviously, you've done some pretty cool stuff to share on github and we appreciate you know your perspective with martini and how you want to keep it clean and how you're kind of
guiding that ecosystem and just coming on the show and and sharing that and maybe even giving a little
twist of the arm via twitter to to get onto the show but you were definitely on our list sir that's
for sure oh awesome well i'm so glad to be on the podcast again. Newer fan, but a big fan. It's awesome talking to you guys. I love talking shop.
It's been good having you back on the show too, Jared. I know I haven't had you back on with me since Katrina's show, really, right? So it's been a bit.
Yeah, it's been a while. Good to be back.
I want to get you back on the show more often, man.
Right on. We'll have to make that our mission.
I also want to give another shout-out to our sponsors,
DigitalOcean, whom we love, New Relic, whom we love,
and TopTile, whom we love,
which those are our sponsors for this show.
But our friends at DigitalOcean want to pay you,
so if you write open source like we've talked about today, if you've got a project out there,
they want to pay you to write a tutorial about your project for the DigitalOcean community.
Best of all, they'll give you $50 and then promote it for you on their Twitter account.
So if you've written martini, maybe you can write a tutorial and they'll promote it to their 21,000 followers.
For those of you listening, I'll put this in the show notes, but the URL for that is digitalocean.com slash write hyphen four hyphen digitalocean.
The word four is the word F-O-R-4, not the number four.
So just so you get that clear.
And you can also get some free stickers from DigitalOcean by filling out the form at stickers.digitalocean.com. want to freelance with companies like Airbnb, ArtSeal, or Audio, head to
toptile.com slash developer and click join the best
to see if you have what it takes
to join Top Tile's elite
elite, capital E, elite
network of engineers. Again, that URL
is toptile.com slash developer.
And that's it for this week. Jeremy, thanks again
for coming on the show. It was definitely
great having you on the show.
The listeners, we thank you for listening
and for your support.
And if you haven't yet, we do have an email
we ship out every Saturday.
It's called The Change Log Weekly.
And we share everything, everything
that hits our source radar.
I know Martini made an appearance at one point.
And I think even the blog post
that Jared was alluding to earlier on,
Jeremy, we had that in weekly as well.
But you can subscribe at thechangelog.com slash weekly. We'll be back next week. And until then, let's say goodbye.
See ya.
See ya. We'll see you next time.