So it seems that I have not actually said on here some things that I have come to realize in the past year. Mostly this is about languages, and programming. Some people will disagree with this, most others won't care, but I'm sure there are at least a few who will like it. I'm not saying anything new, anyway, at least not new to people who read Paul Graham or Steve Yegge, and they are all better at saying it than me.
There are differences in languages. Human languages, I'll talk about programming later. There are some concepts you can't say in English, like "losing face" or schadenfreude or agape. There are many other concepts that you can't say in other languages, like Japanese or Spanish or French. Go read about the Navajo code talkers; they had slang for everything since there are just no words in Navajo for "tank" or "airplane". Even beyond vocabulary, there are structural differences. Romance languages use word endings to form parts of speech, and Germanic languages use particles.
As English speakers, we have the luxury of not caring about this. English steals structural components from all kinds of language, and vocabulary as well. We can look down from the top of the spectrum and not have to know that there are languages without the words for things like "crankshaft". The other languages get there in the end, describing tanks as buffalo and airplanes as dragonflies or whatever, and they can still get things done, but their world is described through a fuzzier lens than ours. Languages shape perception, and English allows us to have a very sharp lens through which to perceive.
I've had people tell me in the past that programming is not like this. Any programming language can write any program, modulo some odd ducks like SQL or regular expressions which are not Turing complete, a phrase used like a talisman to ward off having to understand computability. This idea is called The Turing Tarpit in some circles, and it comes from a misunderstanding of how programs are made.
A program is a representation of an algorithm. An algorithm is a mechanical process that solves a problem in finite time. For a long time in the 1930s and 1940s, it was thought that you would need one machine to run each algorithm. A business would buy a sorting machine and an adding machine and a dividing machine and whatever else they needed. Turing's clever, important, vital thesis was that there was one machine, a universal machine (or Turing machine, although he didn't like the term), that would do all algorithms, including those that hadn't been thought of yet.
So the Turing Tarpit is the idea that at one level, all languages are equivalent, because any language that can emulate a universal machine (or "is Turing complete") can solve any problem.
The minor problem is that we're not talking about algorithms, we're talking about programs, which are representations of algorithms. A hundred lines of Java might represent the same algorithm as three lines of Lisp, but they are very different representations, very different programs. You can say in English that you take joy in watching others suffer, but there is no word for schadenfreude.
There are things you cannot say in some languages. The only thing left to argue is whether they are things worth saying, and I believe that they are.
There are two dominant "real" languages. I'm not counting "support" languages everyone uses like SQL and Javascript; there are two dominant "real" languages: Java and C#. They are part of the same language family, along with C and C++. They are all "curly brace" languages, united by a common syntax and a common ideology.
All these languages let you define data, and code, but separately. You cannot treat data as code, nor code as data.
You cannot pass a function as a parameter to a function, nor return a function from a function. You cannot build a function out of statements and compile and run it on the fly. Data is data, code is code, never shall the line be crossed.
There are things you cannot say without that. In Lisp, or Javascript, I can make a function that will return each member of an array, one by one:
You simply can't say that in Java. There are no words for "this is a function that modifies a function" (combinator) or "this function returns code, compile it" (macro). You can do the same things (that example is an "iterator" in curly brace languages), but they're not the same concepts. There are things you can't say.
It's not about writing shorter code. Shorter code is good for many reasons, but it's not really about that. It's about writing cleaner code, with fewer stupid bugs and less repetition. Short is just a pleasant side-benefit.
It's about being able to write poetry, instead of legalese.
It's a little like ordering food from a place where nobody speaks English, this frustration. I know what I want to say, but I have to translate it into very simple concepts that form a shared ground between the language I think in and the language the compiler speaks. Can't use
Sure, it's the same algorithm, at some level. Do you think at that level? Should you? Shouldn't we have grown out of that by now?
There are differences in languages. Human languages, I'll talk about programming later. There are some concepts you can't say in English, like "losing face" or schadenfreude or agape. There are many other concepts that you can't say in other languages, like Japanese or Spanish or French. Go read about the Navajo code talkers; they had slang for everything since there are just no words in Navajo for "tank" or "airplane". Even beyond vocabulary, there are structural differences. Romance languages use word endings to form parts of speech, and Germanic languages use particles.
As English speakers, we have the luxury of not caring about this. English steals structural components from all kinds of language, and vocabulary as well. We can look down from the top of the spectrum and not have to know that there are languages without the words for things like "crankshaft". The other languages get there in the end, describing tanks as buffalo and airplanes as dragonflies or whatever, and they can still get things done, but their world is described through a fuzzier lens than ours. Languages shape perception, and English allows us to have a very sharp lens through which to perceive.
I've had people tell me in the past that programming is not like this. Any programming language can write any program, modulo some odd ducks like SQL or regular expressions which are not Turing complete, a phrase used like a talisman to ward off having to understand computability. This idea is called The Turing Tarpit in some circles, and it comes from a misunderstanding of how programs are made.
A program is a representation of an algorithm. An algorithm is a mechanical process that solves a problem in finite time. For a long time in the 1930s and 1940s, it was thought that you would need one machine to run each algorithm. A business would buy a sorting machine and an adding machine and a dividing machine and whatever else they needed. Turing's clever, important, vital thesis was that there was one machine, a universal machine (or Turing machine, although he didn't like the term), that would do all algorithms, including those that hadn't been thought of yet.
So the Turing Tarpit is the idea that at one level, all languages are equivalent, because any language that can emulate a universal machine (or "is Turing complete") can solve any problem.
The minor problem is that we're not talking about algorithms, we're talking about programs, which are representations of algorithms. A hundred lines of Java might represent the same algorithm as three lines of Lisp, but they are very different representations, very different programs. You can say in English that you take joy in watching others suffer, but there is no word for schadenfreude.
There are things you cannot say in some languages. The only thing left to argue is whether they are things worth saying, and I believe that they are.
There are two dominant "real" languages. I'm not counting "support" languages everyone uses like SQL and Javascript; there are two dominant "real" languages: Java and C#. They are part of the same language family, along with C and C++. They are all "curly brace" languages, united by a common syntax and a common ideology.
All these languages let you define data, and code, but separately. You cannot treat data as code, nor code as data.
You cannot pass a function as a parameter to a function, nor return a function from a function. You cannot build a function out of statements and compile and run it on the fly. Data is data, code is code, never shall the line be crossed.
There are things you cannot say without that. In Lisp, or Javascript, I can make a function that will return each member of an array, one by one:
function traverse(arr){ var n=0; return function(){ return arr[n++]; } }
You simply can't say that in Java. There are no words for "this is a function that modifies a function" (combinator) or "this function returns code, compile it" (macro). You can do the same things (that example is an "iterator" in curly brace languages), but they're not the same concepts. There are things you can't say.
It's not about writing shorter code. Shorter code is good for many reasons, but it's not really about that. It's about writing cleaner code, with fewer stupid bugs and less repetition. Short is just a pleasant side-benefit.
It's about being able to write poetry, instead of legalese.
It's a little like ordering food from a place where nobody speaks English, this frustration. I know what I want to say, but I have to translate it into very simple concepts that form a shared ground between the language I think in and the language the compiler speaks. Can't use
map
, it doesn't exist and I can't make it. Write another loop. Can't write a macro for this, just copy and paste it.Sure, it's the same algorithm, at some level. Do you think at that level? Should you? Shouldn't we have grown out of that by now?