Imagining the Ideal Language for Writing Free Software
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Sockwell, Daniel
Many programming languages have been explicitly designed to solve the problems of "programming in the large" – that is, to make it easier for large groups of software developers to work together, despite differences in skill, experience, or history with the project. Languages following this pattern are an excellent fit for the sort of large software companies that typically sponsor their development. However, they are not necessarily a good fit for typical free/open-source software projects, which face different challenges and constraints. If a language were designed from the ground up to fit the free-software usecase, what would it look like? What values would it maximize, what tradeoffs would it be willing to make, and what would it be like to program in every day?
 In this presentation, I'll be discussing a question that is very important to me. What makes a programming language good? Not just in general terms, but specifically good for writing free software. Before diving into that, though, I'd like to take the opportunity to introduce myself to those of you who don't know me. My name is Daniel, but some of you may know me as Code Sections if you've seen me around the RACU community. I'm a full-time pre-software developer, and my primary programming language is RACU, although I also program in Rust or other languages as the need arises. I also serve on the RACU Steering Council. Before switching to software, I was a practicing attorney with a law firm in New York City, and though I no longer practice, the mindsets are a bit more similar than you might think. Oh, and one other note, the icon that I use, I have noticed that it is pretty similar to Camilla, the logo for the RACU programming language, but I wanted to mention that that is just a coincidence, though a happy one that makes me smile every time I notice it. With that out of the way, let's dive in. What makes a programming language especially good for writing pre-software? In the course of answering that question, there are three different points that I hope to convince you of. First, that pre-software projects are different, and when I say different, I really mean that in two different ways. First, pre-software projects are different from other types of software projects. And second, and perhaps more surprisingly, pre-software projects are different from the image that many people have of them. Second, I'd like to convince you that there are some excellent languages out there that just really aren't very good for writing pre-software. They're good at other things, but they're not good at that. And third, and relatedly, I'd like to convince you that the ideal pre-software language should be different from other languages, even other excellent languages, because it's aiming at different sorts of projects that should have different design goals. So let's start by saying how pre-software projects are different. I'd like to start with an even more basic question. What is pre-software? What are typical pre-software projects? A lot of times people talk about pre-software by mentioning Linux or Firefox or other high-profile open-source projects. And some people have said that pre-software is like building a cathedral where you have a group of architects and then many laborers who execute their plan. And other people have said, no, it's like a bazaar where many people work together along similar lines, but there's little or no central organization. But somehow out of that chaos, order emerges. Those are both kind of dated. More recently, I've seen a blog post that said pre-software is really like nuclear power where you have a huge team that pours a lot of time and energy into an initial reaction, hoping that it will become self-sustaining and produce even more energy in the end. And I just don't really buy any of those. They all have some good points to them, but all of those analogies miss one really important thing. They miss the fact that Linux is a penguin. What I mean by that is you shouldn't think about Linux or Firefox when thinking about pre-software projects. Yes, a penguin is a bird, but if you think about penguins when thinking about birds, you're going to end up very confused about birds and have all sorts of the wrong ideas. A penguin and Linux are both exceptional examples that are not good to generalize from. And specifically, Linux and Firefox and these other high-profile projects are exceptional in terms of their size. Most pre-software projects are extremely small. This is a study from Redmonk and before thinking it doesn't prove my point as well as it does, notice that the axis is logarithmic. So here, diving into their numbers a little bit more, they found that half of the active pre-software projects had only one contributor a year, 70% had one or two contributors, and 87% had five or fewer contributors. Another group of academics took a look at the same issue. They came at it from a slightly different angle and looked at truck factor, how many sort of core contributors would it take for a project to really be in trouble if they were to go away. But cutting the other way, they took a very narrow definition of what it meant to be popular. They started just with the 100 most-starred repos in six language and then removed any that were in the bottom 25% in terms of other measures of popularity, which cut out the majority of them actually. So this is just the very most popular projects. But even in that sort of rarefied company, they found that 34% had a truck factor of just one, one primary developer. And another 30% had a truck factor of two. It's nice to have academic studies that give a big picture view, but it's also helpful, I think, to dive into a more concrete example. So in that spirit, I'd like to talk about Impress.js, which is a somewhat randomly chosen project, but it's the software I use to write the slides that you're watching right now. And I really enjoyed using it. I thought it was a great project. It's very popular, you know, Hins of Thousands of Stars on GitHub. And when I open its contributor page on GitHub, I see that it has 77 contributors. Those aren't all in the same year, but I looked at it a little more closely and it had 16 contributors in its first year. So that would put it outside of the 87% of the projects that Bedmunk said had fewer than five contributors. So it, you know, on first look, seems like an exception to the rule that free software projects tend to be small. But let's look a little closer. When I dove in, its top contributor had 148 commits. The next contributor had 51 commits, then 14, then six, then just four. So this is not really a story of a project that has, you know, is a bizarre with 70 different people all working together. It's really a story of a project that has a couple of main contributors and then other people who submitted, you know, one-off patches or had particular features that they were interested in implementing. And I want to be clear that I'm not knocking that type of contribution. In fact, I did it myself, but, you know, I found a couple of features that I wanted to add to Impress while I was writing this presentation and submitted some PRs. And I hope that that was helpful to the project. And I think that that sort of contribution absolutely can be. But I also think that if we're thinking about things in terms of a bizarre model, we're probably going to have the wrong idea. This is not a large group collaboration. This is a story of a couple people working as main authors and other people helping out, but in a different way. And I said a couple people, but let's take a look at those couple of main authors. And they're actually, well, we can notice the timing is kind of interesting. The first author had nearly all of their contributions in 2012. After that, the next main author started contributing in 2018. So this really isn't even a story of two people working together. This is a story of a project that had a primary maintainer and then several years later a different primary maintainer. So it has really been not a solo project, 77 contributors, but a project that has had a solo lead developer. Again, very different from the bizarre sort of model. So yeah, that actually makes me think free software is not like building a cathedral or running a bizarre or running a nuclear power plant. Writing free software is like writing a novel. Let me play out this analogy a little bit. As I just walked through, in both cases, you have one author or maybe a small handful of co-authors. In both cases, there are many other contributors for books that editors, agents, publishers for software, all the contributors, bug fixes, documentation, et cetera. In both cases, those other contributors play a really essential, invaluable role, but they're not playing the same role as the author. And in both cases, the author is very likely to be part of some sort of broader community, literary community, coding community, but the actual writing of the code or of the prose is a solitary activity. So if that's the mental model we have, we think of writing free software as akin to writing a novel, what consequences does that have for us? Well, I want to return to these points. Free software projects are different than other software projects. They're less collaborative, more like writing a novel. That leads me to believe that some excellent languages are not good for writing free software. I want to turn to that next, and then that will sort of bleed into our discussion of what design goals a free software language or a language targeting free software should have. So I want to talk about free programming languages that I personally think are excellently designed and there are ones that have gotten a lot of buzz and attention and developer mind share. And I think that even though all of them are very different, all of them are especially poor fits for writing free software. The first language I wanted to mention is TypeScript, a JavaScript superset that adds types and transpiles to JavaScript and really targets, among other things, front-end development and executing in a browser. Second, Go or Golang, a compiled garbage collected language that targets fast compile times and is very active in sort of back-end server web development. And finally, Rust, a compiled language with no garbage collector that aims to equal C in performance and is very useful for systems programming and has gotten a lot of adoption. So these languages, as I said, are three very different languages. They don't have much at all in common other than the fact that they all have gotten a lot of attention and buzz lately. And for good reason, I think, I think all three are excellently designed languages. But they have one other thing in common, the sort of organization that first created them. So TypeScript is a Microsoft project. Go is from Google. Rust came out of Mozilla and now has gotten a lot of support from Amazon and really sort of who's who of large tech companies. And that's exactly what these have in common. They are all the product of large tech companies. Why does that matter so much? Well, I think it matters because it influences their design goals. And I say that not just because I've used these languages and have a sense of what their design goals are, and you can sort of read between the lines and their documentation, but because all three of these languages have actually been remarkably explicit about what their design goals are. This is true for all three languages and I have some links in the notes for this presentation if you're curious about other languages. But I'd like to particularly focus on a talk and paper that Rob Pike gave describing Go. He said, among much else, and really the whole talk is worth a read, but he said, Go is a programming language designed by Google to help solve Google's problems and Google has big problems. Now, a lot of people have focused on that last bit that Google has big problems, big in the sense of the scale that they operate at, being very large. But I really want to focus in on that middle part. This language was sort of from start to finish designed to solve Google's problems. And I think the same is true of the other two languages I mentioned. TypeScript was designed to solve Microsoft's problems. Rust was designed pretty explicitly to help Mozilla build a better Firefox. And there's nothing wrong with any of those goals. I want to be clear. I think that those are good goals to have and it makes sense that some really good programming languages have those sorts of goals. These large tech companies are exactly the sort of company where it makes sense to invest money in developing a whole new language. And as Rob Pike said, they do have big problems. So it is absolutely, I can understand why some languages come out of that environment. But I think that that environment is very different from the sort of solo developer free software or code as novel environment that is really important for free software language to target. To explain what I mean, I'd like to look at three different features of the big tech environment compared to the free software code as novel environment. And then for each of those features, look at how that feature of the environment impacts the language design goals of a language targeting that sort of environment. So first in big tech, you have really large teams, small teams in free software as we've talked about pretty extensively. Big tech also has high turnover, just like the law firm I worked at. It's not at all uncommon for people to start their career there before quickly moving on to somewhere else and they're sort of constantly hiring from people who have just completed their CS education. Free software on the other hand, a lot of these small projects have one maintainer for decades, but even if it's not quite to that extreme, the turnover is much, much lower. In big tech, people are there because they're getting a paycheck. They may have other motivations as well, but that is a sort of defining feature of the job is that it is a job. Free software developers tend to be much more self motivated. They may or may not be getting paid at all. They are, they're getting paid probably less than they would make at a different way that they could be spending their time. So the motivation is pretty different. So how do those features of the big tech environment impact design goals of a language targeting that environment? Well, when you've got a large team, you really want to have a standard code format. You want your, to use tools like Go format or Rust format or prettier.js to make all the code look exactly the same because you want everybody on the team to be able to read each other's code just like they wrote it themselves. More broadly, you want there to be just one way to do it. That plays out in syntax and style guides, but also in standard library design, also in the, just the amount of syntax, the language design itself. And in language design choices, like limiting customization, like operating or overloading and other ways that people can sort of make the language their own. And all of that is in service of avoiding dialects. So, it is really bad if Bob writes some code and then Alice writes some different code and those two, even though they're programming in the same language, might as well be programming in different language and they can't read each other's code. In that talk about the design of Go that I mentioned earlier, this was explicitly called out as one of the design goals for Go that they wanted to avoid subsets or dialects of the language. Things are similar when we talk about high turnover, those two do tend to go together, but I think high turnover really creates an emphasis on the speed at which people can pick up the language. So, you want it to have a familiar syntax. All of these languages bear more than a passing resemblance to C and that's not at all a coincidence. More broadly, you want the language to be easy to learn, not just in terms of syntax, but in every other aspect of it. If people are only there for a few years, you don't have time for a long learning curve to really pay off. Again, Go was very explicit about this value and it is famously easy to learn and even in just a weekend to pick up the basics. Rust is a bit of an exception here in that it is not as easy to pick up. But I think it is clear if you spend any time in the Rust community that they take the value of being as easy to learn as possible consistent with the nature of the language extremely seriously. If there's anything better from the perspective of a big tech environment than having a language that is easy to teach new hires, it's having a language that you don't need to teach them at all because they already know it. So it is even better for language design if you can make the language popular in whatever way possible. And I think Microsoft and Google and to a lesser extent Mozilla have put a lot of emphasis in evangelical efforts behind their language and making it easy to gain that sort of popularity. The final feature of a big tech environment that I'd like to focus on is that people are getting paid. I want to be both tactful and precise in talking about this because it is, of course, the case that there are many absolutely amazing programmers who are working at these large tech organizations and working primarily for the paycheck is no reason at all that someone can't be a way better programmer than I'll ever be. But the thing about money is that everybody likes money. So even if many of the people at an organization on a team are really great programmers, once you start paying people, there is the chance that at least some people there are just sort of doing the minimum they can get away with to not get fired or to get promoted or whatever the bar is. And I think that that thinking influences the design of languages targeting that environment. So when you have that sort of environment, a language really wants to avoid foot guns. Like there are some features that can be used by someone in a really clever way but can also be used to shoot your foot off, then the language is much more likely to take those out if you are targeting this sort of environment. Again, being a little more general, the language wants to prevent corner cutting in whatever way possible. Even if that means being more verbose, if it makes things explicit and people have to sort of lay out every step they are going through, that can make it easier to deal with the person who might be inclined to cut some corners if they could get away with it. And finally, the language from a design perspective wants to optimize for making the code as reviewable as possible. Small diffs where you have a style that doesn't indicate that lines have changed when they really haven't. It also means bigger language design issues like discouraging interactive programming. You don't really want from this perspective a program that you have to fire up a repel and really engage in dialogue with the code that may be easy for someone to write and easy for someone else to maintain later, but it's hard for someone to read a patch set and really have a sense of whether it's a good change or not. So it is harder to review. So that's the big tech environment. You've got languages that are built for a large team with high turnover where people may be inclined to cut some corners, or at least some of them. And I think that you can hopefully get a feel for the sorts of things that, the sorts of directions that that pushes the design of the language. I want to be clear that everything I said over there were values that are higher priorities for that environment. I'm not saying that those are bad things, certainly for our free software language. Certainly I think that free software languages should aim to be easy to learn and have a reviewable code. But I think that as I'll get into in just a minute, those aren't quite as high a priority. Reviewable code is great, but if you know that many of your people using the language are going to be in solo projects or very small teams, there probably won't be the same opportunity for code review. So that's not going to be the same priority. So what priorities will there be over here in the free software world? Well, when you're dealing with a small team, you absolutely want the language to be as powerful as it possibly can be. Free software is, or really anytime where you have a small team, is absolutely the sort of underdog when it's going up against big tech companies. I want to be clear that it is absolutely possible to do a better job with a small team than it is with a huge team. I think, you know, I was using Impress because I think it is a better way to write a presentation than Google Slides, even though it is basically a solo project and Google Slides is funded by the most powerful, best funded tech company in the world. Similarly, I think Mastodon with a very small development team is a better social network than Twitter with a much larger team. So it is entirely possible for small teams of committed free software developers to produce better software than huge tech companies, but they've got to acknowledge that they're the underdogs, so they need every advantage they can possibly get. So it is very important that the language be absolutely as powerful as it can be. One of the best ways for a language to be very powerful is for it to be very expressive. You know, if you can say more with less, you can write your code faster, you can be more clear, and that is a great way for a small team to catch up to a much larger team. And finally, it is really important for a small team to have their language be composable, especially in the free software world where we don't have any licensing difficulties, we're happy to use something no matter how copy left it may be. And free software, the projects have a small team individually, but the free software world as a whole is very large, so to the extent you can follow the UNIX philosophy and have small composable programs, that again allows a small team to really keep up with a much larger, better funded team. Low turnover has similar effects, but I want to focus on the sort of teachability aspect. Of course, it is great for a language to be as easy to learn as possible, but when you're in a low turnover environment, it's perhaps even more important that the language for word mastery. So even if you can't quite get the hang of it at the deepest levels for quite a while, there's time for that level of mastery to pay off. There's also time for domain specific languages to pay off. You can almost think of a domain specific language as a language that you always have to teach to new people who join a project. There's no chance they used it at their previous job or project or whatever because it is specific to the language, to the domain that the project is actually in. So that is a disadvantage of doing specific languages, but when people stick around long enough, the advantages are to vastly outweigh that because they offer extreme power and ability to impose constraints and make the program much, much easier to reason about. So the ideal programming language for a low turnover environment would really support constructing domain specific languages to solve particular problems. And now I have expressiveness up there on the slide for a second time, but in a slightly different way this time. The main reason languages might limit expressiveness is to prevent people from writing code that other people can't read, but in a low turnover environment, there's much more room for a project to develop its own sort of house style. And even if it writes code in a bit of a different way than other users of the language, you know, that's fine if the expressiveness allows that. And in fact, not only is it fine, it's actually very important that the language be expressive because people are going to need to hold the code in their head much more so than they need to or even can in high turnover, large team environments. You know, if a code base is two million lines instead of a million lines, that is really not the end of the world because no one was going to read the million lines anyway. But in a low turnover environment, if a code base goes from 5,000 lines to 10,000 lines, that does make a pretty huge difference because it is entirely possible and even likely that someone is going to be trying to understand and reason about the whole code base. And so to the extent it can be more expressive, more concise, more logical, and someone can sort of hold the whole code base in their mind, that makes the language much better for that sort of low turnover environment. And the final feature of free software development that I wanted to talk about is that people are mostly self-motivated. They may be getting paid, but probably could be making more somewhere else. And some of them are not getting paid at all, working nights and weekends. So that has a few advantages, but it also raises some challenges that a language should try and address. Most importantly, if people aren't getting paid to put up with something, they probably won't. I mean, it's important for every programming language and really every human community to be friendly and welcoming and inclusive. But when you're not paying somebody to put up with nonsense, it is especially important. I know this isn't entirely a language design goal. A huge amount of it goes to the community. But there are some things a language can do in terms of encouraging good documentation. But it's so important that whether it's a language thing or a community thing, it's worth really emphasizing here. And then for the third and final time, I promise, I have expressiveness up on these slides. But this is, again, in a slightly different way. There are a tremendous number of different reasons people are motivated to write code and to write free code, free software. But one of them is the sort of expressiveness, the self-expression, the enjoyment they get out of writing that code. And if every single person writing code to solve a particular problem would solve it in exactly the same way, then it is not nearly as fulfilling to write that sort of code. So if people are self-motivated, the amount of self-expression the code allows them to have is a factor that language designers should consider. And more broadly, if people are writing free software nights and weekends because they want to, it should be fun in whatever way it can be. And in fact, because software developers tend to like using powerful tools and having expressive language features and doing things that fit into all of the other design goals of language targeting free software, it is probably not going too far to say that free software language should be optimized for fun. That last slide might have tipped my hand a bit, but I happen to think that ECU does an excellent job aiming at and at times achieving these values that are so important for an ideal free software language. Exactly how and why I think that is a topic for a whole other presentation and something I've written about on my blog. But I think ECU does a really good job, but perhaps more importantly than that, I think that ECU is aiming at this in a way that so many other languages aren't, which again is not surprising at all. Most other languages were either initially designed by or are these days in large part funded and had their development push forward by huge tech companies who have the sort of scale that make where it makes sense for them to really invest in language design. I think ECU is somewhat unique in how closely it is tied to free software in its sort of origin story and how much it continues to be so closely associated with free software. So I don't think that it is at all an accident that ECU is aiming at free software use case in a way that many other languages, including some excellent languages, just aren't aiming at. But I, while I don't think it's an accident, I also don't think it is a guarantee. So I guess part of my goal with this presentation is a bit of a call to action to say, I hope that these values, I hope that you agree that these values are really important if a language wants to target free software. And I hope that I've persuaded you that it is worth doing so, and I hope that together we can keep Raku targeting that use case and aiming at these sorts of things. I hope you enjoyed this talk and I look forward to your questions. So I actually have a point that I'd like to expand on just a little bit based on one of the talks yesterday before we get to Q&A from this talk. And specifically, it's, I'd like to say something that is expanding based on Matthew's presentation on surprisingly unsurprising features of Raku. And what he said was, you know, that even after he has been programming Raku for a long time for literally longer than Raku has existed, he's still finding things to learn and like interesting new features of the language that he hadn't realized were just that unsurprising. And I think that really hits at what I'm getting at with like rewarding mastery versus ease of learnability. Like I absolutely think that Raku and any language should prioritize learnability absolutely as much as possible. I mean, if I didn't believe that I wouldn't spend time writing introductory blog posts and contributing to the docs. And, you know, so like that is a real priority of mine, but I think that at the same time, it is even more important that we have that we build the sort of language that someone can 10 years after they have been using it pretty heavily still be finding ways to level up and that they won't sort of hit a peak and plateau there. So I thought that was a great illustration of one of the points and sort of how we can strike that trade off. But it's not about a, it's not about sacrificing teachability. Like I said, that is still really important to me and something I spend a lot of my time on. So that was sort of the follow up I wanted to have based on yesterday's presentation. Now, Stuart, I think you had agreed to read off and sort of emcee some of the questions. So if anyone else has questions, feel free to put them in the chat or jump in to the audio. But Stuart. Yeah, thank you very much. So there was a thank you very much for your talk, Daniel. That was excellent. There was a comment around signatures. Would you like to expand on that the point being that they look somewhat different to the coders as expected? Yeah, and I think that that is something that is, goes into the point about sort of what you're used to at a particular organization that you can find something in, you can sort of, when a language is more flexible, you can develop a sort of house style that you are very comfortable with and then use that and it will be sort of the way the language fits your brain the best. If a language is less expressive and sort of forces you into a particular style, then you don't have that option. And so I think that that is one of the ways that an ideal for software language, you know, can leverage that expressivity is when you're not trying to make a language that can fit into the sort of huge team environment, you can make it so expressive that people can sort of find their preferred way of constructing signatures or their preferred subject-verb order or whatever it is that sort of fits their brain. Yeah, so that's what I have to say about that. Thank you very much. Now, you talked in your talk, you were talking about having the difference between a larger team and a smaller team. What about people who are working by themselves in a community? How does that relate? So I mean, I think I would describe someone who's working. Let me ask a clarifying question. Do you mean working by themselves in a community? You mean someone who's working by themselves but accepting contributions from other people in a community or building a tool that will be used by other people in the community? What do you mean by in a community? Yeah, so someone who's working by themselves may be contributing to a community piece of software rather than being a small team or a larger team. Okay, yeah. So I mean, I think to some extent it depends on the size of the team working on the software as a whole. So like even if many of the people who are contributing code to the Rackudo compiler are working by themselves physically. I would describe that as a larger team project because it does have a number of different people and like you need to have a cohesive style. But when you have something like Impress that I talked about in the presentation where it is collaborative in the sense that it is out there for everyone to use and accept pull requests, but the majority of the code is done by just one or two or three or four people. I would describe that as a small team project. Right. Thank you very much. There was another comment about Rackit. So you're familiar with Rackit and that may have a similar approach to Rackit. I think it does. I presented a dichotomy in this talk between languages that come out of sort of big tech and the sort of ideal programming language for free software and that is an important dichotomy. There's sort of a third category that I skipped in the interest of time and that is languages that come out of academia. And I would put Rackit in that category which I think has a lot of overlap with languages that are good for free software but some subtle differences. And I really like Rackit but I think that it is not as much an ideal free software language but for different reasons that I don't have a huge amount of space. That would probably be another interesting talk to contrast the ideal academic language with the ideal free software language. But I would put Rackit more on the academic side of the spectrum although it does have a good job of hitting many of the values that I think are important for free software language. Okay. Thank you very much. So considering that Rackit and Pearl don't have corporate ownership, what are the biggest downsides where the languages you've talked about have downsides may be about being written to solve Google's problems. What are the downsides about not having that corporate big tech leader direction? Well, I mean when I think it really comes down to resources, Larry Wall, when talking about the effort to write what became Raku said, the old saying is you've got to do it cheap, faster, good, pick two and in free software we knew we had to do it cheap because we didn't have the resources to throw at it. So then we were really left with just pick one between good and fast and I think anyone who followed the story of Pearl 6 development and then Raku development knew that they picked good over fast in terms of not speed of the program but speed of delivering their language and I think that was a good point.
 In this presentation, I'll be discussing a question that is very important to me.  What makes a programming language good?  Not just in general terms, but specifically good for writing free software.  Before diving into that, though, I'd like to take the opportunity to introduce myself  to those of you who don't know me.  My name is Daniel, but some of you may know me as Code Sections if you've seen me around  the RACU community.  I'm a full-time pre-software developer, and my primary programming language is RACU,  although I also program in Rust or other languages as the need arises.  I also serve on the RACU Steering Council.  Before switching to software, I was a practicing attorney with a law firm in New York City,  and though I no longer practice, the mindsets are a bit more similar than you might think.  Oh, and one other note, the icon that I use, I have noticed that it is pretty similar  to Camilla, the logo for the RACU programming language, but I wanted to mention that that  is just a coincidence, though a happy one that makes me smile every time I notice it.  With that out of the way, let's dive in.  What makes a programming language especially good for writing pre-software?  In the course of answering that question, there are three different points that I hope  to convince you of.  First, that pre-software projects are different, and when I say different, I really mean that  in two different ways.  First, pre-software projects are different from other types of software projects.  And second, and perhaps more surprisingly, pre-software projects are different from the  image that many people have of them.  Second, I'd like to convince you that there are some excellent languages out there that  just really aren't very good for writing pre-software.  They're good at other things, but they're not good at that.  And third, and relatedly, I'd like to convince you that the ideal pre-software language should  be different from other languages, even other excellent languages, because it's aiming at  different sorts of projects that should have different design goals.  So let's start by saying how pre-software projects are different.  I'd like to start with an even more basic question.  What is pre-software?  What are typical pre-software projects?  A lot of times people talk about pre-software by mentioning Linux or Firefox or other high-profile  open-source projects.  And some people have said that pre-software is like building a cathedral where you have  a group of architects and then many laborers who execute their plan.  And other people have said, no, it's like a bazaar where many people work together along  similar lines, but there's little or no central organization.  But somehow out of that chaos, order emerges.  Those are both kind of dated.  More recently, I've seen a blog post that said pre-software is really like nuclear power  where you have a huge team that pours a lot of time and energy into an initial reaction,  hoping that it will become self-sustaining and produce even more energy in the end.  And I just don't really buy any of those.  They all have some good points to them, but all of those analogies miss one really important  thing.  They miss the fact that Linux is a penguin.  What I mean by that is you shouldn't think about Linux or Firefox when thinking about  pre-software projects.  Yes, a penguin is a bird, but if you think about penguins when thinking about birds,  you're going to end up very confused about birds and have all sorts of the wrong ideas.  A penguin and Linux are both exceptional examples that are not good to generalize from.  And specifically, Linux and Firefox and these other high-profile projects are exceptional  in terms of their size.  Most pre-software projects are extremely small.  This is a study from Redmonk and before thinking it doesn't prove my point as well as it does,  notice that the axis is logarithmic.  So here, diving into their numbers a little bit more, they found that half of the active  pre-software projects had only one contributor a year, 70% had one or two contributors, and  87% had five or fewer contributors.  Another group of academics took a look at the same issue.  They came at it from a slightly different angle and looked at truck factor, how many  sort of core contributors would it take for a project to really be in trouble if they  were to go away.  But cutting the other way, they took a very narrow definition of what it meant to be popular.  They started just with the 100 most-starred repos in six language and then removed any  that were in the bottom 25% in terms of other measures of popularity, which cut out the majority  of them actually.  So this is just the very most popular projects.  But even in that sort of rarefied company, they found that 34% had a truck factor of  just one, one primary developer.  And another 30% had a truck factor of two.  It's nice to have academic studies that give a big picture view, but it's also helpful,  I think, to dive into a more concrete example.  So in that spirit, I'd like to talk about Impress.js, which is a somewhat randomly chosen  project, but it's the software I use to write the slides that you're watching right now.  And I really enjoyed using it.  I thought it was a great project.  It's very popular, you know, Hins of Thousands of Stars on GitHub.  And when I open its contributor page on GitHub, I see that it has 77 contributors.  Those aren't all in the same year, but I looked at it a little more closely and it had 16  contributors in its first year.  So that would put it outside of the 87% of the projects that Bedmunk said had fewer than  five contributors.  So it, you know, on first look, seems like an exception to the rule that free software  projects tend to be small.  But let's look a little closer.  When I dove in, its top contributor had 148 commits.  The next contributor had 51 commits, then 14, then six, then just four.  So this is not really a story of a project that has, you know, is a bizarre with 70 different  people all working together.  It's really a story of a project that has a couple of main contributors and then other  people who submitted, you know, one-off patches or had particular features that they were  interested in implementing.  And I want to be clear that I'm not knocking that type of contribution.  In fact, I did it myself, but, you know, I found a couple of features that I wanted to  add to Impress while I was writing this presentation and submitted some PRs.  And I hope that that was helpful to the project.  And I think that that sort of contribution absolutely can be.  But I also think that if we're thinking about things in terms of a bizarre model, we're  probably going to have the wrong idea.  This is not a large group collaboration.  This is a story of a couple people working as main authors and other people helping out,  but in a different way.  And I said a couple people, but let's take a look at those couple of main authors.  And they're actually, well, we can notice the timing is kind of interesting.  The first author had nearly all of their contributions in 2012.  After that, the next main author started contributing in 2018.  So this really isn't even a story of two people working together.  This is a story of a project that had a primary maintainer and then several years later a  different primary maintainer.  So it has really been not a solo project, 77 contributors, but a project that has had  a solo lead developer.  Again, very different from the bizarre sort of model.  So yeah, that actually makes me think free software is not like building a cathedral  or running a bizarre or running a nuclear power plant.  Writing free software is like writing a novel.  Let me play out this analogy a little bit.  As I just walked through, in both cases, you have one author or maybe a small handful of  co-authors.  In both cases, there are many other contributors for books that editors, agents, publishers  for software, all the contributors, bug fixes, documentation, et cetera.  In both cases, those other contributors play a really essential, invaluable role, but they're  not playing the same role as the author.  And in both cases, the author is very likely to be part of some sort of broader community,  literary community, coding community, but the actual writing of the code or of the prose  is a solitary activity.  So if that's the mental model we have, we think of writing free software as akin to  writing a novel, what consequences does that have for us?  Well, I want to return to these points.  Free software projects are different than other software projects.  They're less collaborative, more like writing a novel.  That leads me to believe that some excellent languages are not good for writing free software.  I want to turn to that next, and then that will sort of bleed into our discussion of  what design goals a free software language or a language targeting free software should  have.  So I want to talk about free programming languages that I personally think are excellently designed  and there are ones that have gotten a lot of buzz and attention and developer mind share.  And I think that even though all of them are very different, all of them are especially  poor fits for writing free software.  The first language I wanted to mention is TypeScript, a JavaScript superset that adds  types and transpiles to JavaScript and really targets, among other things, front-end development  and executing in a browser.  Second, Go or Golang, a compiled garbage collected language that targets fast compile times and  is very active in sort of back-end server web development.  And finally, Rust, a compiled language with no garbage collector that aims to equal C  in performance and is very useful for systems programming and has gotten a lot of adoption.  So these languages, as I said, are three very different languages.  They don't have much at all in common other than the fact that they all have gotten a  lot of attention and buzz lately.  And for good reason, I think, I think all three are excellently designed languages.  But they have one other thing in common, the sort of organization that first created them.  So TypeScript is a Microsoft project.  Go is from Google.  Rust came out of Mozilla and now has gotten a lot of support from Amazon and really sort  of who's who of large tech companies.  And that's exactly what these have in common.  They are all the product of large tech companies.  Why does that matter so much?  Well, I think it matters because it influences their design goals.  And I say that not just because I've used these languages and have a sense of what their  design goals are, and you can sort of read between the lines and their documentation,  but because all three of these languages have actually been remarkably explicit about what  their design goals are.  This is true for all three languages and I have some links in the notes for this presentation  if you're curious about other languages.  But I'd like to particularly focus on a talk and paper that Rob Pike gave describing Go.  He said, among much else, and really the whole talk is worth a read, but he said, Go is a  programming language designed by Google to help solve Google's problems and Google has  big problems.  Now, a lot of people have focused on that last bit that Google has big problems, big  in the sense of the scale that they operate at, being very large.  But I really want to focus in on that middle part.  This language was sort of from start to finish designed to solve Google's problems.  And I think the same is true of the other two languages I mentioned.  TypeScript was designed to solve Microsoft's problems.  Rust was designed pretty explicitly to help Mozilla build a better Firefox.  And there's nothing wrong with any of those goals.  I want to be clear.  I think that those are good goals to have and it makes sense that some really good programming  languages have those sorts of goals.  These large tech companies are exactly the sort of company where it makes sense to invest  money in developing a whole new language.  And as Rob Pike said, they do have big problems.  So it is absolutely, I can understand why some languages come out of that environment.  But I think that that environment is very different from the sort of solo developer free software  or code as novel environment that is really important for free software language to target.  To explain what I mean, I'd like to look at three different features of the big tech  environment compared to the free software code as novel environment.  And then for each of those features, look at how that feature of the environment impacts  the language design goals of a language targeting that sort of environment.  So first in big tech, you have really large teams, small teams in free software as we've  talked about pretty extensively.  Big tech also has high turnover, just like the law firm I worked at.  It's not at all uncommon for people to start their career there before quickly moving on  to somewhere else and they're sort of constantly hiring from people who have just completed  their CS education.  Free software on the other hand, a lot of these small projects have one maintainer for  decades, but even if it's not quite to that extreme, the turnover is much, much lower.  In big tech, people are there because they're getting a paycheck.  They may have other motivations as well, but that is a sort of defining feature of the  job is that it is a job.  Free software developers tend to be much more self motivated.  They may or may not be getting paid at all.  They are, they're getting paid probably less than they would make at a different way that  they could be spending their time.  So the motivation is pretty different.  So how do those features of the big tech environment impact design goals of a language targeting  that environment?  Well, when you've got a large team, you really want to have a standard code format.  You want your, to use tools like Go format or Rust format or prettier.js to make all  the code look exactly the same because you want everybody on the team to be able to read  each other's code just like they wrote it themselves.  More broadly, you want there to be just one way to do it.  That plays out in syntax and style guides, but also in standard library design, also  in the, just the amount of syntax, the language design itself.  And in language design choices, like limiting customization, like operating or overloading  and other ways that people can sort of make the language their own.  And all of that is in service of avoiding dialects.  So, it is really bad if Bob writes some code and then Alice writes some different code  and those two, even though they're programming in the same language, might as well be programming  in different language and they can't read each other's code.  In that talk about the design of Go that I mentioned earlier, this was explicitly called  out as one of the design goals for Go that they wanted to avoid subsets or dialects of  the language.  Things are similar when we talk about high turnover, those two do tend to go together,  but I think high turnover really creates an emphasis on the speed at which people can  pick up the language.  So, you want it to have a familiar syntax.  All of these languages bear more than a passing resemblance to C and that's not at all a  coincidence.  More broadly, you want the language to be easy to learn, not just in terms of syntax,  but in every other aspect of it.  If people are only there for a few years, you don't have time for a long learning curve  to really pay off.  Again, Go was very explicit about this value and it is famously easy to learn and even  in just a weekend to pick up the basics.  Rust is a bit of an exception here in that it is not as easy to pick up.  But I think it is clear if you spend any time in the Rust community that they take the value  of being as easy to learn as possible consistent with the nature of the language extremely  seriously.  If there's anything better from the perspective of a big tech environment than having a language  that is easy to teach new hires, it's having a language that you don't need to teach them  at all because they already know it.  So it is even better for language design if you can make the language popular in whatever  way possible.  And I think Microsoft and Google and to a lesser extent Mozilla have put a lot of emphasis  in evangelical efforts behind their language and making it easy to gain that sort of popularity.  The final feature of a big tech environment that I'd like to focus on is that people  are getting paid.  I want to be both tactful and precise in talking about this because it is, of course, the case  that there are many absolutely amazing programmers who are working at these large tech organizations  and working primarily for the paycheck is no reason at all that someone can't be a way  better programmer than I'll ever be.  But the thing about money is that everybody likes money.  So even if many of the people at an organization on a team are really great programmers, once  you start paying people, there is the chance that at least some people there are just sort  of doing the minimum they can get away with to not get fired or to get promoted or whatever  the bar is.  And I think that that thinking influences the design of languages targeting that environment.  So when you have that sort of environment, a language really wants to avoid foot guns.  Like there are some features that can be used by someone in a really clever way but can  also be used to shoot your foot off, then the language is much more likely to take those  out if you are targeting this sort of environment.  Again, being a little more general, the language wants to prevent corner cutting in whatever  way possible.  Even if that means being more verbose, if it makes things explicit and people have to  sort of lay out every step they are going through, that can make it easier to deal with  the person who might be inclined to cut some corners if they could get away with it.  And finally, the language from a design perspective wants to optimize for making the code as  reviewable as possible.  Small diffs where you have a style that doesn't indicate that lines have changed when they  really haven't.  It also means bigger language design issues like discouraging interactive programming.  You don't really want from this perspective a program that you have to fire up a repel  and really engage in dialogue with the code that may be easy for someone to write and  easy for someone else to maintain later, but it's hard for someone to read a patch set  and really have a sense of whether it's a good change or not.  So it is harder to review.  So that's the big tech environment.  You've got languages that are built for a large team with high turnover where people  may be inclined to cut some corners, or at least some of them.  And I think that you can hopefully get a feel for the sorts of things that, the sorts of  directions that that pushes the design of the language.  I want to be clear that everything I said over there were values that are higher priorities  for that environment.  I'm not saying that those are bad things, certainly for our free software language.  Certainly I think that free software languages should aim to be easy to learn and have a  reviewable code.  But I think that as I'll get into in just a minute, those aren't quite as high a priority.  Reviewable code is great, but if you know that many of your people using the language  are going to be in solo projects or very small teams, there probably won't be the same opportunity  for code review.  So that's not going to be the same priority.  So what priorities will there be over here in the free software world?  Well, when you're dealing with a small team, you absolutely want the language to be as  powerful as it possibly can be.  Free software is, or really anytime where you have a small team, is absolutely the sort  of underdog when it's going up against big tech companies.  I want to be clear that it is absolutely possible to do a better job with a small team than  it is with a huge team.  I think, you know, I was using Impress because I think it is a better way to write a presentation  than Google Slides, even though it is basically a solo project and Google Slides is funded  by the most powerful, best funded tech company in the world.  Similarly, I think Mastodon with a very small development team is a better social network  than Twitter with a much larger team.  So it is entirely possible for small teams of committed free software developers to produce  better software than huge tech companies, but they've got to acknowledge that they're  the underdogs, so they need every advantage they can possibly get.  So it is very important that the language be absolutely as powerful as it can be.  One of the best ways for a language to be very powerful is for it to be very expressive.  You know, if you can say more with less, you can write your code faster, you can be more  clear, and that is a great way for a small team to catch up to a much larger team.  And finally, it is really important for a small team to have their language be composable,  especially in the free software world where we don't have any licensing difficulties,  we're happy to use something no matter how copy left it may be.  And free software, the projects have a small team individually, but the free software world  as a whole is very large, so to the extent you can follow the UNIX philosophy and have  small composable programs, that again allows a small team to really keep up with a much  larger, better funded team.  Low turnover has similar effects, but I want to focus on the sort of teachability aspect.  Of course, it is great for a language to be as easy to learn as possible, but when you're  in a low turnover environment, it's perhaps even more important that the language for  word mastery.  So even if you can't quite get the hang of it at the deepest levels for quite a while,  there's time for that level of mastery to pay off.  There's also time for domain specific languages to pay off.  You can almost think of a domain specific language as a language that you always have  to teach to new people who join a project.  There's no chance they used it at their previous job or project or whatever because it is specific  to the language, to the domain that the project is actually in.  So that is a disadvantage of doing specific languages, but when people stick around long  enough, the advantages are to vastly outweigh that because they offer extreme power and  ability to impose constraints and make the program much, much easier to reason about.  So the ideal programming language for a low turnover environment would really support  constructing domain specific languages to solve particular problems.  And now I have expressiveness up there on the slide for a second time, but in a slightly  different way this time.  The main reason languages might limit expressiveness is to prevent people from writing code that  other people can't read, but in a low turnover environment, there's much more room for a  project to develop its own sort of house style.  And even if it writes code in a bit of a different way than other users of the language, you  know, that's fine if the expressiveness allows that.  And in fact, not only is it fine, it's actually very important that the language be expressive  because people are going to need to hold the code in their head much more so than they  need to or even can in high turnover, large team environments.  You know, if a code base is two million lines instead of a million lines, that is really  not the end of the world because no one was going to read the million lines anyway.  But in a low turnover environment, if a code base goes from 5,000 lines to 10,000 lines,  that does make a pretty huge difference because it is entirely possible and even likely that  someone is going to be trying to understand and reason about the whole code base.  And so to the extent it can be more expressive, more concise, more logical, and someone can  sort of hold the whole code base in their mind, that makes the language much better for that  sort of low turnover environment.  And the final feature of free software development that I wanted to talk about is that people  are mostly self-motivated.  They may be getting paid, but probably could be making more somewhere else.  And some of them are not getting paid at all, working nights and weekends.  So that has a few advantages, but it also raises some challenges that a language should  try and address.  Most importantly, if people aren't getting paid to put up with something, they probably  won't.  I mean, it's important for every programming language and really every human community  to be friendly and welcoming and inclusive.  But when you're not paying somebody to put up with nonsense, it is especially important.  I know this isn't entirely a language design goal.  A huge amount of it goes to the community.  But there are some things a language can do in terms of encouraging good documentation.  But it's so important that whether it's a language thing or a community thing, it's  worth really emphasizing here.  And then for the third and final time, I promise, I have expressiveness up on these slides.  But this is, again, in a slightly different way.  There are a tremendous number of different reasons people are motivated to write code  and to write free code, free software.  But one of them is the sort of expressiveness, the self-expression, the enjoyment they get  out of writing that code.  And if every single person writing code to solve a particular problem would solve it  in exactly the same way, then it is not nearly as fulfilling to write that sort of code.  So if people are self-motivated, the amount of self-expression the code allows them to  have is a factor that language designers should consider.  And more broadly, if people are writing free software nights and weekends because they  want to, it should be fun in whatever way it can be.  And in fact, because software developers tend to like using powerful tools and having expressive  language features and doing things that fit into all of the other design goals of language  targeting free software, it is probably not going too far to say that free software language  should be optimized for fun.  That last slide might have tipped my hand a bit, but I happen to think that ECU does  an excellent job aiming at and at times achieving these values that are so important for an  ideal free software language.  Exactly how and why I think that is a topic for a whole other presentation and something  I've written about on my blog.  But I think ECU does a really good job, but perhaps more importantly than that, I think  that ECU is aiming at this in a way that so many other languages aren't, which again  is not surprising at all.  Most other languages were either initially designed by or are these days in large part  funded and had their development push forward by huge tech companies who have the sort of  scale that make where it makes sense for them to really invest in language design.  I think ECU is somewhat unique in how closely it is tied to free software in its sort of  origin story and how much it continues to be so closely associated with free software.  So I don't think that it is at all an accident that ECU is aiming at free software use case  in a way that many other languages, including some excellent languages, just aren't aiming  at.  But I, while I don't think it's an accident, I also don't think it is a guarantee.  So I guess part of my goal with this presentation is a bit of a call to action to say, I hope  that these values, I hope that you agree that these values are really important if a language  wants to target free software.  And I hope that I've persuaded you that it is worth doing so, and I hope that together  we can keep Raku targeting that use case and aiming at these sorts of things.  I hope you enjoyed this talk and I look forward to your questions.  So I actually have a point that I'd like to expand on just a little bit based on one of  the talks yesterday before we get to Q&A from this talk.  And specifically, it's, I'd like to say something that is expanding based on Matthew's presentation  on surprisingly unsurprising features of Raku.  And what he said was, you know, that even after he has been programming Raku for a long time  for literally longer than Raku has existed, he's still finding things to learn and like  interesting new features of the language that he hadn't realized were just that unsurprising.  And I think that really hits at what I'm getting at with like rewarding mastery versus ease  of learnability.  Like I absolutely think that Raku and any language should prioritize learnability absolutely  as much as possible.  I mean, if I didn't believe that I wouldn't spend time writing introductory blog posts  and contributing to the docs.  And, you know, so like that is a real priority of mine, but I think that at the same time,  it is even more important that we have that we build the sort of language that someone  can 10 years after they have been using it pretty heavily still be finding ways to level  up and that they won't sort of hit a peak and plateau there.  So I thought that was a great illustration of one of the points and sort of how we can  strike that trade off.  But it's not about a, it's not about sacrificing teachability.  Like I said, that is still really important to me and something I spend a lot of my time  on.  So that was sort of the follow up I wanted to have based on yesterday's presentation.  Now, Stuart, I think you had agreed to read off and sort of emcee some of the questions.  So if anyone else has questions, feel free to put them in the chat or jump in to the  audio.  But Stuart.  Yeah, thank you very much.  So there was a thank you very much for your talk, Daniel.  That was excellent.  There was a comment around signatures.  Would you like to expand on that the point being that they look somewhat different to  the coders as expected?  Yeah, and I think that that is something that is, goes into the point about sort of what  you're used to at a particular organization that you can find something in, you can sort  of, when a language is more flexible, you can develop a sort of house style that you  are very comfortable with and then use that and it will be sort of the way the language  fits your brain the best.  If a language is less expressive and sort of forces you into a particular style, then  you don't have that option.  And so I think that that is one of the ways that an ideal for software language, you know,  can leverage that expressivity is when you're not trying to make a language that can fit  into the sort of huge team environment, you can make it so expressive that people can  sort of find their preferred way of constructing signatures or their preferred subject-verb  order or whatever it is that sort of fits their brain.  Yeah, so that's what I have to say about that.  Thank you very much.  Now, you talked in your talk, you were talking about having the difference between a larger  team and a smaller team.  What about people who are working by themselves in a community?  How does that relate?  So I mean, I think I would describe someone who's working.  Let me ask a clarifying question.  Do you mean working by themselves in a community?  You mean someone who's working by themselves but accepting contributions from other people  in a community or building a tool that will be used by other people in the community?  What do you mean by in a community?  Yeah, so someone who's working by themselves may be contributing to a community piece of  software rather than being a small team or a larger team.  Okay, yeah.  So I mean, I think to some extent it depends on the size of the team working on the software  as a whole.  So like even if many of the people who are contributing code to the Rackudo compiler are  working by themselves physically.  I would describe that as a larger team project because it does have a number of different  people and like you need to have a cohesive style.  But when you have something like Impress that I talked about in the presentation where it  is collaborative in the sense that it is out there for everyone to use and accept pull requests,  but the majority of the code is done by just one or two or three or four people.  I would describe that as a small team project.  Right.  Thank you very much.  There was another comment about Rackit.  So you're familiar with Rackit and that may have a similar approach to Rackit.  I think it does.  I presented a dichotomy in this talk between languages that come out of sort of big tech  and the sort of ideal programming language for free software and that is an important  dichotomy.  There's sort of a third category that I skipped in the interest of time and that is languages  that come out of academia.  And I would put Rackit in that category which I think has a lot of overlap with languages  that are good for free software but some subtle differences.  And I really like Rackit but I think that it is not as much an ideal free software language  but for different reasons that I don't have a huge amount of space.  That would probably be another interesting talk to contrast the ideal academic language  with the ideal free software language.  But I would put Rackit more on the academic side of the spectrum although it does have  a good job of hitting many of the values that I think are important for free software language.  Okay.  Thank you very much.  So considering that Rackit and Pearl don't have corporate ownership, what are the biggest  downsides where the languages you've talked about have downsides may be about being written  to solve Google's problems.  What are the downsides about not having that corporate big tech leader direction?  Well, I mean when I think it really comes down to resources, Larry Wall, when talking  about the effort to write what became Raku said, the old saying is you've got to do it  cheap, faster, good, pick two and in free software we knew we had to do it cheap because  we didn't have the resources to throw at it.  So then we were really left with just pick one between good and fast and I think anyone  who followed the story of Pearl 6 development and then Raku development knew that they picked  good over fast in terms of not speed of the program but speed of delivering their language  and I think that was a good point.
programming_lang_for_free_software_0_131.png programming_lang_for_free_software_132_179.png programming_lang_for_free_software_180_635.png programming_lang_for_free_software_636_827.png programming_lang_for_free_software_828_1283.png programming_lang_for_free_software_1284_2063.png programming_lang_for_free_software_2064_2243.png programming_lang_for_free_software_2244_2423.png programming_lang_for_free_software_2424_2963.png programming_lang_for_free_software_2964_3899.png programming_lang_for_free_software_3900_4295.png programming_lang_for_free_software_4296_4523.png programming_lang_for_free_software_4524_5471.png programming_lang_for_free_software_5472_6671.png programming_lang_for_free_software_6672_7583.png programming_lang_for_free_software_7584_8771.png programming_lang_for_free_software_8772_9359.png programming_lang_for_free_software_9360_9887.png programming_lang_for_free_software_9888_10631.png programming_lang_for_free_software_10632_10775.png programming_lang_for_free_software_10776_10847.png programming_lang_for_free_software_10848_10895.png programming_lang_for_free_software_10896_12707.png programming_lang_for_free_software_12708_13991.png programming_lang_for_free_software_13992_14195.png programming_lang_for_free_software_14196_14327.png programming_lang_for_free_software_14328_15731.png programming_lang_for_free_software_15732_16643.png programming_lang_for_free_software_16644_17867.png programming_lang_for_free_software_17868_18899.png programming_lang_for_free_software_18900_19031.png programming_lang_for_free_software_19032_20339.png programming_lang_for_free_software_20340_20639.png programming_lang_for_free_software_20640_23147.png programming_lang_for_free_software_23148_24575.png programming_lang_for_free_software_24576_24959.png programming_lang_for_free_software_24960_25295.png programming_lang_for_free_software_25296_25931.png programming_lang_for_free_software_25932_27275.png programming_lang_for_free_software_27276_28163.png programming_lang_for_free_software_28164_30935.png programming_lang_for_free_software_30936_33335.png programming_lang_for_free_software_33336_35195.png programming_lang_for_free_software_35196_37007.png programming_lang_for_free_software_37008_40715.png programming_lang_for_free_software_40716_42935.png programming_lang_for_free_software_42936_45419.png programming_lang_for_free_software_45420_49643.png programming_lang_for_free_software_49644_53147.png programming_lang_for_free_software_53148_53243.png programming_lang_for_free_software_53244_53519.png programming_lang_for_free_software_53520_53579.png programming_lang_for_free_software_53580_54563.png programming_lang_for_free_software_54564_56939.png programming_lang_for_free_software_56940_57587.png programming_lang_for_free_software_57588_59291.png programming_lang_for_free_software_59292_59795.png programming_lang_for_free_software_59796_59915.png programming_lang_for_free_software_59916_60407.png programming_lang_for_free_software_60408_61691.png programming_lang_for_free_software_61692_61955.png programming_lang_for_free_software_61956_63755.png programming_lang_for_free_software_63756_64487.png programming_lang_for_free_software_64488_65783.png programming_lang_for_free_software_65784_65904.png