4 ms·
Compilier design and programming language design are two very diffierent things. Perhaps someone could even make the argument that a programming language is BE
by robzyb 12y ago
Compilier design and programming language design are two very diffierent things.
Perhaps someone could even make the argument that a programming language is BEST designed by someone who doesn't know how to make a compiler?
The choices for a programming language should purely be based on the language, and on the user experience. In the design phase no thought will be given to compiler design (initially) and all of that will eventually be hiddden as implementaiton details.
- yoklov 12y agoLong compile times are bad user experience, and language design influences this. Performance is also extremely important for language ux, and there are certainly constructs that will prevent your language from ever being efficient. Someone completely unfamiliar with compiler design could easily add these to the language on features that are simply not worth it, even in his or her own eyes. Besides, have you ever looked back on something and said 'Gee, I wish I knew less about this when I started'
- robzyb 12y agoI understand your point. Perhaps I went a bit too gung-ho with my POV. I'd note, though, that long compile times shouldn't be too dependant on language design, should it? I feel that an argument could be made that if a programming language is well defined, then a well written compiler could be well thought out and designed around it. Of course, I'm sure that there are counterpoints. I'm sure that there are languages for which it is very difficult to write a "fast" compiled. > Besides, have you ever looked back on something and said 'Gee, I wish I knew less about this when I started' Actually, I kind of have. Experts (for lack of a better term) sometimes make their solutions more complicated than they need to be, and this is partly because they have the knowledge to do that.
- pjc50 12y agoC and C++'s system of macros by textual inclusion and approach to "compilation units" means that virtually all large C++ projects end up having multi-hour compile times.
- userbinator 12y agoExperts (for lack of a better term) sometimes make their solutions more complicated than they need to be, and this is partly because they have the knowledge to do that. I think that's caused by a slightly different effect - not considering essential and incidental complexity. It is true that for some programmers, the urge to put in as many things as they know tends to override the more basic goal of solving the problem in the most direct way.
- dmytrish 12y agoIt's not only compile time that matters: an overcomplicated language grammar/specification hinders development of language infrastructure (static analyses tools, linters, debuggers, parsers/code generators, IDE interaction, etc).
- shiro 12y agoWhen you design something concrete, you have to make choices on lots of things that you don't really care at that time, but the choice may haunt you later. I think your point is that too much knowledge may hinder your view. That's certainly something you should watch; but in general, I think risk of making bad decision from ignorance is greater.
- vidarh 12y agoThat's how you end up with languages that are near impossible to compile efficiently.
- 59nadir 12y agoIf a language feature is sufficiently good I'll take a X-fold increase in compile time. There really is no win in placing compile time before ease of use.
- sanxiyn 12y agoIn theory, implementation simplicity is a rather low priority concern. In practice, it is very important. This was the point of "Worse is Better" article. http://www.jwz.org/doc/worse-is-better.html http://www.jwz.org/doc/worse-is-better.html
- vidarh 12y agoIt wasn't clear, but it's not compile time I'm talking about, but runtime efficiency.
- 59nadir 12y agoAh, yes, then it becomes a question of real tradeoffs, I guess. There are a lot of domains in which I will happily trade a reasonable amount of performance for nice language feature, though.
- vidarh 12y agoThat's true. My favourite language is Ruby. Which is an exercise in how to frustrate a compiler writer (in a sign of deep seated masochism, I'm working on a ahead-of-time compiler for Ruby), and much of it certainly is a result of providing nice features. But many of the worst offenders in such languages also have little to do with "nice features" and more to do with not thinking about compilation. E.g. one of the big issues with compiling Ruby is that classes can generally be re-opened at any time. It's an awesome feature for a lot of things. But it also makes it incredibly hard to formally reason about Ruby code. What does "1+1" mean? You can't know without knowing whether or not someone has overridden Fixnum#+. And that can happen anywhere. So even if you know that 1+1 is 2 now, after the next method call, you don't know any more unless you've determined exactly what the intervening method call was, and traced everything it might have called. Oh, and you need to take into account threading. Executing 1+1 in a tight loop, expecting it to mean the same on every iteration? Can't safely do that, as someone might be randomly redefining methods in another thread. Even if you determine that that can't happen now, if anyone ever calls eval() on data you can't statically determine (or its cousins such as "require"), you're back to square one. Of course 99% of the time nobody has a sane reason to do that, and the 1% (or more like 0.001%) when it happens, it's almost always because someone is proving a point, and nobody would care about breaking the proving-a-point cases. Outlawing overriding methods of the basic system classes, or even "just" specifying a subset of basic methods that the implementations should treat as immutable would make optimising Ruby code immensely much easier with very little practical impact. (Ruby has the woefully underused "freeze" but that applies only to objects; a method-level "freeze" or "final" carefully applied to a few dozen rarely-if-ever methods would make a lot of difference; it'd even be fine to supply a way of overriding it, as at least then you'd be signalling clearly that you're about to do something that requires disabling certain optimisations). Providing restricted versions of "eval" (so you can provide guarantees about what will still be the same after eval), and the same for "require" would also make a huge difference (e.g. if I had a way of loading new code and being sure that it only defined new classes rather than modifying existing classes, I would be able to aggressively inline a lot of things in situations where I could determine types statically; without it, I can still do inlining but needs to do a lot of work to verify when changes have occurred and potentially fall back on a much slower path, which seriously increase the complexity and reduces the benefit of inlining) The strength of language designs coming from people who are experienced at writing compilers is that you rarely see those kind of situations, because the first thing a compiler writer would tend to want to do would be to declare a lot of corner cases like the above as "undefined behaviour" at a minimum, and proceed to implement optimisations that would utterly break it. While Ruby is my favourite language, my favourite influence when it comes to writing compilers is Niklaus Wirth, who from his first language work on successors to ALGOL-60 has consistently been working to reduce the complexity of his languages with each iteration (he has usually removed more than he has added in each new language). One might very well believe Wirth is too much of a purist, but while his languages tended towards the minimal, his overall principle is worth considering: He only wanted to retain functionality in his languages with proven benefit and that he understood how to implement efficiently. A lot of languages could benefit from extensive pruning of functionality on that basis. (Incidentally, for my Ruby compiler if/when I finally get to the stage when these things matters, I do intend to deviate from Ruby and declare a whole lot of things that people don't generally ever do but that should technically work as "undefined behaviour unless you specify the --generate-horribly-slow-but-compatible-code switch or something to that effect)
- soup10 12y agoI disagree. Programming is creating an efficient man->machine interface. All abstractions are leaky, the best programming languages balance control with convenience. There is a cost and benefit for every design decision. Disregarding implementation often imposes drastic hidden costs that only become apparent as programs grow in complexity and requirements. Twitter had to change to java, reddit had to change from lisp to python(and still has performance issues constantly), facebook had to write a php compiler, minecraft had to write a C++ version... There's no free lunch.