6 ms·
Despite the positive tone, what really struck me in this article was that they struggle with getting people to work on the compiler because it is too complex.
by socialdemocrat 7y ago
Despite the positive tone, what really struck me in this article was that they struggle with getting people to work on the compiler because it is too complex.
It just confirms my main criticism against advance statically typed languages: They are simply too complex.
It is why I have more faith in languages like Julia, because you can achieve a tremendous amounts of power, expressiveness and performance in a relatively simple language.
Dynamic typing gives you simplicity in the type system which is impossible to achieve with static type checking.
Long term this has profound implications. People can keep hacking on and expanding Julia because they can wrap their head around the language. You don't need to be Einstein to grok it.
I think you may also see Clojure overtake Scala for the same reason. The simplicity of Clojure may in the long run overtake Scala although Scala benefits a lot from similarity to Java at a superficial level.
- adrianN 7y agoMost compilers are very complex because generating performant code on modern hardware is hard. I don't think the complexity of the type system make much of a difference. Of course many new languages (like Julia) outsource a large part of the complexity to LLVM.
- socialdemocrat 7y agoI completely disagree. The experience with Julia points in a different direction. Julia performance has has little to do with LLVM. If performance was that easy, you could just slap LLVM in the back of any dynamic language and poff by magic you have super performance. Most dynamic languages that have reached decent performance have done so using trace-JIT compilers. These are complex and require a lot of man hours to make. PyPy is a similar approach. It is hard problem to solve. Yet Julia spending considerably less man hours than either project and with smaller and simpler code base has managed to run circles around these two projects in terms of performance. Why? Because of smart language design. The pervasive multiple-dispatch design tailored towards JIT code generation has been key. It allowed Julia to get great performance with a very simple method-JIT compiler. These are much easier to make than trace-JIT compilers. But Julia is not alone. Go is another example of a language which kicks above its weight. It is a relatively simple implementation, yet has good performance and is enjoyable for most people to work with. Except those who really hate Go of course ;-) My bottom line is: LANGUAGE DESIGN MATTERS!!! You you design a smart and simple language you can get away with simple implementations and still get good performance. Sure LLVM is an important piece of the puzzle, but it serves no more important role than C does as the backend for Haskell IMHO.
- josch 7y ago"pervasive multiple-dispatch design tailored towards JIT code generation" sounds interesting. What is the relationship between the two?
- pansa 7y agoJulia is built around multiple dispatch - when making a call, the method to execute is chosen based on the run-time types of all of the arguments. Once this choice has been made, Julia compiles the method, specialised for the exact types of the arguments. So, the dispatch process and the JIT compiler are linked - both are reliant on type information every time a function is called. This specialisation is the only way the Julia JIT uses runtime type information. Unlike JavaScript JITs, Julia does not track things like the types of local variables during execution (although it may do some static inference). Therefore type annotations for local variables can improve performance.
- StefanKarpinski 7y agoMostly spot on, although it's very rare for local variables to require type annotation—type inference can easily figure it out for locals. Unless, of course, they are assigned from an untyped external source the compiler couldn't possibly know. You could, for example read something from a JSON source knowing that it should be an number, annotate it with `json["field"]::Float64` and then the compiler will emit code to check the type and throw an error unless the type is actually a Float64.
- pansa2 7y agoThanks for the reply - I wasn’t sure what Julia did in terms of type inference. So, if not on local variables, where are explicit types necessary (other than function parameters)?
- ChrisRackauckas 7y agoYou actually don't need explicit types in function parameters unless you're trying to control dispatching. Otherwise the compiler will auto-specialize on call. This blog post might be a better explanation on when it's necessary: https://www.stochasticlifestyle.com/type-dispatch-design-post-object-oriented-programming-julia/ https://www.stochasticlifestyle.com/type-dispatch-design-pos...
- noelwelsh 7y agoI don't think that the type systems are too complex. I think the issue is that approximately zero effort (perhaps even negative effort) has been put into the UX of the type system. We have tools for debugging run-time errors, such as debuggers and tracing. When you shift errors from run-time to compile-time, as type systems do, you need similar tools to debug and inspect type checking. Very little work has been done here.
- socialdemocrat 7y agoThat is why dynamic languages shine. Because types are objects like any other object you can use the same tools to deal with types as other code. It is one of the reasons why meta programming tends to be much harder to achieve in statically typed languages.
- noelwelsh 7y ago(What you call types are not what those who work in programming language theory call types. I disagree but this is an old and well worn argument and I'm not really interested in revisiting it.)
- socialdemocrat 7y agoThere is your problem right there. These static type gurus live in an alternative universe in ivory towers far removed from where the rest of us simpleton programmers live. Frankly I think it is an intellectual cargo cult. For all its sophistication these languages have not delivered that much. Look at language like Go, which these guys would laugh their butt off. Yet Go has produced usable software for a lot more people and made a lot more developers happy than Haskell ever could. Coming years after Haskell Julia seems to be doing a lot more for science than Haskell has ever managed to achieve.
- noelwelsh 7y agoWell allow me to climb down from my ivory tower and offer the following in way of explanation: Here is a reasonably good overview of safety (aka dynamic typing) vs types: https://papl.cs.brown.edu/2018/safety-soundness.html https://papl.cs.brown.edu/2018/safety-soundness.html Put another way, the standard programming language theory is that types are constraints that are uncovered (via type inference) and checked at compile-time. If type information is found at run-time these are known as tags. In Haskell, for example, you can declare a type like newtype SecretKey = Int This creates a new type (SecretKey) that has a run-time representation that is just an Int. I.e. it has no additional information associated with it at run-time that you could use to distinguish it from an Int. At compile-time it is distinguished, however. You cannot use a SecretKey where an Int is expected and vice-versa. This could prevent you leaking secrets to other parts of your program, for example. This is one way you can reclaim performance in a statically typed language, vs dynamic types, without degenerating to passing around uninformative primitive types like Int (which introduces the possibility for errors).
- Random_ernest 7y ago> I think you may also see Clojure overtake Scala for the same reason. The simplicity of Clojure may in the long run overtake Scala although Scala benefits a lot from similarity to Java at a superficial level. Correct me if I'm wrong, but didn't Scala overtake Clojure some years ago as the second most popular language on the JVM (second to Java ofc). From my point of view it rarely happens that these trends reverse. Scala has the advantage that it allows OOP or Functional Programming, which Clojure does not. But I do get your point about simplicity. I tried 3 times to learn functional programming by learning Haskell and it never clicked. Then I learned Clojure and who would have thought, functional programming is actually not as hard as Haskell makes it out to be.
- socialdemocrat 7y agoI don't keep up with Scala and Clojure that much since I am not a JVM guy but I was always under the impression that Scala being older has ALWAYS had a lead on Clojure. However the Scala hype seems to have died down years ago while you see more enthusiasm around Clojure. > I tried 3 times to learn functional programming by learning Haskell and it never clicked. LISP (Racket) and Julia helped me most with functional programming. For Haskell type of functional programming I think Swift actually helped me most. But I find many of the same problems with Swift as with Haskell. Understanding type mistakes can be really hard. You struggle much longer with figuring out type problems than you would in a dynamic language. I think advocates of these super statically typed languages completely overestimate the complexity the average human mind is capable of dealing with. Perhaps because the creators are super smart themselves ;-)
- Random_ernest 7y ago> I think advocates of these super statically typed languages completely overestimate the complexity the average human mind is capable of dealing with. Perhaps because the creators are super smart themselves ;-) That is a really good point. From my personal pov languages that take to long to understand and take you >1 week to get productive are rarely useful since you won't be able to afford or train "normal" people to use it. In my company we recently switched from Python + Numba to Python and Clojure. Since even though people never heard of functional programming or Clojure, they can get started on simple things within the first week.
- kryptiskt 7y agoCompilers are wonderful to implement in a statically typed language with algebraic types and pattern matching, every pass can be a function transforming this intermediate language to that intermediate language until you emit the target code. The only thing that comes close in dynamically typed languages is the Nanopass framework used in Chez Scheme. GHC development has a far lower bus factor now than when it just consisted of a handful of Simons. Compare to Clojure that has everything needing to go through one guy. Julia is irrelevant, it is implemented in C++. All the real work is done in LLVM, which is a tremendously complex heap of C++, far more intimidating than GHC.
- socialdemocrat 7y agoSay Julia is all LLVM is like saying Haskell is all C code because that is what it outputs. That is simply a fantastically ignorant statement. If LLVM was what mattered every dynamic language would have slapped it in the back. I am sorry but it just isn't that simple.
- kryptiskt 7y agoLLVM isn't all that matters, but Julia is built on 4 million lines of statically typed code, so maybe tone down your dynamic typing boosting a bit?
- socialdemocrat 7y agoHow did you arrive at that number? Quite a lot of ways one could count that. Anyway I have never claimed statically typed languages are irrelevant or not useful. My criticism is of advance statically typed languages. I am quite okay with stuff like Go, C and maybe Ada and Swift. I am highly critical of C++. Far too complex language. With Haskell my criticism is different. It seems like an elegant language you can learn a lot from. However I criticize the prevalent belief that Haskell is some sort of programming Nirvana. That somehow it is the ultimate language. I think Haskell is grossly overrated. It is too complex at a theoretical level for the average programmer. When we also learn the implementation is complex.... well then I am not sure there is much hope for that language. Sure keep it in academia. People learn lots of useful stuff from it. But don't kid yourself into thinking world dominance is right around the corner.
- cinnamonheart 7y agoGHC was released in 1992 and has a large amount of language options it supports (over 100 now, I think) https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#language-options https://downloads.haskell.org/~ghc/latest/docs/html/users_gu... I don't think the issue here is due to static typing, but due to the age and complexity of the language implementation. It's not trivial to figure out how all of those extensions interact with each other and your changes.
- G4BB3R 7y agoScala and Haskell are complex because it's creators wanted that way, not because they are typed FP. Take a look at Elm, it's very simple and clean syntax.
- eklavya 7y agoYeah, it’s not like they created a much much more feature rich language and solved really hard problems.
- tsss 7y agoYou can get literally the same "simplicity" as a "dynamically typed" language through structural row-polymorphic types with type inference, i.e. static duck typing. Not to mention that the concepts of static and dynamic typing are orthogonal and there are languages that have both or neither. You have no clue what you're talking about.
- socialdemocrat 7y agoBefore calling somebody clueless you have to understand the point they are actually making. I don't have the space to go into details in this comment. But you can read a more detailed explanation of what sort of simplicity I am talking about here: https://medium.com/@Jernfrost/the-many-advantages-of-dynamic-languages-267d08f4c7 https://medium.com/@Jernfrost/the-many-advantages-of-dynamic... It is not just about the simplicity of implementation but also about the simplicity you can create in your whole development environment and process. > You can get literally the same "simplicity" as a "dynamically typed" language through structural row-polymorphic types with type inference If you believe that, then I am sure you can point me to a language that does exactly this and let me try learning it myself and make up my own mind whether it is simple or not.
- IceDane 7y agoThat is an absolutely awful article. Example: > The same problem as before repeats itself. Complexity grows to a point that we yet again need a real language to do the job. A script language which allows us to write some code that explains how e.g. our C++ values should show up in the debugger. Not to mention that debuggers for statically typed languages themselves tend to grow into complex behemoths with a dizzying array of functionality to deal with the complexities of statically typed languages. This is just blatant nonsense and the author of the article clearly has no idea what a powerful static type system is capable of. If you want to get a feel for what structural typing can give you, you don't need to look further than TypeScript. If you want proper row polymorphism, you can try PureScript.
- socialdemocrat 7y ago
- the_af 7y ago> It just confirms my main criticism against advance statically typed languages: They are simply too complex. But this is about the complexity of the compiler itself, not of general software written in Haskell. For any given language, most people use the language and don't hack the compiler. The compiler of any given language can be complex for plenty of reasons, many historical and unrelated to the programming language itself.
- hopia 7y agoHaskell's compiler is already big and fat, having a very wide range of features. I don't think Haskell's extensibility is a problem in terms of adoption at this point, the problems lie elsewhere. Therefore, simplifying GHC development likely wouldn't attract any larger user base for the language. > Dynamic typing gives you simplicity in the type system Can you elaborate on this? Dynamically typed languages essentially have no type system (but yes even they do have types).
- socialdemocrat 7y ago> Therefore, simplifying GHC development likely wouldn't attract any larger user base for the language. I can agree with that. What I meant was more that I see it as a sort of symptom of its complexity. A kind of complexity which causes problems elsewhere. > Can you elaborate on this? Dynamically typed languages essentially have no type system (but yes even they do have types). Of course they have a type system. You define types and the types of values determine what you can do with them. That is not different from static typing. It is just that the enforcement happens at runtime. One example of complexity in static typing is what you get when you try to do any kind of meta programming such as templates or generics. Perhaps the easiest way to illustrate the problem is to look at the terra language. http://terralang.org http://terralang.org In terra you see Lua serving the same job as the templating language in C++. Yet a typical templating language is very limiting compared to a full blown dynamic language. With static typing you just very easily end up in a catch-22 situation: What are the types of the types of the types? For instance in Julia I can write: A = Int B = Char c = 10 bar(name::String) = println("Hello ", name) foo(x::(c < 10 ? A : B)) = 2+x - 10 Which is kind of complete nonsense code, but it illustrates a few different things which I can trivially do in a dynamic language like Julia but which would be hard in a static language. Here I am storing types in the variables A and B. Then I define a function `foo` which has a specific implementation depending on the type of its single input argument `x`. In `bar` I specify the type of `name` as String. However in `foo` the type of `x` is evaluated at runtime. When the function definition of `foo` get evaluated, only then do we decide what the type of `x` is. Here an if statement is used to determine the type of `x`. However I have the availability of the full Julia language to make that decision. I can make multiple functions to do that. Try something like that in a statically typed language and the type system will tie itself in knots. If you could even support this in a static language, the complexity of describing what I just did in a static language would make most software developers dizzy.
- darksaints 7y agoScala is still growing, and it has been doing so (albeit slowly) from the very beginning. Clojure was very trendy for a while and grew really quickly, but it peaked around 2015 and is mostly dead now. The idea that clojure will supercede scala in the future is completely lost to reality.
- lonelappde 7y ago> power, expressiveness and performance Static languages are static because static provides opportunities for correctness, not on your list.