8 ms·
We need less powerful languages (2015)
- EGreg 4y agoYes! I liked the original C because of that. So did Linus: https://www.youtube.com/watch?v=CYvJPra7Ebk https://www.youtube.com/watch?v=CYvJPra7Ebk I remember this great talk Growing a Language by Guy Steele, totally on point, about Java... I liked Java: https://www.youtube.com/watch?v=_ahvzDzKdB0 https://www.youtube.com/watch?v=_ahvzDzKdB0 I even liked the original C++ when it came out, and used it (although needing to do >> > was a bit silly). But then it jumped the shark with C++0x and thereafter. Concepts. Lamdas. Time travel. Quantum mechanics. Even Bjarne Stroustrup quit and is like "whaaa" In this interview with Dennis Ritchie, James Gosling, Bjarne Stourstrup, the latter is the most verbose. And it shows in the C++ features hehe. When everyone knows the 10 features the language has, teams can work together without a language lawyer and tricky "look ma no hands" code This is what makes games like Chess great, as opposed to, say, Yu Gi Oh: https://www.youtube.com/watch?v=Wr13DYngSqE&t=4m30s https://www.youtube.com/watch?v=Wr13DYngSqE&t=4m30s
- hinkley 4y ago> When everyone knows the 10 features the language has You have to be careful here because people will give you/expect emergent behavior to pick up the slack, and then you get a language that has barely any syntax or semantics and all of the functionality comes from stringing a bunch of NewSpeak-looking bullshit together into a system that would make Rube Goldberg suicidal. As simple as possible, but no simpler.
- kelipso 4y agoHaha, brainfuck is simple and only has five features that everyone knows but...there's going to be a decent number of patterns you'll have to memorize.
- hinkley 4y agoAs someone who's spent a thousand hours or so thinking about the board game Go, I'm quite familiar with the idea of simple rules with an explosion of consequences. Unfortunately I'm also familiar with the consequences in software. Fractal code sounds like it might be cool until you have to edit it, especially if it's someone else's. This is the domain of madmen.
- nine_k 4y agoWe already have less powerful languages, like C. The results are underwhelming. We need powerful languages with the power harnessed and thus safer to use. It's like saying that we only need chisels and knives instead of power tools. I'd say we need power tools with proper safety features, and thoughtfully built to make them efficient to use. The particular case of Python is exactly about the lack of harnessing. The same reasons would apply to Perl even more, and equally to Smalltalk or Ruby, etc; cleanliness of the design is not the point. Any of these languages is basically play-doh. You can build anything from it. It will not be very strong, and it's a bit hard to make it into a precise shape. But it's supremely easy to quickly prototype anything in such a language. When you don' have a clear plan, constantly experiment in a REPL, and keep reworking your design several times a week, nothing beats a highly pliable, highly dynamic language like Python. Then, of course, you have to ship it, and can't afford rewriting it. There are hyper-powerful languages like C++ and Rust. They are much harder to wield, and C++ famously does away with many safety features for the sake of ultimate flexibility, while Rust goes to great lengths to ensure safety and efficiency at the same time. Rapid prototyping in them is not easy even for top experts. There are relatively fine middle-ground languages, to my mind: say, Kotlin (or even plain modern Java), or Ocaml (maybe using the Reason syntax), and even Typescript where you can increase strictness gradually while allowing areas in the codebase still in magma state. But Python, due to its very friendly and human-readabale syntax, won a lot of mindshare by being easy for a beginner, and also by having a nice set of very important libraries (many not written in Python). So we'll see a lot of software that could benefit from being written in a less play-doh-like language, but were started in Python, and will not be rewritten. Python specifically tries to grow some safety / stability harness, in the form of optional typing and mypy, protocols, etc. It's better than nothing, but it's still far from allowing to write bulletproof code effortlessly.
- shpongled 4y agoPersonally, I find rapid prototyping much faster in Rust than Python, and I don't think I'm a "top expert".
- nine_k 4y agoCan you write a function in a REPL and run it instantly? Can you easily inspect intermediate results? In this regard I love Haskell's REPL mode, it's really productive for prototyping. It has a worse discoverability / autocompletion story than Python REPL though.
- Jensson 4y agoMost programmers aren't metaprogramming, to them expressiveness isn't a big issue like it is for programmers making frameworks or languages. Making languages less expressive to make the life of framework programmers easier but at the cost of all the other programmers isn't a good trade-off most of the time.
- nine_k 4y agoNo, lack of powerful tools in a language is not limited to library authors. If authors can not use powerful tools, they cannot create powerful libraries for other developers to use. Everybody is then pushed down to the low expressiveness level. Case in point: Golang until recently, Java before version 5. Copy-paste programming is as prone to bugs as stringly-typed programming. If there needs to be a strict separation between powerful tools and easy tools, using two different languages works well enough. Many game engines allow level designers write small Lua scripts, for instance. Or the whole Visual Basic thing which allows to glue together powerful COM components. Also, nearly every templating language allows for simple data manipulation (iteration, filters) while not being Turing-complete. (That works until the users of the simple glue language require enough features for the glue language to become a principal tools for developing increasingly complex things, and we're in square one. Could have started with a proper language...)
- Jensson 4y agoStatic types for example, it is one of the few things where the trade-off seems to be worth it, so I agree there are times where the improvement of tools can improve productivity more than expressability of the core language. But those things are already widely popular, someone saying "we need less powerful languages" means they want even more than that, I'm not aware of any things that aren't currently popular that would improve these things by a lot.
- nine_k 4y agoA language that plays with types fast and loose is strictly more "powerful" in the sense that it accepts an attempts to execute more programs than a language with a stringent type system. Natural language is the most powerful (kind of) language we have, because using it we can generate narrower and stricter languages (mathematics, for instance) and communicate their semantics to fellow humans. But natural language can express a lot of things that are imprecise, like "huh?" or "well, you know...", or, say, profanities. So a somehow less powerful language, with some restrictions requiring politeness and clarity, is easier to understand. That's the point of the original article, broadly. That's what I mean by "harnessing" the power. Restricting the language by simplifying it, switching to baby-speak, is what I'd like to avoid: while less powerful and not allowing for many potentially dangerous constructs, it remains imprecise, but loses the ability to express complex things concisely.
- jrm4 4y agoHmm. People are talking about languages like C? I presumed (and even after reading, though not in detail) that this was more in the space of how some games are done, with C for the low level stuff and Lua for game logic, which I think is a good idea.
- chewxy 4y agoI recently gave a talk[0] to data engineers that is an extension of this idea. The conclusion I came to after years of considering this, the Blub paradox and various other sources, is that we should use more languages. In the talk I mention Gary Miller, who is working on formalizing the tradeoff between expressiveness (as defined by jumps in the language hierarchy) and decidabilities. The TL;DR is that as you jump up the language hierarchy you lose more decidabilities. A decidability is a question that can be answered with a yes/no. For example: "does this program halt?" is a decidability. Interestingly this also shows a difference between lambda calculi and universal turing machines. When you go from lambda calculi to UTMs, you lose equational reasoning (but depending on how you define an encoding function, you may also gain intensionality). This of course has some implications, which is pretty much a can of worms that nobody wants to touch (i.e. whether the Church-Turing hypothesis is true) [0]: https://www.youtube.com/watch?v=KOuwZEtHZ_U https://www.youtube.com/watch?v=KOuwZEtHZ_U
- sylware 4y agoMany compiler devs want the most complex language as possible, because it increase exponentialy developer/vendor lock-in.
- 3836293648 4y agoThat is misattributed malice. Firstly language devs are some of the most pro tiny languages people out there, it's the users that ask for the kitchen sink (though not the same kitchen sink as their neighbour) Secondly people doing something because they like it want to continue working on said thing?! What a surprise. This is not malice
- sylware 4y agoI do attribute that to malice by default, until proven otherwise. This is my opinion, pleasant or not, this is not on a whim.
- TimTheTinker 4y agoCan you name one language that this is true for? Also, this looks like a clear violation of Hanlon's razor: never attribute to malice that which is adequately explained by stupidity. Not that I'm calling compiler devs stupid, but like languages (and systems overall) do tend towards increased complexity over time. This is the default trend no matter the subject. It takes clear, agreed-upon goals and hard work to keep that from happening.
- sylware 4y agoAs I said this is not on a whim. llvm/gcc devs do not realise that there is an issue with those compilers reaching a complexity and size fairly qualified as absurd and grotesque. Since it has been roughly 2 decades, I am finished to believe those devs are merely blinded by an accute lack of experience, that's why for me those devs are actually malicious for developer/vendor lock-in, that on top of the other big issue which is planned obsolescence (mostly syntax and compiler extensions). This is so accute that the other alternative, since I now exclude any accute lack of experience, would be to start questioning their sanity, and I think we are dealing with evil, not medical pathology. I am very serious about this.
- alphanullmeric 4y agoThere’s always rust if you want the compiler to tell you you’re not allowed to do something you were intending to do.
- bitwize 4y ago"If we submit ourselves to law, Alex, even to the loss of freedoms -- the freedom to indirect through an invalid pointer, for instance -- we may discover new freedoms yet unknown to us." --Abraham Lincoln, Lincoln (2012) (paraphrased)
- ggm 4y agoThis is so good, I'm stealing it. Daniel Day Lewis didn't realise he was a C type language on a PDP type architecture.
- globalreset 4y agoThis article is missing the point. It's not just any "powerfulness" that we need to drop. Languages evolve by limiting expressiveness in ways that increase composability. The desired direction is one that increases composability, without sacrificing any other valuable properties (like performance).
- japhib 4y agoNot sure about that. The benefit of something like a dumb `MANIFEST.in` file is that it can have many implementations, and many different optimizations, while being absolutely certain that the result logic is the same. Any time you add powerfulness/expressiveness, you limit the ways it can be parsed/refactored/executed/whatever.
- JKCalhoun 4y agoI was curious about Unity, Godot lately. These "ecosystems" with built in IDE with animation trees, sprite trees, scripting languages make me a little nauseous. My experience has been that often you have an idea you want to bring to life, programmatically, design-wise, but then you find hurdle after hurdle in trying to shoehorn your idea to make it work in these prefab environments. Eventually you succumb and write the same games everyone else is writing — sigh. I think I am agreeing. It seems "composability" and "powerful" don't often go hand in hand.
- raincole 4y agoBecause these tools are built with non-programmers in mind. We're not talking about people who are not good at programming. We're talking about people who straight up refuse to read/write even the simplest code, because 1) they're afraid of code 2) they're hired as artists/designers/animators and believe code is never mentioned out of their job description.
- taeric 4y agoI'd be happy to have less focus on the textual symbols someday. Preferably without diving completely away from them into common graphical programming languages. This is largely doable in any modern environment. Dr Racket, for example, can do fun things. https://docs.racket-lang.org/teachpack/2htdpimage.html https://docs.racket-lang.org/teachpack/2htdpimage.html Emacs can largely do the same. What I would love, is an overall system that brought all of these together such that I can have images that are type checked for size or other necessary items by the build to do the next step. Instead, we have forced ourselves into text only. Everywhere. Why can't we have a visual view of what we want the UI to be that is cross linked to the code in a build/check step?
- js8 4y agoI would argue similarly, we need more languages like Dhaal or SQL or systemd, which are explicitly not Turing-complete. Most of the so-called "business logic" can be written in non-TC language. Lately, I was thinking about about a kind of pentagon of things: (1) Algorithms are primitives of data transformation, and they are written/debugged in TC languages. (2) Data transformations (like ETL process or DB transaction) are written in non-TC language (like SQL), are composable, and use algorithms (1) as primitives. (3) Platforms are primitives of execution resources, things like databases, application servers, client UI loops, etc. These are also implemented in TC languages. (4) Computational resources (like I have this many application servers of this type that provide this much CPU and this much memory) are written in non-TC language that doesn't compose in terms of functions, but in terms of resource additivity. In other words, these languages can describe global constraints on platforms (3). Something like systemd comes to mind, but perhaps more expressive. (5) Then there is a system-description language (composable but not TC) which marries the data transformations (2) and computational resources (4). It does say how data move through the system, and where each transformation gets executed. However, this language is not concerned with how each transformation gets executed (that's the job of (2) and (1)) nor with at which exactly piece of infrastructure they get executed on (that's the job of (4) and (3)). The goal would be then to take language descriptions (5),(2) and (4) and compile it in terms of (1) and (3), i.e. what actual algorithms are executing on which actual platforms. (Hence the pentagon with nodes (1)-(2)-(5)-(4)-(3).)
- FridgeSeal 4y ago> we need more languages like Dhaal or SQL or systemd, which are explicitly not Turing-complete. Agreed 100%. First time I used Dhall a similar thought crossed my mind about it being an ideal specification language for most ETL pipelines and similar “business logic” work. I feel like Spark was (in intent) an initial foray into this kind of solution with the data frames and SQL interface, but it falls short in number of ways and is way too attached to a single implementation (warts and all). The idea of a “resource descriptor language” (4) is a very cool concept, and not one I’d thought of before. Would this be granular compute resources (x % of CPU and memory, a la Kubernetes resource limits) or more like terraform? Maybe I’m misunderstanding, but isn’t (5) less of a language, and more some kind of constraint-solver based on (2) and (4). That is, it attempts to find the “layout” and allocation of resources for the requirements (optimise for minimum hardware, optimise for maximum throughput, etc). Again, this could be me misunderstanding this stage though.
- gumby 4y agoGo is waving its hand from one of the desks in the back
- rochak 4y agoNot sure if that is good or bad. The fact that you need to write a util function just to find a value in a slice is hilarious.
- kuon 4y agoI've been doing some zig and I really like how reusable is every little bit of code I write. I do not know if it is because of it's simplicity but I am quite productive with it.
- HybridCurve 4y agoThis is a bad take on a common problem with higher level languages. The burden will always be on the programmer to be responsible for selecting the best approach to implementing any solution while keeping in mind the additional workload they might be inflicting on the tools, system, or subsequent maintainers. The language, at best, can be considered at fault for providing poor documentation and bad examples for use cases (Java comes to mind: Somewhere Oracle's docs suggest defining 15+ line callback function within the argument list for the function that registers it.) which would contribute to the problem. It is possible the issues the author has pointed out instead are related to how easy it might be for an inexperienced developer to utilize the language improperly. Perl is notorious for this and it is a major complaint for everyone who has had to deal with someone else's abomination of a solution. Thus, it is common knowledge for Perl users to familiarize themselves with Conway's book 'Perl Best Practices' in order to a avoid causing grief for both your peers and antecessors.
- gavinhoward 4y agoDisclaimer: this essay of a comment is sort of an ad for my ideas. At the time this article came out, I had been designing a language for 2-3 years. I'm still designing it now, so I have more than 10 years experience. The author is right and wrong. The W3C principle is right and wrong. Paul Graham is right and wrong. The author and W3C are right in that the less power you have, the better for understanding, analysis, and even optimization/performance. Paul Graham is right that you need power. I only realized this recently after working on a build system, which might be the most hated type of software. As I designed mine, I wanted to do it right, to avoid the mistakes. The biggest mistake, and one common to nearly every build system was not providing the user enough power. The common opinion about building software is that it shouldn't be that hard. Most of the time, that's correct. But when it is hard, there is nothing that will work except raw power. When you need it, truly need it, literally nothing else will do, by definition. This leads to a quandary because by the time a project runs into a situation where building is hard, the build system is deeply entrenched. This means that changing the build system would be difficult and time-consuming for little perceived benefit. Instead, users find ways around a build system's lack of power (usually by writing a script; after all, a script is powerful) and moan about how the build system is a problem. I agree with them: such hamstrung build systems are problems. But at the same time, an all-powerful build system would be complicated to use, right? Spoiler: no, but to do it right takes actual design and user experience work instead of just coding. But let's assume it is too complicated to use. What can we do? We need the power, but the power makes it too complicated. Should we just throw up our hands and accept that the complexity is inherent, or should we hamstring the build system and hope we don't need the power? Absolutely not. Would we do that with our programming languages? No, so removing the power is not an option. Most of the time. What if we could remove the power some of the time? Let's say it's a config option we put into the build file. Maybe that option can be one of several things: 1. Only targets and commands, like a pure POSIX make Makefile. 2. Like the above, but add conditionals, like `if` statements. 3. Like both of the above, but add constrained `for` loops. 4. Screw it, add `while` loops and make it Turing-complete. 5. Let's go Hole Hawg [1] and add metaprogramming! Some projects will never leave level 1. Some will never leave level 2. Most will never leave level 3. Most of the remaining few will never leave level 4. But for those that need it, level 5 still exists! And more importantly, so does level 4. This means that the projects that don't need power won't use it and can have all of the advantages of a less-powerful language. It also means that the other projects won't curse their build system. Everyone's happy! (As a sidenote: implementing this idea is easy; the build system just needs to not allow certain "keywords" in each setting. In fact, you could make it even more granular by allowing users to forbid individual keywords!) This is an extension of a comment I wrote recently. [2] I replied to someone who asked if Guy Steele was right when he said to restrict the grammar of your language. My answer: he was, unless you need power. The more powerful your language, the more likely that an LR(1) grammar is not sufficient for it, to the point that for the most powerful of languages, only an all-powerful Turing-complete parser can parse them. There is no substitute for power. But use as little as possible. So yes, we need less powerful languages. We also need more powerful ones. Perhaps what we really need is a language whose power you can tune to your needs. (Shameless plug: stay tuned!) [1]: Read the "Hole Hawg" section of "In the Beginning Was the Command-Line" by Neal Stephenson. https://web.archive.org/web/20180218045352/http://www.cryptonomicon.com/beginning.html https://web.archive.org/web/20180218045352/http://www.crypto... [2]: https://news.ycombinator.com/item?id=34416730 https://news.ycombinator.com/item?id=34416730
- stakhanov 4y agoAfter 20 years of Python being my main language, I switched to Lua last year, and it felt great. I just felt Python's feature set was becoming too boated, and reading other people's code was becoming too much of a cognitive drain, because others don't tend to subset the language in the same way that I would subset it to keep complexity to a minimum. Also, the larger feature set of Python means that code written in Python doesn't move between environments as easily. With Lua, I can rely on hobbyist implementations running on top of Java (KeraLua/Luna), .NET (NeoLua), JavaScript (fengari), or native (the original PUC-Lua), where the latter in turn has bindings to other languages (like Python). With Python there has been the same amount of appetite to do these things (Jython, IronPython, various JS-based pythons like Transcrypt, etc.) but they just never achieve actual compatibility with CPython for practical intents and purposes.
- _taar 4y agoI've never met anyone who used lua having experienced other languages without growing to hate it. What's an example of good code in lua, that you would enjoy working on?
- stakhanov 4y agoHow many people do you know who used lua, having experienced other languages, and who did grow to hate it? What are the properties of the language that they do hate, specifically? As I've said, my own code is mostly in Lua these days, and I am enjoying working on it. It's closed-source, so I can't point you to it.
- deleted 4y ago[deleted]
- JonChesterfield 4y agoI really like being able to easily statically link libraries into the lua interpreter. Spawn a process using libuv and wrap it in a native coroutine to get concurrent execution with fewer failure modes than normal. Embed sqlite and get a friendly repl over your database. Find some utility written in lua and it's similarly easy to embed. I replaced python with it for misc code generator and admin tasks for that reason. Instead of whatever pip is called these days and global installation conflict nonsense, I can clone a single .c from github that contains lua and all the libraries I've found useful so far. Mostly it just gets out of your way. Compiler feedback isn't wonderful when you get something wrong but it's adequate. Some conventions are a bit weird but it's fine. Lexical closures, garbage collection and native coroutines make up for them.
- bcrosby95 4y agoI look at it from the opposite angle. I want a language that starts as simple and powerful, with simple and easy to use building blocks, that then builds simple abstractions on top of them, ideally allowing me to too. I'm tired of languages that start simple and weak, then bolt shit after shit on top until you need a phd in FuckedLanguage before you can really understand how to use it. If you're constantly surprised by undiscoverable expressivity features in your language, this is a good a sign your language is, at its core, both weak and complex - a hilarious combination that most languages are rapidly chasing to keep the "modern" label.
- dietrichepp 4y agoMy sense is that the simple building blocks are more trouble than they’re worth. The main example I look at is call/cc in Scheme. It’s simple, it’s elegant, and it can be used to build all sorts of things like exceptions, coroutines, and backtracking. However, if you build all sorts of abstractions with it, the abstractions will interact with each other in unexpected ways. It also “contaminates” your library code and makes it hard to write certain higher-order functions—if your library function is not a leaf function, it might call call/cc, and call/cc might return multiple times. I’d say call/cc is powerful like dynamite is powerful. I don’t want it in my toolbox.
- ashton314 4y agoThere’s a good talk called “ Constraints liberate, liberties constrain” https://youtu.be/GqmsQeSzMdw https://youtu.be/GqmsQeSzMdw
- hooby 4y agoI'm not sure "powerful" is the right term. What actually seems to be needed is more consistency in usage. Opinionated conventions on how to properly use something. I don't think it's a problem of a language to be universal and generic and usable in many different ways and usage scenarios. But a project probably should not randomly mix and match all available language features - but follow a best practice approach that makes sense for the project. Constrain itself to a certain subset of language features. The language still can offer features that aren't used for this project - but might be useful for another project. It can't be the job of the language to stop programmers from using (or abusing) any language features. Use things inappropriately, or use stuff that isn't a good fit for the problem it's used to solve. There's always going to be multiple different ways to implement something, and it has to be the responsibility of the programmer, to choose a solution that's a good fit. Trying to make it impossible to use any non-optimal approach on a language level, isn't going to ever work out. No matter how restricted and patronizing you make your language - there's always gonna be some programmer who uses something inappropriately, and then blames the language for it.
- BulgarianIdiot 4y agoIf I never hear the word "opinionated" again in the context of software engineering, ever in my life, that'd be nice.
- hooby 4y ago@BulgarianIdiot It is a (more or less) technical term that carries a (more or less) specific meaning with regards to software design. See: * https://stackoverflow.com/questions/802050/what-is-opinionated-software https://stackoverflow.com/questions/802050/what-is-opinionat... * https://softwareengineering.stackexchange.com/questions/12182/what-does-opinionated-software-really-mean https://softwareengineering.stackexchange.com/questions/1218...
- BulgarianIdiot 4y agoBelieve me, I know what it means. And it's not a technical term, but a MARKETING term. An obnoxious and misleading one. So, I know for example the sentence after you said it contradicts it: "generic and usable in many different ways and usage scenarios". I know DHH first used it, and he named his product "on Rails" precisely because he wanted to make non-developers and beginners feel empowered that they're in the driving seat, while actually not driving at all and running on rails. Opinionated software is training wheels (or rails). It can't be flexible or general purpose. It constrains you, so that when you don't know what you're doing, you still end up doing something. Children love this, and non-professionals also love it. Experienced professional developers hate it. It's not fun for professional developers to be told what to do, because they're in the business of they telling computers what to do. And they know libraries can be easy to use and flexible without being "opinionated". DSLs have their place. But they're not general purpose, it's a contradiction. And I don't like the term "opinionated" because aside from the smug arrogance with which it's often said around the RoR community, it lies about what it is. It's not "opinionated" - every software is created with opinion, it's impossible for it not to have one. But what the term really means is "constrained". This would suck for marketing though, and DHH is great at marketing, so he came up with that BS instead. PS: let me also remind you what this word means as an English word: "characterized by conceited assertiveness and dogmatism."
- goto11 4y agoThe web became successful because of the constrained formats of URL's, HTTP and HTML. This allowed linking between uncoordinated parties and it allowed indexing and searching. In contrast, powerful executable "black box" objects have been suggested as a better alternative to the constraints of the web, and Java applets and MS Silverlight were implementations of this idea. But they never solved the basic problems if linking and searching. Even JavaScript-heavy sites have trouble with supporting indexing.
- mejutoco 4y agoIn a way, type-systems are less powerful non-turing-complete languages that are guaranteed to halt, thus can be checked at compile-time. I think we need powerful but easy-to-restrict languages. Can you mark that function as pure, as not safe? that kind of thing.