28 ms·
OCaml is Pretty Great (2019)
- jchw 6y agoInteresting but I find myself confused. There is not really much discussion about what kinds of implications these metrics might have in practice and what the limitations of this analysis are. Obviously the goals of programming languages vary, and outside of esoteric languages few really strive to be very terse. It seems at least a bit odd to me , then, to make value judgements based on this. Hate to be a wet towel, since it is interesting. But does it actually mean anything?
- apk-d 6y agoWhen it comes to picking criteria to compare languages with, performance and succinctness have the advantage of definitely having a large impact on developer productivity/happiness (same thing tbh) while being (relatively) easily measurable. Having recently jumped ship to a language/runtime that gives up to several orders of magnitude of performance speedup while maintaining similar verbosity, I appreciate the many opportunities this opens. I can write "lazy" code that pretty much always runs (way) faster than the stuff I used to carefully optimize. Perhaps the last metric I'd be interested in is the a number of bugs in the average codebase, and while I've seen language comparisons for that, I'm not sure whether to believe that they're accurate.
- deleted 6y ago[deleted]
- kumarvvr 6y agoGo and Rust are harder to pick up. With weird operators and syntax. Maybe I am getting old, losing my edge or python has spoilt me. Even C# is elegant compared to those two. I tried to learn both of them, but they just didnt excite me as much as C# or Python.
- dgellow 6y agoWhat weird operators and syntax do you have in Go? I'm asking because I feel the exact opposite. Someone who already knows a bit of a language with C-like syntax can pick it up very quickly.
- kumarvvr 6y agoFor Go: 1. Exports from packages are to be defined with a Capital letter. To me, that is very hard to read. An explicit export statement is way better, if verbose. 2. Type declarations after variable (x int, y int), to me personally, is hard to read. Now I know a lot of people are fine with it, so this is a personal thing for me. 3. Multiple return values syntax is terrible. func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return } In this function, the sum is the input and x & y are outputs. The syntax seems weird to be. This also is a personal gripe. 4. Variable declarations can be var i, j int = 1,2 AND k:= 3 with implicit typing. To me this is a bad design, with various programmers choosing different methods to declare and initialize. Leads to a lot of cognitive overhead to read code, especially on large open source projects. Why not make it explicit to declare types? Sure, it's a bit of more work for the programmer, but in the long run, that bit of more initial work will save a lot of downstream confusion and frustrations. 5. Constants cannot be declared using := syntax. I am sure there is a valid reason for it, but assignment in the language for now is = , := and those can and cannot be used in various places. That is confusing. 6. For loop has no parenthesis for the loop initialization but needs {} for the loop blocks. This is really stupid. Personally, for(i:=0,i<100;i++) {} is a concise syntax and looks pleasing and readable. 7. To complicate it further the initialization and post statements are optional // This is a valid for loop in Go sum := 1 for ; sum<1000; { sum = sum + 1 } Isn't that confusing in itself. Sure, we don't have to write a loop that way, but some junior developer is going to write it anyway, and it muddles up the code for sure. 8. From the official Go Docs "At that point you can drop the semicolons: C's while is spelled for in Go" // This is a ALSO valid for loop in Go sum := 1 for sum<1000 { sum = sum + 1 } yay. 9. And then there is this gem in the "if" statement. if v := math.Pow(x, n); v < lim { return v } Yes, you can write an optional initial statement before the if condition. All this for what? So you save one extra line in the code? Sorry, the beards got too long and too tangled up for whoever came up with this idea. 10. Also, the initial statement you saw just after the if statement, the variable "v" is available in the scope of else/if and else statement blocks. But not outside the if/else scope. Yay, another way to confuse code readers. 10. What is up with the defer keyword to defer function calls until the "surrounding function returns". There are many more, but I think I have made it clear why, personally, Go is off putting. edit : Changed format a bit.
- ahartmetz 6y agoRust has a similar "problem" as C++: it wants to be high level (for productivity) and close to the metal (for performance). Such languages are needed, but they are not going to be the easiest to learn. It is not their fault.
- m0xte 6y agoThere has to be a simpler solution than Rust though. Rust seems to have started with some clear objectives but evolved into a nightmare. We should be putting the effort into the compilers and keeping the language free of cruft and any unsafe concerns. Much like Delphi did for example.
- rwmj 6y agoFor most, average userspace programs garbage collectors work very well. (Of course there are exceptional cases as I'm sure people will be quick to point out.) However if you deny garbage collection for all programs you have to replace it with something very complex to reason about, like RAII for C++ or borrow checking in Rust. Or you end up reimplementing GC inefficiently (C++ reference counting). Also certain algorithms -- persistent data structures with shared subgraphs and therefore cheap updates -- become very difficult to write because there's no local ownership of nodes, only something with a global program view (a GC) knows when an object is unreferenced and can be freed.
- foldr 6y agoThis. The Rust community seem to be pushing Rust as a more-or-less general purpose programming language. But giving up garbage collection never makes sense unless you have to. The applications where you really can't use GC are a tiny niche relative to the ones where you can.
- StreamBright 6y ago>> The applications where you really can't use GC are a tiny niche relative to the ones where you can. And this is one space Rust is targeting explicitly. Why would people replace Go with Rust for performance reasons otherwise? https://blog.discord.com/why-discord-is-switching-from-go-to-rust-a190bbca2b1f https://blog.discord.com/why-discord-is-switching-from-go-to...
- m0xte 6y agoSimilar opinion. The only two things I consider worthy at this point are C and Python. Everything else seems to have lost the balance of compromise, stability, low API and language volatility, the ability to retain it and it's API in mind effectively and tool flexibility. On the Go front I have to say I like the language but not the rigidity which quite frankly gets in the way a lot of the time and turns minor experiments and refactoring into a time consuming nightmare. On the C# front, I've been writing C# since before the compile toolchain was even RTM and I dislike every moment now. It has become a bloated mess of a language and the supporting frameworks are impossible to keep track of and up to date. Edit: I prefer SBCL over everything really but that's another universe :)
- amedvednikov 6y ago> On the Go front I have to say I like the language but not the rigidity which quite frankly gets in the way a lot of the time and turns minor experiments and refactoring into a time consuming nightmare. Can you give an example of this?
- fluffything 6y agoHave you tried C++? Rust is an alternative to C++ or C, not to Go, C# or Python. Sure, you can write any program on any language, but if you try to write bare metal C code from C# or Python, your frustration will be quite large as well. Use the right tool for the job.
- kumarvvr 6y agoI have used C++. I understand about using the right tool for the job. But Rust and Go are not good tools solely due to their syntax.
- dragonsh 6y agoJust a minor correction, Rust is trying to be replacement of C++. It will be unlikely to replace C, at least for next 2-3 decades. C will serve as the low level language and Rust will be a higher level language. Today Rust needs LLVM (written in C++), to generate binaries and it may be 2-3 decades before Rust will be used to write anything like LLVM with supporting platforms. Today Rust library to do anything useful rely on unsafe integration with underlying C code. Rust is still on fringes and quite a complicated language compared to C. I still doubt it will be a replacement for either, may be it will go-exist with C/C++ on fringes and may be in next 30 years if it survives like Python might have significant code and can be useful in place of C++.
- pjmlp 6y agoNo language will replace C on its turf, FOSS UNIX clones and embedded POSIX RTOS. Everywhere else C has been being replaced a good part of the last two decades, even all major C compilers are written in C++. As for Rust, yes a co-existence is more likely.
- jstimpfle 6y ago> Everywhere else C has been being replaced a good part of the last two decades, even all major C compilers are written in C++. You keep saying this, but I'd recommend you to look at a few random "C++" files in https://github.com/gcc-mirror/ https://github.com/gcc-mirror/ for example. For many of these projects, "moving to C++" often means to change the file extension. Or not even that, sometimes it's just changing the build setting to "Compile as C++". There's no reason for holy wars. Fact is that regular C code is still ruling the world. Maybe not in the financial industry. Maybe it's embedded in a few C++ syntactic constructs. Maybe some people even found a way to use RAII in a way that doesn't suck in a large project. But the vast majority of the stuff that does something is still dangerous, evil, ugly C. And now excuse me while I go watch another talk named "C++ Features to avoid" or "Taming build times in a large C++ codebase" or "Why we went back to plain C"
- k__ 6y agoHave you looked at Nim?
- RcouF1uZ4gsC 6y agoI am happy that functions/subroutines were invented and in common use by programmers in the 1970’s, otherwise we would have had arguments that function calls with their stack based semantics are confusing, and explicitly writing out what you want your code to do instead of hiding it behind a function call increases code clarity. There would have been a group of people who criticized Go’s lack of functions, but other people would have pointed out that functions are not strictly necessary and besides they will be added in version N+1 once we are sure about the best way to do functions.
- foldr 6y agoSubroutines themselves weren't the innovation. Everyone was already calling out to subroutines in their assembly code. The innovation was structured programming.
- fpoling 6y agoStack-based subroutine calls associated with structured programming came quite after people started to use subroutines in the assembly or higher level programming. Fortran, for example, gained those in eighties. Prior that everything was statically allocated and recursive calls were not supported.
- zozbot234 6y agoI'm not sure that "stack-based subroutine calls" are associated with structured programming. An activation stack is required to ensure reentrancy e.g. if a subroutine might be called from an ISR or a cooperatively-executing task, in addition to suppprting recursion.
- srean 6y agoCould you give us an example of a pre-structured programming, high level language that supported the things that you talk about. PDPs had instruction support for cooperatively executing tasks but the return address was stored in a register, and was therefore limited to a depth of one. From what I know stack based subroutines really became common around Dijsktra's famous paper which really ought to have been called 'Use the Stack, Stupid" rather than GOTO considered harmful. I am more than willing to be corrected with citations to the contrary.
- dang 6y agoLet's try an experiment and replace the putdowney first part of the title with its upliftey second part. The experimental bit is this: since titles basically dominate discussion completely, this change will probably convert a dyspeptic Go thread (boring) into a vigorous OCaml one (hopefully less boring). Of course that assumes that my posting this comment doesn't pull a Heisenberg on the discussion. Edit: I forgot to mark this off topic so of course the meta aspect took over. (This was the top subthread, probably overnight. I'm going to downweight it now.)
- TsiCClawOfLight 6y agoThank you so much. Please do this more often!
- thunderbong 6y agoI don't know if it helped much though - Like others have mentioned this is a quasi Go article doing a Schrödinger on OCaml
- dang 6y agoI probably should have read the article before trying a late night experiment. Also, I should have marked my comment off topic.
- switch007 6y agoEither of them alone kind of misrepresents the article. Why not both, e.g. "Go is a Pretty Average Language (But OCaml is Pretty Great)"
- MRMediocre 6y agoThis is called 'misrepresentation'.
- MRMediocre 6y agoFurthermore, by completely changing the title, you're grossly violating your own guidelines: "Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize."
- dustinmoris 6y agoThe original title of this blog post is "Go is a Pretty Average Language" and the sub title is "But OCaml is Pretty Great". Why has the title of this HN post been changed to something which isn't either?
- steev 6y agoProbably to try and prevent this from turning into a flamewar. A lot of people just read the title and don't read the article and then comment based on what they think the article is about.
- yawaramin 6y agohttps://news.ycombinator.com/item?id=23040385 https://news.ycombinator.com/item?id=23040385
- MRMediocre 6y agoSolely because dang didn't like the title. Here are several things to consider: 1. HN's own guidelines state: "Otherwise please use the original title, unless it is misleading or linkbait; don't editorialize." 2. dang edited the title of a submission from another user. Almost certainly without asking. 3. dang edited the title that reflecte title of an article verbatim, to something completely different that conveyed completely different information. Almost certainly without asking the author of the article. It's HN's prerogative to do whatever they want on their site. However, considering the after-the-fact manipulation of a HN user's post for no good reason, and the misrepresentation of an article that someone else wrote, I do not trust the HN mods at all. Since they're already changing user's contributions based on a whim, it's reasonable to assume that this extends to users' comments, the vote scores, and anything else visible on the site. I'm going to get permabanned for this, and I don't care at all. I now have zero trust in the mods of this site, and the information it presents.
- deleted 6y ago[deleted]
- dang 6y agoYou're describing something that has been standard practice on HN for over a decade, and is well understood by this community—so much so that entire websites have been dedicated to tracking title changes on HN. If you want to know more about HN, it's easy to learn by using the search box that's at the bottom of every page, as well as the links (guidelines, FAQ, etc.) at the bottom of every page. Also we're happy to answer questions at hn@ycombinator.com, and HN users are happy to explain things to new users. It's usually a good idea to take a little while to learn about the conventions of a community you've just joined before jumping into high drama. On the other hand, most new accounts that show up to complain about HN and its moderation are not really new users at all, but concern trolls—sturgeon of the second freshness: https://www.google.com/search?q=%22second+freshness%22&oq=%22second+freshness%22 https://www.google.com/search?q=%22second+freshness%22&oq=%2....
- smabie 6y agoThe reason why Ocaml and Haskell are relatively verbose is that in order to achieve maximum performance one must write code in a decidedly unidiomatic style.
- rwmj 6y agoThis is true, but also not necessarily an objection. It gives you a choice of decent performance by default, or very good performance when you really need it.
- k__ 6y agoReminds me of some blogposts abut JavaScript and Rust, I've read. The author was arguing that you can achieve maximum performance with Rust while still writing it in an idiomatic way, which isn't possible with JS.
- tomp 6y agoThat might be true, but the converse is that even idiomatic Rust is extremely verbose and painful to the eyes. Ideally, you'd be able to write mostly OCaml (higher level, closures, polymorphism, GC) and Rust (safe manual memory management) only when needed.
- k__ 6y agoI think coming from JavaScript, the wins in writing Rust are much bigger than coming from OCaml. So, as a JavaScript developer, I currently favor Rust instead of OCaml.
- pjmlp 6y agoWhich will be possible when algebraic types get integrated into OCaml, part of the work has already been integrated due to the ongoing multi-core changes.
- tomp 6y ago
- zabil 6y agoMy team's been using Go for the past five years to build an open source test automation framework. None of us knew Go before starting on the project. Five years on, we have no regrets. The language semantics does not get in our way, it "feels" easier to solve problems. Personally, with OOP languages I spend a lot of time designing vs solving. Design is subjective. Go, takes that burden away.
- fb03 6y agoI am doing the same with Rust. Fell in love with the language and it feels great :) Yeah you have to battle the borrow checker sometimes but it's there to help you avoid shooting yourself in the foot.
- deleted 6y ago[deleted]
- pansa2 6y ago> You may have noticed I left one of my favourite languages, Python, out. This is because I had truncated the chart at the given maximum X and Ys. Such a plot for Python would show no red line. Is this because Python is very slow? If so, it would be interesting to see a graph for PyPy.
- bno1 6y agoPretty great until you come across a project with thousands of lines of code and 0 type signatures. At least Haskell warns you about top-level declarations without type signatures. This is the error of the developer, true, but I think compilers should steer people away from doing such things.
- rwmj 6y agoFor OCaml, generate annot files by adding the -annot flag. Then in emacs you can do C-c C-t over any expression and it will tell you the type. Edit: But I do think you have a point. In our OCaml programs we enforce interface files (*.mli) for all modules (the rule is enforced by 'make check'). So at least between modules there is always documentation and an explicitly typed interface.
- c-cube 6y agoIn ocaml, install merlin or the upcoming ocaml-lsp, you mean :) It's excellent tooling and provides completion, jump to def, etc. Annot files are very limited in comparison.
- k__ 6y agoAren't they always displayed in a virtual line above?
- yawaramin 6y agoAre you talking about OCaml. It's widely accepted community practice to have type signatures in separate interface files. Those make it pretty easy to navigate the code.
- bawolff 6y agoWhat a silly metric. Is there any point other then feeding language-war trolls?
- barbegal 6y agoIts a tough thing to study but I'm not sure the definition of verbosity is particularly good. >size of the clean (i.e. no comments, normalized white space) GZip’d program source code, in bytes. Some languages idiomatically use comments and white space to aid readability whereas others use more verbose function and variable naming. Gzip will also encode patterns that could be very verbose (switch statements, unrolled loops, functions with same prefixes...) into very few bytes
- cousin_it 6y agoMaybe a logarithmic performance axis would make the plots clearer.
- tsegratis 6y agoHaskell's higher gzipped code size might be due to assignment providing semantic compression for other languages -- that gzip isn't applying to Haskell I.e. gzip is very unlikely to model assignment in it's compression algorithm, so it will compress other elements -- and those elements probably correlate with the ones Haskell already optimizes for So gzip metric makes the other languages look better than a pure loc would
- tsegratis 6y agoDoes this imply that anti-functionalism is better? I.e. gzip and the human brain can probably compress repetition and local effects very easily -- and this is what purity gives. So with purity I can only represent the obvious (i.e. easily computable), and gzip suggests this is the part of the computation that least needs expressing -- since it is already the most clear But allowing anything to affect anything else in any way; as a maxima; allows me to represent the least-obvious algorithms most succinctly -- and least-obvious algorithms are the most important ones to represent succinctly! I feel like there is some truth here, but it is not the whole story. What am I missing?
- tsegratis 6y agoI suppose I assumed less-obvious algorithims always have semantically meaningful differences to more-obvious algorithims But we can hope that this is rarely the case More-obvious always wins if there are never any semantic differences Good programming is finding the most-obvious algorithim while keeping the same semantics -- and even sometimes changing the semantics to make them more obvious In that vein, a side question I often ask myself is, which should the algorithm represent clearly: 1) The problem 2) The solution 3) The transition between those two All 3 have validiy, and result in very different programming paradigm How can I choose one above the other??
- tsegratis 6y agoI'd like an answer to that if anybody would care to ;) 1) The problem. Maps well to macros 2) The solution. Maps well to prolog 3) The transition. Maps well to imperative What basis can I use for choosing between those goals?? -- The given mappings are examples
- grey-area 6y agoThis chart shows the balance between the verbosity of a program written in a language, and the runtime performance of it. The ideal programming language would sit at the lower left quadrant. This is a very odd way to rank programming languages. A language which said nothing and did nothing would be in the lower left too. I don't mind things being verbose if they are easy to read - compactness is not a good measure of clarity. Code is read far more often than it is written, so this is important, and performance is part of a set of tradeoffs against resource usage etc, it's not a static thing for all situations.
- ImprobableTruth 6y ago>A language which said nothing and did nothing would be in the lower left too. Huh? This is like if I were to argue that I'm one of the top runners in the world since I can't finish a marathon and thus my finish time is 0. A language that is unable to solve the problems would not be listed at all or have an infinite value on the performance axis. >compactness is not a good measure of clarity Solely taking compactness into account is definitely not a good idea, since it just leads to code golfy situations. However, I completely disagree that verbosity isn't a major detractor to readability, since it introduces a lot of noise that detracts from what actually happens. People can only keep track of so many things at once, so the simplicity of a single part often enough comes at the cost at making it harder to understand the whole. It's not a coincidence that 'higher-level' languages are generally less verbose than lower-level ones.
- grey-area 6y agoA language that is unable to solve the problems would not be listed at all I was pointing out the absurdity of using these two criteria in isolation to judge languages, turns out there are other important things like finishing correctly, number of bugs, and clarity, not compactness. I don't think the ideal language can be judged on two criteria (or that there is an ideal language for everyone). However, I completely disagree that verbosity isn't a major detractor to readability, since it introduces a lot of noise that detracts from what actually happens Sure I agree extreme verbosity can be terrible too. So also can extreme terseness, unless it closely matches the problem domain, because otherwise now you have two problem domains you have to be familiar with in order to get work done - the actual problem domain, and the jargon invented by the programmer/language in order to solve it. This depends partly on the person reading and their preference for abstraction.
- AzzieElbab 6y agoI wish this post and comments had more ocaml :(
- bufo 6y agoHave people actually looked at the code? You can’t treat the benchmarks game code as a simple black box. Most implementations look like C regardless of the language, eg. https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/mandelbrot-ghc-3.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... or https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/nbody-ghc-2.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... There is very little to infer from code which is so far from being idiomatic, aside from the fact that you might as well use C if you ever find yourself in the benchmark situation.
- faccacta 6y agoSome other examples of what you are talking about: In the regular expression benchmarks, some entries implement their own idiomatic regex parsers or link to the PCRE2 library, rather than use the regex library that comes with the language implementation: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/regexredux-python3-2.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/..., https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/regexredux-csharpcore-8.html https://benchmarksgame-team.pages.debian.net/benchmarksgame/... This is, arguably, totally fine, because these are still valid programs that run (and run quickly). BUT, it makes the benchmark programs poor choices to compare the verbosity of languages. So statements like "For a language famed for its terseness, Haskell it turns out, isn’t as terse as expected" can't be supported when comparing benchmark programs that were written to maximize speed, rather than written to minimize developer time. Fortunately, the Benchmark Game does publish all of its programs, including the ones that don't "win" the speed race, and it's possible to find nice, concise, idiomatic Haskell programs in there.
- igouy 6y ago> BUT, it makes the benchmark programs poor choices to compare the verbosity of languages. Because? Because the way some link to an external library is more verbose than the way they link to an included library?
- 6y ago
- deleted 6y ago[deleted]