(Editor's note: transcripts don't do talks justice.
This transcript is useful for searching and reference, but we recommend watching the video rather than reading the transcript alone!
For a reader of typical speed, reading this will take 15% less time than watching the video, but you'll miss out on body language and the speaker's slides!)
[APPLAUSE] Hi. Thank you again. Hi, everybody. Wow. This has been an amazing couple of days, at least from where I've been sitting. I was wondering how this is going to just be such an amazing connection of different ideas, and I think it's just gone off even better than I possibly could have imagined. It's been so educational for me so far. So can we just get another round of applause for the organizers and speakers?
Thank you so much for making this amazing conference happen. I'm really excited to be here with you today. I feel very honored to be here, and I'd like to talk to you today about the language of programming.
My name is Anjana Vakil. You can find me on Twitter at my name. And I am a software developer among other things, but I didn't study computer science. I got to know and love programming and software development through the field of linguistics and computational linguistics, linguistics being the scientific study of language. So great that we got a refresher on the scientific method just now. So that's what linguists do with language. And this has really colored my perspective on how I think about code and doing software development, and I'd like to share a little bit of that perspective with you today.
Before I studied linguistics, I studied philosophy, so I like to get into these really big, open-ended, philosophical questions like, what even is code? I make fun of myself, but I think it's actually important for us to take a step back once in a while and ask ourselves these questions. I think it's probably not that controversial to say that we think of code as some kind of language. We use the word programming language. We use a lot of metaphors of language when we talk about code, but usually, we think about it as being a language intended to communicate with machines for us to talk to machines.
This is how I definitely thought about it when I first started coding. I thought, OK, cool. I can have some brilliant idea. I write it down in my programming language of choice. I save it to a 3 and 1/2 inch floppy, which I then insert into my laptop's floppy drive, of course, and execute the program. And then voila, my idea comes to life.
But recently, I've started thinking a little bit differently about code, and I've started wondering whether actually thinking about it in terms of an analogy of a language for machines is really the best way. And I'm definitely not the only one who asks this question.
There's an interesting essay or article by Yukihero Matsumoto, who created the Ruby language, which has come up a couple of times today, including our first talk by Julia. He compares code to an essay and says that both essays and lines of code are meant, before all else, to be read and understood by human beings. So reframing code in this way-- no longer as a language that is primarily intended for humans to communicate their ideas with machines, but rather, for humans to communicate their ideas with each other and then also run those ideas on machines.
So code then starts to look more like human language, which is all about collaboration. We use human language, and some theories say we evolved human language to work together so that we could survive in the wilderness because we're not great at evading lions on our own.
And code is also a really collaborative endeavor. So when I write my program and save it to my floppy, I am not just writing something that I can execute in the machine and bring my idea to life. More importantly, I'm writing down something that someone else can come along and read and understand what that brilliant idea was that I had, what it is I'm trying to get the computer to do. And then they can work with me to do it together. So we can both collaborate on this idea on making the idea better and making the program better and bringing the idea more realistically to life.
And it's in this sense that code gives us the ability to collaborate, that much like language, it gives us this incredible power. This sort of brings to mind the legend of the Tower of Babel-- so the idea that there was a time when all of humans spoke one, single language. We could all understand each other, and that allowed us to all work together to do anything we could set our minds to, including the completely audacious idea of building a tower all the way to heaven. And this gave us so much power, this single, unified language and the collaboration it enabled, that even the omnipotent being, God, felt threatened and worried about humans having all this power, and so, the legend goes, split up our language, scattered us all about, made us speak different languages so that we could no longer understand each other and collaborate and do such audacious things.
Now, this may or may not be the scientific explanation of how the world got so many languages, but it's probably not what linguists would say happened. They think it has a lot more to do with how we evolved as a species and moved around and things like that. But one way or another, the world ended up with a bunch of different languages.
So human language-- and as we'll see in a moment, also programming language-- is something that has many different faces, and linguists seek to understand language generally, globally. So they take the perspective that every single language matters, and every single language has something it can tell us about how language works in general. So they value every data point that they can get about the way a particular language works, the way it behaves, the way languages are different. They value all of those data points as precious pieces of a single, unified puzzle of how language works.
This is a map from a really cool site called the World Atlas of Language Structures, which if you're interested in language features is a great way to explore how the world's languages are similar and different. And here, we're visualizing a particular feature-- in this case, a grammatical feature of language. And the different colors indicate languages that have a similar way of approaching this feature or different ways. And the particular feature that we're looking at is whether or not the language has gender distinctions in its personal pronouns.
There's a couple of interesting things to notice about this map. One thing is that the languages that were studied-- and it's about 300 and some languages, which is a very small fraction of the world's roughly 7,000 languages-- but that a lot of the languages share features, but that there are also some languages that do things quite differently. So for example, there are only a couple of languages that have gender distinctions in the first or second person, but not in the third person like he or she. And the other interesting thing to notice about this map is that about 70% of the languages in this sample-- 254 of them-- don't make any gender distinctions in personal pronouns, which I'm just going to point out without further comment.
So the way that linguists look at different languages to try and get a global perspective of how language works is really by taking language and breaking it down into its constituent parts by deconstructing language. Do you see what I did there? Yeah. And they do this in lots of different ways.
So one way that we've actually already made reference to today-- in Alison's talk this morning, we saw the sentence "Colorless green ideas sleep furiously." I am so delighted and shocked that this sentence has come up twice in one day at a programming conference, but it's amazing. This is a sentence, as we saw earlier, that Noam Chomsky put forward in his groundbreaking book Syntactic Structures, which came out in 1957, where he was really concerned with how syntax works in language and breaking the structure of words in a sentence and the phrases that those words make up-- breaking that down and looking at it completely independently of any meaning that those words might have. Hence the sort of nonsensical non-meaning of this sentence.
So looking at the syntax of words and phrases and how those are structurally related, this is just one way that linguists look at language. There are lots of other levels of abstraction and other structural units that they analyze in order to understand how language works. Some units are much bigger and higher level, like entire texts. Sometimes they look at a much smaller level, like the sub-word units of meaning called morphemes, like the de- and the -ing in "deconstructing." Sometimes they look at written forms of language. Sometimes they look at the sound of language, trying to understand how the spoken form of words breaks down into syllables, how syllables break down into phones and to individual sounds, et cetera.
And this is sort of similar to the work that we do as programmers and as software developers when we analyze our programs and think about how they work. We also try to break them down. We analyze them on lots of different levels of abstraction, sometimes big levels like modules or even entire code bases, if we're talking about micro-services working together. Sometimes we get really, really low level and we think about the way individual bits and bytes are organized into pieces of data or the instructions that we're sending to a virtual or a physical machine.
And of course, there are other intermediary units that we might use to break down our programs-- so things like functions. Perhaps if you're a functional programmer, you think in terms of how your program is structured as functions composed together, or objects, if you're an object-oriented programmer, as we saw yesterday in Sandy's talk. And it's important for us to remember that the way that we break down our programs, the way that we understand them and the structures that we look for in them are not these sort of platonic, objective entities that exist somewhere out in the world. They are all embedded in theories of how programs work or how they should work.
This is true in linguistics as well. Here's a quote from a linguist named Michael Tomasello. He says that there are no theory-neutral structures in linguistics. This comes from an interesting paper he wrote called "Language is Not an Instinct," which is a response to a book perhaps some of you have heard of by Steven Pinker, another linguist, called The Language Instinct.
And this gets at this really deep war, I guess, in the linguistics community between the two different ways of looking at language as something that's innate, which came out of this Chomsky-an school of universal grammar, et cetera, et cetera, or is something that comes more generally out of our human cognitive and social functions. And we're not, unfortunately, going to have time to go into all of the interesting intricacies of that debate, but suffice it to say that I think it is interesting for us to think about the perspective that we are necessarily taking when we posit certain structures in our programs, just as linguists have to think about the theories that they're working in when they posit certain structures in language.
And we have to remember that whenever we talk about a certain structure, be it in human language or programs, we're working in a worldview that tells us that that structure is the important one to pay attention to. And we have a name for that kind of worldview. We can call it a paradigm, and that's where the notion of programming paradigms comes from.
Programming paradigms is a subject I could nerd out on for just eons of time. I'm going to spare you, but I do think it's important for us to remember that if we're going to look at deconstructing the code that we write, the language that we use, we also have to think about understanding the structure of the paradigms that we're writing that code in.
One computer scientist who works on this is Peter van Roy, and he describes languages. He says that each language supports or realizes one or perhaps multiple different programming paradigms-- so maybe functional programming, object-oriented programming, procedural programming, et cetera, et cetera. But each of those paradigms is not an indivisible unit. They can be understood further by breaking them down into the concepts that they support.
So each paradigm is made up of different concepts-- for example, things like, does it support state? Does it allow non-determinism? Et cetera, et cetera-- and there's a lot of these. And these concepts are really the crucial ideas here because it's the collection of concepts that a paradigm, and therefore, a language, supports that make it a better or worse fit for a particular problem.
And he says that all of these are valid. Just like linguists think that all languages tell us something interesting about human language, Peter van Roy says that each paradigm-- and therefore, each language, insofar as it supports the paradigm-- supports a set of concepts that make it the best for a certain type of problem.
So it stands to reason that since we as humans have just an infinity of problems and we're always going to have more because we seem to create them for ourselves all the time, it behooves us to use as wide a range and as diverse a range of different concepts, paradigms, languages as possible so that we have hammers for the right nails.
And what this brings to mind from the field of linguistics is another word that in linguistics is kind of a dirty word-- "prescriptivism." So a prescriptive statement in linguistics is something that says how language should be, as opposed to a descriptive statement which says how language is without making any kind of value judgment. So for example, a prescriptive statement you may have heard at some point in your life-- something like, "The correct form is is not. Ain't is incorrect and bad, and you should not use it."
That's prescriptive, and linguists have no time for that. Linguists are not interested in making prescriptive value judgments like that. They are only interested in considering, hey, we hear both of these things. We hear "is not" sometimes. We hear "ain't" sometimes. Let's try to understand when, and how, and in which situations, and why.
And this is something that we as programmers, as a community, could stand to learn from linguists because there's a fair bit of prescriptivism that goes around. If you've ever been on the internet, you will notice that. And this isn't anything new. This has been happening in computing for a long time. For example, in 1975, a guy named Dijkstra--
--who I guess did some important stuff said a bunch of really, really offensive and disturbing things on many levels, but basically making all kinds of negative prescriptive value judgments about some very important and influential languages. He wrote that FORTRAN is an infantile disorder, and people who've done BASIC are mentally mutilated, and that COBOL cripples the mind.
And then he just said APL is a mistake. It's a well-executed mistake, he says, but no, just a mistake. Just no, Dijkstra. This is not how we should be thinking about things. If we as a community and as individuals want to get better at understanding programs and how they work and what the nature of programming as a discipline is, we don't have time for this kind of prescriptive nonsense. Instead, we should understand that each of these languages is, was, and might still be best for certain types of problems.
And let's take this last one as an example-- APL. Who's heard of APL? Because I had not until recently. OK, a lot of hands. Great. Who's written APL? OK, like, three, maybe five hands? OK, yeah. So APL is a language that I was not familiar with until recently. It was created by Kenneth Iverson in a book called A Programming Language, hence APL. You only get to do that once.
I don't know. So Dijkstra said it's a mistake. From Kenneth Iverson's perspective, it certainly can't be, because it won him a Turing Award in 1979. He developed APL as a type of sort of mathematical notation that he had this vision for-- what if we could solve problems with a notation that allowed us to think in the most convenient way to that problem, and then we could also execute that notation instead of having to go off and write a mathematical solution to a problem in a certain mathematical notation and then translate it into a computer program that uses a completely different way of describing what we're trying to do, the algorithm that we're trying to use?
So this is what he came up with. This is from APL. Well, it's a more modern form of APL called Dyalog. I have no idea what these symbols do, but can anybody guess what this program is?
The Game of Life.
It's Conway's Game of Life. Very good. So it basically-- this is an implementation of the Game of Life in one line of code, which if you're into code golf, this surely is exciting. We are already seeing APL definitely ain't a mistake if you're able to write an entire program in one line.
What APL does is it focuses on arrays and on matrices, and this is kind of the central idea around which it's based. So it lends itself really well to solving problems that can be represented in terms of matrix manipulations. For example, the Game of Life-- we have this grid of cells that are alive or dead, and we can represent that with a matrix. And then, we can calculate future generations by doing transformations on that matrix.
So this is a type of problem that this language, which Dijkstra thinks is a mistake, is really well-suited to solve. And maybe it has a steep learning curve, I'm guessing, but there are lots of enthusiasts of this language, and it gave birth to a whole family tree of array programming languages.
And those were very influential on some other languages that we're perhaps more familiar with, like Matlab and R. Has anybody used Matlab or R? OK, quite a lot of hands, but actually, kind of the same number as APL, which is awesome. All right. We're going to talk about that later.
So Matlab and R are also languages that do a lot-- that handle things like matrix manipulations really well. They're used a lot in scientific computing, and they were both influenced by ideas from array programming languages, which ultimately trace back to APL. So we certainly can't say it's a mistake if we're doing useful things in it, if we're doing science in it, for example.
And other cool trivia fact, since APL is great at matrix math, it also lends itself well to problems in computer graphics. And there was at least one case, according to the internet-- Wikipedia-- of a company using their implementation of APL to do some computer graphics for, among other things, the movie Tron. So if you like Tron, you also partly have APL to thank.
The point is, you are able to do useful stuff in this language. Therefore, it had a certain place and time, and we need to understand it in terms of those problems that it was good at solving, and in terms of the context in which it was created.
And this is also something important to linguists. From that same paper, Tomasello says, "Languages are cultural artifacts. They differ radically among different cultures, and they change in important ways as the communicative needs of their speakers evolve over time."
So we have to understand languages as the product of a community that has certain needs, that has certain things it wants to do. And that community in human natural language, as in programming, will create tools and evolve them over time to solve the problems that it has, to fit its needs.
So this is the other major idea that I took away from my studies in linguistics, which is that we have to understand language in context. For example, the field of sociolinguistics looks at language thus. It says we can't really understand language as if it's in a bubble, as if it's this isolated thing out in left field. We have to understand that it is part of a wider context, a wider social and cultural context that humans find themselves in. And that means that it is inextricably intertwined with all of the other aspects of human culture and society, including notions of power and status, including systems of economics and politics, issues related to race and gender. There is no way to de-tangle language from all of these things.
And make no mistake about it. This doesn't just apply to human natural language. This applies to code as well. Programming as a human activity, as a way that we humans try to work together to solve our problems, is related to all other human activity. I think [? Naveel's ?] talk yesterday made that case absolutely beautifully. And we have to understand code in the wider social context that it finds itself in.
Another field of linguistics that thinks a lot about context is pragmatics, which studies how we actually use language, how language is performed, as it were. And under this view, whenever we utter a sentence or whenever we write something down, we are performing an action. We are doing something in the world. We are having some kind of effect. So we need to be conscious of what kind of effects we're having.
And this applies to our code as well, not just how we talk about, the kind of prescriptive statements we make, not just the blog articles that we write, but even sometimes the words that we use for the concepts in the code itself, which sometimes even show up as things like variable names. So when we use words, we have to remember that they exist in a wider social context. They have meaning, and they have impact.
So there are certain words that come up a lot in computer science that have a very negative impact. For example, we often hear terms like "whitelist" and "blacklist" to talk about things that are trusted or things that are not trusted. Sometimes you see metaphors of masters and slaves used to describe systems. These words do not exist independently of history, independently of culture, independently of society, and they can have a real negative impact.
This is a tweet from a woman named Kiya Thomas, who-- this was a few years ago-- apparently was in class and felt negatively affected by these terms coming up over and over again. And this is something that we see, unfortunately, a long history of using terms like "white" and "light" to talk about positive things and trustworthiness and purity and things like that, and words like "dark" and "black" to refer to negative things when we think of terms like the "dark web," for example.
There is no way to de-tangle these from their wider context. And before you say no, well, that's not really what they mean, that's not what I intended, that's not the actual etymology of the words, in the perspective of sociology and sociolinguistics and pragmatics, it doesn't matter because these words still evoke all of those cultural issues. And so when we write in code or we're writing about code and we're talking about code, we really need to pay attention to the words that we're using and the language that we're framing it in and the impact that those can have.
And the thing is, there are such simple ways of making this better. There are simple substitutions that we can use that are not only not so negatively culturally loaded, but are also, in many cases, just much more self-explanatory. A safe list is a list of safe things. In a way, it involves less processing to understand.
So we really need to be conscious about the words that we choose because there is no way to de-tangle our programs from this context, and especially when we're thinking about this in settings like a class, like an educational context. We have to be all the more sensitive to the culture and society that we're operating in because if we look at code as something that gives us the collaborative power to do what we want to do in the world, we need to make sure that we are extending that power to everyone. And if we're going to teach programming around the world, we have to be aware of those cultural biases.
There's a quote from Ramsey Nasser, a programmer who created an Arabic programming language called Alb. I hope I'm pronouncing that somewhere close to correct. And I think that this applies not just to teaching programming, but if we're going to do programming anywhere, we have to be conscious of the cultural biases, but especially in that educational context. He created Alb partly because of the understanding that most of our languages-- they work with certain assumptions like, for example, that you're used to reading Roman scripts or that you're used to reading from left to right, and neither of those are true if your native language is Arabic.
This Alb project inspired a great talk I saw last week at Bang Bang Con by [INAUDIBLE] that showed an example of another Arabic programming language he created called Nor. Typologically different than Alb-- Alb is like a functional LISP-type language, and Nor is more [INAUDIBLE] inspired, more imperatives, procedural.
But the idea here is that this is a language that is intended to allow people, especially children whose first language is Arabic, to have a more seamless entry into coding so that they can start learning to code. This is not meant to be a language that goes into production. It's meant to be an educational language.
And so we need to do this. We need to think about the context that we're teaching and we're operating in, and we also need to be thinking about if we're going to be extending programming as a language to more people, if we're going to be teaching programming, how do we understand the process of learning that language?
So one thing that we learn from linguistics, and especially the field of study concerned with language acquisition, is that there's a lot that we can take away from that study of how humans acquire language that we can use to inform how we teach and how we help people learn programming. So one thing that language acquisition teaches us is that just as no language exists independent of context, we also don't learn independent of context. We learn words, and we learn types of phrases and things like that in the contexts in which we need them. We learn the word "cat" when we see a cat, et cetera.
So this is something that you run into in a lot of introductory programming texts. These nonsense words like "foo" and "bar" and "bes"-- when I was first learning to program, I was so confused by these words. I was reading a book. I was learning from a book, and I had to flip back and forth to see if I'd missed something. Did they introduce the concept of what a "foo" is and I somehow skipped that chapter accidentally? What is a foo? It's not a thing.
These are just nonsense words, and they're kind of a catch-22 because they only really mean anything to you if you've already gone through an introductory programming course and you've already associated these words with nonsense programming. Let's not do that when we're teaching people to code. Let's use real words that have meaning, that tell them something about what the code is supposed to be doing.
Another thing that we can learn from language acquisition is that when we learn a written form of communication, it's very, very closely connected to the spoken form. So we probably all have the experience that when children are learning to read, we see them reading out loud to themselves or to others. Or when we are trying to-- as adults trying to learn a foreign language, we often sound out the letter, sound out the words. This is a crucial part of the language acquisition process, and this is something that is really interesting to think about in the context of code.
So OK, I want to play a tiny game. All right. Turn to the person next to you. Say hi. Cool. OK. Now, on the count of three, read this line of code out loud to them. 1, 2, 3.
[BABBLING] is what I heard. OK, now raise your hand if you said the same thing as the person next to you. There's a few scattered hands. A few people did, but the vast majority did not, right? Because how do you pronounce this?
There's no standard form. Some people might say result equals analyze data. You might say set result to analyze of data because we're calling the function of some input. Maybe you say the right-hand first and you say analyze. Maybe you say, oh, it's a string. Analyze string data becomes result. Who knows? How do we pronounce this? There's no standard way.
This is a really interesting field of study that [INAUDIBLE], a computer scientist in the Netherlands, and her group are looking into. They're terming it code phonology, trying to understand whether there's a connection between how we can pronounce the code that we see on the page and how we learn it. So for example, is it possible that by developing a canonical way of pronouncing code, we could actually help people learn to code faster? Or we could even, as programmers who already know how to code, become more productive, for example, when we're pairing? It's really interesting. Definitely recommend checking it out.
The final thing that I want to mention that we can learn from language acquisition is that as humans, we can't learn language alone. We don't learn language alone. A human baby cannot learn to speak if it is not exposed to other humans. That's generally what's found, and I think this also applies to us as programmers. We don't and can't learn in a vacuum.
The notion of the self-taught programmer I think is a myth. I learned to program from a book the first time I wrote code, but that doesn't mean that I was teaching myself. Somebody else has written that book, and that book was in a library full of useful things. And I had the internet and all of the blog posts, for better or worse, and the forums and things like that.
We don't learn alone, and we can't, and we shouldn't. And so what we should really think about as programmers and as developers is how crucial the notion of communities of learning is to us getting better as individual programmers and collectively advancing the art of software development.
So I've been really lucky to be a part of some amazing learning-oriented communities. One is the Recurse Center. You might have heard of it. It's a programming retreat and space and amazing community in New York City. Check it out.
Another thing we need to think about in the industry of software development is how we approach learning in terms of things like internships and apprenticeships. I was really fortunate to get started in tech via an internship program called Outreachy, which offers paid remote internships to women and under-represented minorities for them to get started working in open source. These kind of programs make a huge difference to how we are all able to collaborate and work together to get collectively better at doing code.
And now, in my current job, I work for Mapbox. My title is engineering, learning, and development lead. It's my job to pay attention to the learning culture at our company and to make sure that it is a positive learning community for all of our engineers, and more generally, for all of our teammates so that we can all work together to be leveling ourselves and leveling each other up every day at work. If that sounds like a cool thing, you can check out our careers page. This isn't a pitch, but in any case, I think it's important that we be attentive to the cultures of learning in our communities, and that we make sure that we foster spaces and programs through which people can learn together and can together acquire this beautiful, powerful language of code.
So I'm a little bit behind time. Thank you for putting up with me. I know I'm the last thing between you and really interesting conversations that are about to happen outside. I'll just leave you with this. So I think that we've all probably, when we first started to code, had a moment where we've realized how much power we had now that we could type these magical spells into the computer and make something happen, even if it was just making the words "hello, world" appear where before there had been nothing. And this power-- it's really only when we come together, when we collaborate on these ever more complex, ever more far-reaching, ever more efficient, ever more useful programs and systems that we can really start to see the full force of that power.
And I hope that we've today started a conversation or get started thinking about the fact that it's code as a language that allows humans-- us humans-- to talk to one another about our ideas and about how we want them to come to life that really gives us that possibility for collaboration, and thus, the power that we feel from it. And so of course, as you're probably guessing, the question, which I think has come up several times in these fascinating two days, that this leaves us with is given this immense collaborative power that the language of programming provides, what are we going to do with it?
So thank you so much to everyone who spoke and to all of the organizers who made this happen and to all of you for listening. This has been an amazing experience, and yeah. Hope we'll all be thinking about this when we go home from the conference. Thank you.