Inverse Sapir-Whorf and programming languages
46 points by spookylukey
46 points by spookylukey
Really cool article.
One way to think of language design (both programming and spoken) is that by choosing what elements you put in the language, you choose where you think a user should put their attention. C implicitly says "we want you to care about memory management". Haskell says "we want you to care about what types variables and expressions can contain".
When the language guides you in a way that aligns with where you do want to put your attention, it feels well suited for the job. When it doesn't, it feels like you're at a cocktail party trying to listen to a quiet speaker while someone across the room is yelling and distracting you.
Our attention is, I think, our most precious resource, so it makes sense to be mindful of how our tools guide and shape it.
Perhaps a name for the idea that 'your language restricts what you cannot say' could be something like the non-neutrality of expressions (in a given language, relative to a particular topic). How an English expression explicitly using or omitting "the" is non-neutral regarding the specificity of its subject, and how the example Turkish expression using or not miş is non-neutral regarding whether the information was attained first or second-hand. This would then be clear as the inverse of the neutrality of expressions, or the standard Sapir-Whorf hypothesis stating that 'your language restricts what you can say' about the inexpressibility of phenomena in a language (although I never personally thought of the original hypothesis as making such a distinction).
Then neutrality or non-neutrality of a language on a given topic becomes something we can describe and, as language designers, tune to dilute or focus a users' attention onto: using garbage collection to keep expressions neutral regarding heap allocation, or adding effect-tracking so that expressions are non-neutral regarding side effects and IO.
I'm not sure I fully grasped the point of the post, but it did bring to mind a drum I've been beating for a while about Rust. So apologies if this is tangential.
Rust occupies this weird space where it allows you to work with references but has strict rules about them to ensure that memory is safe. If I were writing C++ and I think something should be a reference, I make it one and then hopefully don't suffer the consequences. If I were writing Python, I copy my data with reckless abandon because I don't have that kind of control. But in Rust you can get caught in this optimization hole where you think "let's make this a reference because copying data is inefficient," and then the borrow checker yells at you but you're sure it is safe to be a reference so you spend an hour refactoring your code.
Many good Rust programmers say "just use .clone, RC, Box, etc." and I agree. But that doesn't change the fact that references are available to you and you are quite sure it would be safe to use one. So it sits weirdly because you know you could make it "better" but you've decided to make it worse to appease the borrow checker.
So I can kind of understand why some (many?) people throw up their hands and say "the borrow checker is too much for me" --- I assume they've fallen into the same trap.
This seems very related to what I was trying to get at in my article: Rust makes you think about some of these things and make some choices, while other languages don't, and that adds to the burden of using the language (as well as the power).
Awesome. Love the topic, love too that it talks a bit about Turkish grammar (a topic I hear far too little about).
Another common example: Plurality is a detail that can be omitted in some languages, e.g. Vietnamese.
And it was very pleasing to see a link on the word "exaggerated", think "I wonder if that link points to an article about Arrival", then discover that yes, yes it does. A movie beloved by many but I couldn't suspend my disbelief -- like science fiction but the "science" is some kind of magic linguistics.
Plurality is exactly the thing that I think we try to paper over with things like APL or Pandas or SQL.
Most application programming languages focus on singular values as their sort of 'atomic' base. From there one can build things like Lists or Maps, but these are themselves singular things, and often not cross-compatible in subtle ways. In Rust you're often copying from one to another. In SQL you stop caring about this but then you have to start caring about indexes and query plans, esp. when the database comes up with an obviously very stupid way to complicate what you were trying to ask. And let's not even touch SQL NULL.
The end result is that most of our software is unbelievably overspecified to the level of individual values, to the extent that best-case UI Latency is 10x what it used to be, despite 1000x more powerful PCs. Object-oriented programming dogma is partially to blame for this. Async took a stab but it was too easy to decay back to losing the forest for the trees (think, awaiting each of a series of independent things).
One must imagine https://www.uiua.org/ happy.
Imperative code tends to very explicitly focus on pulling items out of collections and operating upon them one at a time.
A functional style tends to favor more abstract iteration- filters, maps, flatmaps, etc- but still bake in handling collections and items of a specific, fixed rank.
Since APLs make it easy to write code that both abstractly and implicitly iterates, and the same program can often be applied to a variety of ranks of input, it can be surprisingly challenging to capture the actual generality of APL-style code when transliterating it into other languages- I wrote a short piece touching on this a while back.
Of course, this expressiveness can cut both ways; sometimes it's difficult to imagine the intended behavior of a fragment of code in an APL-family language separately from the data it applies to, in much the same way that SQL can be puzzling without the corresponding schema of a database. Is the generality of a function intentional, or accidental? If I leverage the generality of a definition, am I building on a stable contract, or exploiting a brittle, incidental property?
APL philosophy teaches us to try to make systems so small and clear that they can be thrown away and rewritten from whole cloth as requirements change, but sometimes there isn't enough time to write a short program, so we write long ones.
The first thing that popped into my mind was interfaces to objects or modules. I'm every programming language this is really concrete but it's a lot fuzzier in natural language conversation.
Another example was generics in c++ vs Python (though maybe covererd in the post as strictly typed languages). In c++ you need to be really intentional about it, whereas in python (ignoring type hints) it's very implicit.
Ngl, until I looked it up just now I always thought it was something named after some Star Trek episode.
inverse Sapir-Whorf says your language limits what you can’t say, or makes it hard not to say some things, or even hard not to think about some things
I picture it as a pyramid of syntax > idioms > standard libs > 3rd party libs > ecosystems (frameworks and engines). The "hard not to think about" part seems to focus on problems with constraints difficult or important to express; familiarity seems to work from top and bottom in, and people hint at their background in how they write at each layer.
15+ years of reading, writing, and speaking English and I didn't know that "I live in London" and "I'm living in London" are different.
(I also don't know if I live in London or I'm living in London 😅)
For "I'm living in London", it's a bit useful to expand out to "I am living in London". Now switch out the gerundive for a regular adjective "I am cold." I you said that, I would expect that you are currently cold, but not that you are permanently cold in some sort of supervillain manner. Similarly, "I am living in London" implies that you live in London currently, but that it may change in the future. There's also an indication that you did not always live in London, just as "I am cold" rather implies that you've at least once experienced a warm enough temperature to recognize that your current condition is "cold" and not "normal".