16 ms·
What else are we getting wrong about programming languages?
- prmph 10y agoI'm looking forward to an extremely-typed language, where in addition to the usual types, more specific types can be defined with regex expressions, sub-ranges, even function-based rules, etc. Such extra-strong typing would lead to much more robust program and reduce complexity of testing
- raiph 10y agoPerl 6 supports arbitrary run-time predicates as "subset" types: subset Foo where /foo/; subset Bar where 0 .. 99; subset Baz where * > rand; my Foo \foovar = 'Some food'; my Bar \barvar = 42; my Baz \bazvar = 0.5; # Fails typecheck half the time
- glangdale 10y agoThis is a very good article. I do like Yaron Minsky's line, dismissing generally programming-student-based studies rather evocatively: "there is no pile of sophomores high enough to prove anything". That being said, the idea that a programming language is a user interface and might be primarily evaluated like one, rather than a cult object to be venerated, is intriguing. If half the effort that has been put into ever-more-esoteric type theory had been put into serious long-term studies (perhaps with non-sophomore populations?) of usability, we might know rather more and might be able to design better languages. My suspicion is that very few researchers would be willing to follow UI-driven PL research wherever it leads; at best it might skewer some sacred concepts, at worst it might lead to a bunch of inconclusive statistical hints. Far better to stick a bone through your beard and declare your chosen flavor of { functional programming, type theory, OO, logic programming, ... } the winner.
- pmontra 10y agoThe usability of programming languages is important. Look at how Elixir became popular by adding a Ruby like syntactic sugar on the top of Erlang. I can't find the source but Matz said that when he was in doubt about the most easy to understand way to design some Ruby syntax, he asked his little daughter to make a choice. When I look at some other languages I'm pretty sure nobody performed any kind of usability tests on them. It's a pity because there are languages stuck within the same community of users that used those languages parents and grandparents and can't break out into the mainstream.
- deleted 10y ago[deleted]
- programminggeek 10y agoHere is one thing we get very wrong. Programming is a communication tool to describe communication systems. If you were to design a tool to design/build communication systems, it wouldn't look like what we program with.
- cndkxjsnf 10y agoDo you want to invest your time worrying about types or actually programming? My issue with building these type-theoretic monstrosities is that now you suddenly have to tackle two problems instead of just one. Just like the underlying machine code is hidden in modern languages, types should be totally abstracted away when programming in a high level language.
- cbanek 10y agoOn the other hand, do you want your code to have to deal with any object or type from anywhere in the world or actually programming? Programming is inherently the art of making something specific to a use. Types help that in that you limit what the code operates on, which makes the code you write simpler, because you have less ambiguity.
- tines 10y agoIn my opinion, you've got the order wrong: types are the abstraction, and untyped-ness is the concrete implementation (just look at almost all assembly languages). > Do you want to invest your time worrying about types or actually programming? Another order reversal: type systems allow you to focus on programming, instead of hunting around for bugs because somebody 50 levels up the call stack passed you a value that doesn't support the interface it needs to support. This is an endless debate of course, just wanted to throw in a typed pl fan's opinion in the mix.
- cndkxjsnf 10y ago>Another order reversal: type systems allow you to focus on programming, instead of hunting around for bugs Except that is false. Bug prevalence is empirically orthogonal to type system. See Xmonad
- tines 10y agoBut this is in deployment software, i.e. I interpret your assertion as meaning "bug prevalence in software after it has been debugged is the same regardless of type system." My argument is that, at least for me, code becomes bug-free faster with static types than with dynamic, not that it ends up more bug-free in the end.
- cbanek 10y agoI feel like what we are getting wrong is throwing the baby out with the bathwater... repeatedly. Engineers love to engineer things. Why do people invent new languages? Sometimes it's a company trying to do something new, or something hard in a different language. Other times, it's someone who enjoys languages making a new language, thinking they've finally solved all the "hard problems," where "hard problems" is defined as problems they actually care about. If you're not making a programming language, you're probably making a DSL or something on top of another programming language, so now you have the fun and quirks of two languages. Instead, what if we had just a few programming languages, and made them more expressive? We'd avoid problems with language incompatibilities, libraries, and other general impedance mismatches. I chalk this up to a few of factors: 1) Your syntatic sugar is probably not as sweet as you think it is. Many times, people claim something is easier to read or work with when it is merely easier for them, and different for others. This causes confusion for people who aren't used to that syntax. Please stop trying to make boring code look interesting. Boring code is the easiest to work with and fix. 2) Languages are hard, and working on a language is a lot harder than most people think. Once your "brilliant idea for a new language feature" actually gets implemented, the more it does, the more likely it is to screw something up. To quote Scottie: "The more they overthink the plumbing, the easier it is to stop up the drain." 3) Because of #1 and #2, language development for major languages like python and C++ are slow. People hate slow, and so they'd rather build something special for themselves, or try some new language, because it's more fantastical. If this is a project for fun, go for it. But if this is for a business, people always constantly think some new tool is the silver bullet. What actually happens is you end up hunting bugs up and down your stack, lack robust programming tools, and end up keeping up with breaking changes rather than using that new margarita machine.
- pjc50 10y agoThere aren't really all that many popular languages, and adoption is a huge hurdle. I don't think we have too much of a problem of wheel reinvention or syntatic sugar. Rust, for example, is trying genunine innovation in semantics. You also have to face the problem that, once a feature is shipped in a programming language, you can (almost) never remove it. This is why Python2->Python3 is taking so long: it's backwards-incompatible.
- m1sta_ 10y agoConsistency, intuitiveness, error rates, task performance - even if we just heard reference to these four more often things might improve.
- lambdasquirrel 10y agoSometimes, ideas come before their time? How many times has parametric polymorphism been reinvented? Java tried to pretend it wasn't important, and then Go. Python isn't really typed, which allows it to avoid those kinds of mistakes. Having been a Haskell programmer, I would argue that the type system is beautiful and powerful, but still not powerful enough that it's a game changer. And it may never be powerful enough. People forget that the reason we program is to make stuff for other people. Python gets used because it's accessible to the people most connected to the real world problems. The primary in my mind is that there is too much risk involved in transitioning from messy languages to cleaner ones. Much of that isn't just in the language, but e.g. how easy it is to debug and deploy. So I look forward to things like stacktraces for ghc, and for stack to continue maturing. I look forward to more people being comfortable with the language. That all having been said, it's just way too easy to run into the limitsof non-dependently-typed programming in Haskell. So here's another thought, what if string type inference is a dead end?
- cgag 10y agoHaving been a haskell programming I kind of think it's type system is too powerful. I feel like I run into more problems of being unable to figure out all the type-level hackery and abstraction in a Haskell library, than I do of "I wish I could have encoded this bug into my types". edit: disclaimer: hobbyist, never did haskell professionally
- tome 10y ago> I feel like I run into more problems of being unable to figure out all the type-level hackery and abstraction in a Haskell library When you feel like this please file issues on those libraries!
- dnautics 10y agoHave you seen Julia's type system? It is strong, and parametric on types, bitvalues, and tuples thereof. So for example Array{Int32, 2} is a 2-dimensional array of Int32. Types are tied into multiple dispatch; so the properties are defined by the functions created for it. Moreover, JITting is type-dependent; if you call a function with a type signature, it compiles it, unless it's seen that signature before.
- yoodenvranx 10y ago> We should worry, for instance, when Python, a language that breaks all academic language design tenets, is one of the most popular languages in the world. Well, Python has a) an extensive runtime library (e.g. batteries included) and b) you type some text in a file and then you can run your program without dealing with any build system. I'd argue that both of these things might more important for the average programmer than some perfect but esoteric type system. I kinda love the language C++ but I hate dealing with all the hassles surrounding it. Why is it so complicated to include a random C++ library from the internet to my project? Why do i have to redo my build system when I switch platforms? I usually use Python for 99% of my pet projects because it is just so easy to get started. I have some hopes that Rust improves the plumbing situation for low-level programming languages.
- cabalamat 10y ago> Python has a) an extensive runtime library (e.g. batteries included) Which is also decently documented. The importance of good documentation for libraries (and other tools) cannot be over-emphasized. Also, just as important as the standard library are third party libraries.v The advantage of using Python (or other popular languages) is that there is probably already a library for what you want.
- good_gnu 10y agoIf anybody wants an example of how programming languages can be designed with an emphasis on empirical evidence over mathematical proof, take a look at https://quorumlanguage.com/ https://quorumlanguage.com/
- nradov 10y agoOne big mistake we keep making is drawing a false distinction between static versus dynamic typing and treating it as all or nothing. Type systems should be scalable, in that programmers should be able to specify as much or as little type information as they want. For example, a variable could be declared with any of the following types. 1. A value. 2. A number. 3. A floating point number. 4. A floating point number between 0.0 and 100.0. 5. A floating point number between 0.0 and 100.0, and optimize for runtime performance instead of precision. Etc. That way you could start with something quick and dirty for a prototype and then gradually lock it down through progressive iterations. Ada and Microsoft Visual Basic incorporate some elements of this concept but didn't take it far enough.
- JBiserkov 10y agoI agree. Have you seen Clojure spec? http://clojure.org/guides/spec http://clojure.org/guides/spec
- eu90h 10y agoThere's been a lot of work on racketlang adding a gradual typing system. You can write without types, and when youre ready, refine your code by adding types where necessary.
- err4nt 10y ago> That way you could start with something quick and dirty for a prototype and then gradually lock it down through progressive iterations. Like tightening the bolts. This is a really interesting idea. I could also envision a utility wizard that you could run on a piece of code that could help guide you through making things more specific by asking you questions about the code. Are tools like this out there already? Like if you've defined a string and you run the utility it would ask: “Is this variable a number? Yes/No.” and then change to ensure it's a number in your source?
- ZenoArrow 10y agoI don't know if such tools exist already, but it's conceptually similar to a linter, so perhaps you'll find something like this by investigating linters for languages with optional type annotations (such as Python). EDIT: Found one for you: http://mypy-lang.org/ http://mypy-lang.org/
- dancek 10y ago> A couple of years ago I had breakfast with Guido van Rossum -- he almost left the table when I told him I was an academic PL researcher -- and I was quite impressed with the way he dismissed all mathematical aspects of the study of programming languages but was almost exclusively focussed on "soft" aspects of usability such as concrete syntax. I know next to nothing about academic PL research, but this tells me enough. I know that Haskell is an academic language, and it's a good language. But then Python is a good language too, and it's apparently almost anti-academic! Anyway, the author seems to have good ideas about where programming language research should be directed. Hopefully someone can one day find a great combination of rigor and usability in a language. Until then I'm left wondering which of the 5-10 good languages that I know I should use for a new project (or whether I should learn X this time).
- charlesism 10y agoThere's some wonderful talks by Guido on YouTube. Before Python, he was involved with the ABC language. He discusses in one of his talks, I wish I could remember which, the fact that they conducted a lot of research with users for ABC. The sort of thing where you ask a naive user what they think a command named "join" might do, etc. As a result, Guido has a better idea than many, of how real-world users expect languages to behave.
- ClayFerguson 10y agoNon-typesafeness of javascript is a massive disaster. TypeScript changed my life as a software developer by bringing types to javascript.
- aikah 10y ago> Non-typesafeness of javascript is a massive disaster. TypeScript changed my life as a software developer by bringing types to javascript. Javascript was built for an environment that needs to do everything not to fail, just like HTML. A javascript engine will do everything to save a bad script from yielding an error. Javascript wasn't build with code correctness in mind. In that perspective, the language is a success. I personnally don't like languages that allows the developer to add a string to an integer without yielding a type error. Typescript can help but it is still javascript underneath. And it doesn't correct the libraries you use that are written in Javascript.
- JBiserkov 10y ago>Is any current language 100 times better than FORTRAN for programmer productivity, just as FORTRAN was compared to machine-code programming? Probably not. I beg to differ. A well-designed Lisp, with the power of homoiconity (code-as-data, real macros), immutability by default and a sane model for concurrency. Running on the most optimized virtual machines (JVM, .NET CLR, JavaScript), with the ability to use all of their existing libraries. I'm talking about Clojure. http://clojure.org http://clojure.org http://clojurescript.org http://clojurescript.org
- nradov 10y agoHow productive is a Clojure programmer when the requirement is to write a high -performance application which performs vector operations on large matrices?
- didibus 10y agoYou can be pretty productive. Have a look at core.matrix (https://github.com/mikera/core.matrix https://github.com/mikera/core.matrix) and vectorz.clj (https://github.com/mikera/vectorz-clj https://github.com/mikera/vectorz-clj) libs. They give you almost native speeds. If you need even more performance, checkout neanderthal (https://github.com/uncomplicate/neanderthal https://github.com/uncomplicate/neanderthal) which has a GPU back-end.
- JBiserkov 10y agoMuch more productive than with OpenCL where "Hello World" is 170 lines of code. See http://dragan.rocks/talks/EuroClojure2016/clojure-is-not-afraid-of-the-gpu.html http://dragan.rocks/talks/EuroClojure2016/clojure-is-not-afr... Down/up arrows move you through slides, while left/up arrows move you through sections. Normally, you'd press down-down-down until there are no more slides, and then right to cross to the next section. ESC gives you the bird's view of the structure.
- theaeolist 10y agoNot that I disagree, but do you have any evidence that Clojure is 100x more effective than Fortran?
- Razengan 10y ago> What are we getting very wrong about programming languages? Perhaps it's the fact that languages have always had to accommodate the hardware, rather than the other way around. Why don't we have CPUs and memory controllers with built-in support for type safety and garbage collection etc. on the silicon yet?
- pmontra 10y agoI guess it has to do with this quote from Coders ar Work, from the interview to Fran Allen > Allen: By 1960, we had a long list of amazing languages: Lisp, APL, Fortran, COBOL, Algol 60. These are higher-level than C. We have seriously regressed, since C developed. C has destroyed our ability to advance the state of the art in automatic optimization, automatic parallelization, automatic mapping of a high-level language to the machine. This is one of the reasons compilers are . . . basically not taught much anymore in the colleges and universities. > Seibel: Surely there are still courses on building a compiler? > Allen: Not in lots of schools. It's shocking. there are still conferences going on, and people doing good algorithms, good work, but the payoff for that is, in my opinion, quite minimal. Because languages like C totally overspecify the solution of problems. Those kinds of languages are what is destroying computer science as a study. > Seibel: But most newer languages these days are higher-level than C. Things like Java and C# and Python and Ruby. > Allen: But they still overspecify. My guess is that it is left to the programmer because that was the way C did (no type safety and malloc) and the CPUs were developed to work with C. We're still stuck with that.
- dnautics 10y agoYou don't want to do that. That level of complexity will consume power by requiring more transistors... For something that can be done once, on compile time (instead of each time code is run). Already we have things like microcode translation and out of order execution, which can be thought of as "hardware JITting"... And x86 is running against a power/performance wall. Probably a better solution will be to backend microcode compatibility on our compilers, and then "run once to generate optimized".
- freddref 10y agoEach new language seems to provide diminishing returns from the previous ones if you consider only the language constructs. It appears that everything surrounding the language has more of an impact, how easy it is to get started, how big the community is, how good the package management system is, openness of the language ecosystem. Maybe what we need is more automation and support around the language instead of new languages. Building automated compilation, testing, linting infrastructure could be a way to go.
- lisper 10y agoMy nomination for what we get wrong over and over again: working under the assumption that there is One True Syntax. There isn't. Different syntaxes are suitable for different needs. A single language can support multiple syntaxes if the AST is exposed as a first-class construct. This makes it easy to write new syntactic front-ends. Unfortunately, the only language to date that supports this idea is Lisp, which means that this incredibly powerful idea is conflated in most people's minds with lots of irritating silly parentheses. (One of the reasons for this conflation is that once you start adopting this mindset the parens become a lot less silly and irritating, but that's another story.) I'm currently working on cryptography code, where algebraic syntax is very convenient. Here's an excerpt from some code I'm currently working on: (define-method (point-double (ec elliptic-curve a b c q r) x y) (bb lambda modp(q, (3*x*x + 2*a*x + b)/(2*y)) x3 modp(q, lambda*lambda - a - 2*x) y3 modp(q, lambda*(x-x3)-y) (values x3 y3))) (define-method (point-add (ec elliptic-curve a b c q r) x1 y1 x2 y2) (if (and (= x1 x2) (= y1 y2)) (point-double ec x1 y1) (bb lambda modp(q, (y1-y2)/(x1-x2)) x3 modp(q, lambda*lambda-a-x1-x2) y3 modp(q, lambda*(x1-x3)-y1) (values x3 y3)))) Notice that it looks like Lisp (and it is Lisp) but there's infix code seamlessly embedded. Moreover, the MODP construct automatically converts everything to modular arithmetic operations, so, for example, x/y doesn't actually divide but instead expands into (* x (modular-inverse y p)). But when I code, all I have to do is copy the mathematical formulas more or less verbatim and my compiler takes care of expanding everything out into calculations that use Montgomery reduction or whatever optimizations I want to provide. This approach also has the advantage that I can test the correctness of my protocols completely independently of the correctness of my optimizations.
- err4nt 10y agoHey thanks for taking the time to write this out. I'm new to programming and learning JavaScript, and what you said about exposing the AST and writing new syntaxes for the same language is really intriguing. I try to learn about the history of computer science and I try to understand where languages have come from - and one so far I haven't dabbled with any of the Lisp languages at all. If I was a JS learner curious about Lisp - what's the easiest way for me to get started with some experiments?
- js8 10y ago"But I know of no scientific studies actually backing up the (sometimes implicit) claim that this types-first methodology leads to better languages, from the point of view programmer productivity." So here's my problem, maybe I am using Haskell wrong, and somebody can give a good answer (FYI - I am big fan of Haskell, but I am still much more efficient in Python). Let's say I write a library, I annotate all the functions with types, so I give it a nice API, and then what happens.. I realize I should have used a different type for this parameter in this library. For instance, a type class instead of normal type. But boy, it's like everywhere. Or it's a third party library and I can't really change the type signatures. I just wish sometimes that I could just "forget" the types temporarily and just borrow the existing logic, and then reintroduce different types, type check, done. To be fair, Haskell has potential solution for this type of problem - type inference. But the thing is, once you write the (expected) type signatures into your program (which is sometimes needed to actually help the type inference, and it's also useful as a documentation), they are always there, and sometimes, they obstruct. So I guess I wish there was a tool with which I could manage type information in the program in a lot more dynamic way than I currently do. That would, IMHO, close the gap to the dynamic languages. What about making every type into a type class, would it do the trick? But how would the concrete type be specified, then? Would the compiler pick it? (Maybe it's obvious, but let me point out the connection of this question to lambda calculus. I can have two functions in typed lambda calculus which are different, because they have different type signatures, but their actual semantics is identical (provided they get arguments of correct type); or in other words, if we convert both into untyped lambda calculus, we get identical functions. So the question is, why cannot we somehow reuse code from the first function, why we have to define the same code twice with different type signature?)
- imh 10y agonewtype BusinessLogicThing = BLT Int Then you use the semantic thing instead of the other thing (with no overhead). That can help in some situations.
- clusmore 10y agoSome really interesting points in here. >So I guess I wish there was a tool with which I could manage type information in the program in a lot more dynamic way than I currently do. I write a small amount of Haskell for personal projects and I always use type annotations for top-level definitions for two reasons. 1) I write them in advance because it helps me think about what I'm doing, and 2) I like that the compiler will tell me if I accidentally change the type between successive compilations. If it weren't for the first point though, I can imagine it would be nice to omit the type signatures and then have the compiler not only infer them for me but actually place them into the source code to save itself the trouble next time whilst improving my documentation. If it could do that, the logical next step would be to have another tool to strip out all the type signatures, to give you that design-time dynamic feeling whilst still being very much static at compile time. You can refactor all you want changing signatures and the compiler will put them all back in again when you're done.
- steveklabnik 10y agoRegarding the litte call-out to Rust here, while it's true that we have a strong type system, we also aren't doing very much _innovative_ work on type systems. And in many regards, we're not even that advanced by the standards of Haskell or Idris. The "production-oriented" bit is important as well; we _need_ those features to achieve our goals, the type system features aren't just there because we like type systems. And we've resisted doing so; the most classic example being higher kinded types. People have been asking for years, and they would be useful, but there's a lot of stuff that would also be useful, and we're focusing on them first. We're very wary of adding type system features just because we can.
- theaeolist 10y agoDo you have any evidence that your way of doing systems programming is more effective, for programmer productivity, than the alternatives?
- steveklabnik 10y agoDepends on your standard of evidence; it's not like we have a peer-reviewed study or something. Then again, that's a pretty high bar, almost no language does. Like most languages, we take users' experiences into account. We find that we're more productive, and so do many of our users. And where people don't, we're working on improving it.
- mannykannot 10y agoPerhaps the dogma that needs to be reexamined is the notion that programming languages are the key to improving productivity. Perhaps the key might be found in teaching programming differently, or in better or different tools.
- chenglou 10y agoIs there a programming language/research area dedicated to the transitioning of one library API to the next? For example, I depend on Foo v1, and would like to upgrade to Foo v2. Currently mainstream languages either use a type system to indicate the upgrade was unsuccessful (can't catch everything, and still require the user to patch things), or allow the user to muddle along, knowing things might break subtly but not enough to be "bothersome" (e.g. node ecosystem). So one Foo upgrade is costing O(n) in refactoring cost where n = dependents of Foo. Given enough patience the Foo author could make an adaptor between v1 and v2 to reduce it to O(1) upgrade (inside Foo itself), but this is asking so much that nobody sensibly do it, except for big projects which provide great migration warnings, codemods, bridges, etc. This, combined with, say, plaintext structural sharing/diffing between library versions (so that code size doesn't blow up if you have 5 transitive dependencies on Foo), might solve two important problems of dependency/versioning hell imo, and keep software as fresh as realistically possible. I understand the general version of this is uncomputable, but that's my question: is there research on constraining the expressivity of an language just enough to make version upgrade of a library mostly automatable? Here's an idea: first-class support for fetching the code of a transition between v1 and v2, half-automated by the language & tools, half community-maintained & uploaded to a dedicated place. Alternatively, push as much as possible to data instead of functions, to make writing transition code (which would simply be massaging data from one form to another) much easier, like GraphQL deprecation strategies (https://facebook.github.io/graphql/#sec-Object-Field-deprecation https://facebook.github.io/graphql/#sec-Object-Field-depreca...) Real-life example: two React.js components written under two different React versions naturally don't interoperate. You can't include one inside another. Right now you "can", but this is thanks to sheer human effort from React.js to maintain backward compatibility, so components using React 15 work with components using 14, etc. Same for Java, Windows, and others. The language doesn't help you with that at all. Semi/fully automated version transition/code generation would be a killer language feature.
- Iv 10y agoOver time, I saw one intriguing idea that any person would reject immediately as they shock the sane mind, but that I thought may be worth a bit more consideration: Moving away from a pure text format. If you think about it, a lot of projects already do that: Android projects and Visual Studio projects often include GUI descriptions. Sure, they are XML, technically a text format, but not designed for direct redaction by a human. It is the thing I have realized when, despite a lot of ideological reservations, I started to like Visual C#: a programming language is linked to the way it is used, to its IDE. I wish language designers would embrace that fact, and not assume that the IDE would be a generic text editor. I think that is holding back a lot of possible designs.
- wmwragg 10y agoI think one of the main things we get wrong is that pretty much any language can be used successfully to write a small to medium sized program, it's when a large program is written that things can start to fall apart. Some language features aid large program developement e.g type systems, but can get in the way, or even seem pointless, when writing small programs