29 ms·
8 months of OCaml after 8 years of Haskell in production (2023)
- fn-mote 2y ago(2023) in case it looks familiar
- agnishom 2y ago> I’m interested in building stuff, not sitting near my pond on a warm summer day, thinking if TypeFamilies + DataKinds would be better than GADTs for making illegal states unrepresentable. I feel differently. I would rather sit by the pond on a summer day rather than build stuff
- yazzku 2y agoEngineer vs mathematician. Haskell is the schizophrenic product. > If I come to an existing OCaml project, the worst thing previous developers could do to it is have poor variable names, minimal documentation, and 200+ LOC functions. That’s fine, nothing extraordinary, I can handle that. > > If I come to an existing Haskell project, the worst thing previous developer>s could do… Well, my previous 8 years of Haskell experience can’t prepare me for that This is kind of like Go vs C++, or <anything> vs Common Lisp. The former is a rather unsophisticated and limited language, not particularly educational or enlightening but good when you need N developers churning code and onboard M new ones while you're at it. The latter is like tripping on LSD; it's one hell of a trip and education, but unless you adopt specific guidelines, it's going to be harder to get your friends on board. See, for example: https://www.parsonsmatt.org/2019/12/26/write_junior_code.html https://www.parsonsmatt.org/2019/12/26/write_junior_code.htm...
- shermantanktop 2y agoLearning a “pure” language is a lot like tripping on LSD. The people who do it can’t stop talking about how great it was, but also can’t really explain why it was so great, and when they try it just sounds ridiculous, maybe even to them. And then they finish by saying that you should drop acid too and then you’ll understand.
- CyberDildonics 2y agoThe reality is people want what you produce when you're sober, not having fantasy hallucinations.
- yazzku 2y ago"You mean you're going to make a copy of that every time?"
- mrkeen 2y agoHaha, can't tell if you're joking or not. For anyone else reading - you don't need to make a copy if you know your data isn't going to change under your feet. https://dev.to/kylec32/effective-java-make-defensive-copies-when-necessary-4bd6 https://dev.to/kylec32/effective-java-make-defensive-copies-...
- yazzku 2y agoI was half-joking. I wasn't aware Java was promoting "defensive copies" :D
- eru 2y agoHaskell isn't all that pure.
- ChadNauseam 2y agowhat do you mean by that? all functions in haskell are pure unless you explicitly use unsafePreformIO or similar (which is rare to ever have to do)
- enugu 2y agoOCaml is not an unsophisticated language. It inherits the features of ML and has first class modules, which is not present by default in Haskell (present in backpack). Not having first class modules leads to a lot of issues. Also, there is a better story for compilation to the web.
- wyager 2y agoOCaml's type system is quite janky and simplistic compared to Haskell's. The first class module system is fairly nice, although it leads to an annoying problem where now you kind of have two "levels" to the language (module level and normal level). This is arguably analogous to Haskell having a "term level language" and a "type level language", where the type system is more prolog-y than the term language. Also, Haskell's type system is powerful enough to do most of the things you'd want the OCaml module system for, and more. I do occasionally miss the OCaml module system, but not most of the time.
- RandomThoughts3 2y agoConversely, the Ocaml module system is powerful enough to do all the things you had want to do with Haskell except the Ocaml module system is nice to use. Anyway, the issue has nothing to do with relative powerfulness. The issue is that the Haskell community encourages practices which lead to unreadable code: lot of new operators, point-free, fancy abstraction. Meanwhile, the Ocaml community was always very different with a general dislike of overly fancy things when they were not unavoidable.
- kreetx 2y agoIf by "encourages" you mean "has features", then yes. The typical haskell shop doesn't really encourage complex feature use, it's the people learning/online who don't actually need to work within their solutions, do. That's what seems to draw (some) people to haskell.
- wyager 2y ago> except the Ocaml module system is nice to use This comment doesn't lead me to believe you've ever worked in an ocaml shop. It's only "nice to use" for trivial use cases, but quickly devolves into a "functorial" mess in practice > the Ocaml community was always very different with a general dislike of overly fancy things when they were not unavoidable This is the exact thing that people always say when they are coping about their language being underpowered.
- hedora 2y agoGo is good for onboarding people onto a project, but not much else. There's a reason Google is migrating Go services to Rust: https://www.theregister.com/2024/03/31/rust_google_c/ https://www.theregister.com/2024/03/31/rust_google_c/ > "When we've rewritten systems from Go into Rust, we've found that it takes about the same size team about the same amount of time to build it," said Bergstrom. "That is, there's no loss in productivity when moving from Go to Rust. And the interesting thing is we do see some benefits from it. > "So we see reduced memory usage in the services that we've moved from Go ... and we see a decreased defect rate over time in those services that have been rewritten in Rust – so increasing correctness." That matches my experience: Go serivces tend to be tire fires, and churn developers on and off teams pretty fast.
- krmboya 2y agoIsn't Go's concurrency model an advantage over other approaches?
- lmm 2y agoWhen it exactly fits your problem, yes. But it's not like you can't express that model in Rust (in a more cumbersome way) when you need to.
- foldr 2y agoYou'd expect a rewrite to take less time than development of the original system from scratch. So I'm not sure this is actually as favorable a result for Rust as it's presented.
- deleted 2y ago[deleted]
- JoshTriplett 2y ago> I feel that I can focus on actually building stuff with this language. This is very much how I felt when using Rust as a previous production Haskell user. I enjoyed aspects of Haskell, and I'm still very impressed with it, but it seems to call up a kind of perfectionism that I don't experience nearly as much with other languages.
- kreetx 2y agoIME, the trick with perfectionism is knowing when to apply it. I.e, don't do it at the beginning but at the moment when the initial version starts falling through. Also, do it on the general area the issue lays (not "everywhere").
- JoshTriplett 2y agoAbsolutely. But with Haskell in particular, there are endless expressiveness micro-optimizations like "how can I write this point-free", "is there a combinator that would allow expressing this differently", "how can I express more of this in the type system"... I am sure it's possible to write Haskell and just not fall into that trap, but I found that Haskell was especially prone to nerd-sniping the micro-optimizing part of my brain, in a way that other languages don't.
- karmakaze 2y agoThis for me sums up the library ecosystem and the type of folks who like using Haskell as a hobby. When I write production code, I aim to be as clear showing a good working design that's easy to understand (reading the issue/PR descriptions if necessary). The code style is chosen to maximize human comprehension. What I'm not doing is playing a game of one-upmanship with (virtual) others. The only parts I'm really interested in optimizing are the bits that matter: factoring, naming, datastructures, algorithms, queries (for database), and minimizing abstractions that don't pay their weight. I spent some time using F# out of curiosity of both it and OCaml and found that it was very easy to use with the exception of (mutable) arrays.
- zeendo 2y agoBeing conservative in the language extensions you use/allow in an organization is pretty important to maintaining usability of Haskell as a language. Do we ever use TypeFamilies and DataKinds? Sure, but it's very rare. https://www.simplehaskell.org/ https://www.simplehaskell.org/ is a pretty reasonable set of guidelines (though we opt for a more conservative approach ourselves)
- anta40 2y agoNice to see some folks encouraging how to solve problems with less fancy features/lang extentions (especially in commercial context), considering not all Haskell coders are programming language/compiler nerds :)
- rjh29 2y agoSeems similar to Perl, where there are about 20 ways to do any given thing, and 15 of those are deprecated or not recommended by the community.
- mrkeen 2y agoIt usually follows that the fancier stuff is done for a reason, not just artistic expression. So it's not that they're not the best way, it's just that not everyone knows how to do it that well.
- cosmic_quanta 2y agoNowadays there are "language editions" (e.g. GHC2024) packing many stable language extensions together. It's definitely safe to turn those on, from a maintenance point of view. Edit: Link to docs: https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/control.html#controlling-editions-and-extensions https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/cont...
- zeendo 2y agoYeah - we definitely consider the language edition as we revise our internal lang extension rules...but we still find ourselves even a little more conservative than even GHC2024.
- sgt_bilko 2y agoAnyone built simple (but not trivial) projects with Haskell or OCaml with source that I can look at?
- elbear 2y agoAn unfinished command-line client for Hacker News: https://github.com/LucianU/hn-reader https://github.com/LucianU/hn-reader
- eru 2y agohttps://github.com/matthiasgoergens/Div7 https://github.com/matthiasgoergens/Div7 is a simple one that you might like.
- stitched2gethr 2y agoThis seems more on the trivial side to me.
- eru 2y agoYes, depends on where you draw the line. XMonad is a bit bigger: https://github.com/xmonad/xmonad https://github.com/xmonad/xmonad
- wyager 2y agoI wrote this like ~10 years ago as a "Hello World++" type demo (basic key/value server) in Haskell. It's about 200 LoC, with a Haskell and Python client. http://github.com/wyager/neks http://github.com/wyager/neks
- jlarocco 2y agoI'm sure a lot of people here have much better examples, but I wrote some basic regular expression and finite automata algorithms in Haskell a long time ago: https://github.com/jl2/Compiler-Algorithm-Code/tree/master/haskell https://github.com/jl2/Compiler-Algorithm-Code/tree/master/h... I tried it out and after renaming fold -> foldr, it still builds and seems to work. The main function takes a regex as a command line argument and creates a finite automata graph using GraphViz's dot. In the Compiler-Algorithm-Code/haskell directory: make ./test "(foo)+(bar)*(foo+)" | dot -Tpdf -ofoobarfoo.pdf && xdg-open foobarfoo.pdf
- kccqzy 2y ago> Both Haskell and OCaml have kinda barebones standard libraries. […] Haskell doesn’t include Map and HashMap; The Haskell standard library was split off into smaller parts. Map used to be part of the standard library. To date the containers package (which contains Map) is still pre-installed alongside the GHC compiler. So it should be considered part of the standard library. Check out the documentation for GHC 3.02 https://downloads.haskell.org/~ghc/3.02/docs/users_guide/users_guide-5.html#ss5.6 https://downloads.haskell.org/~ghc/3.02/docs/users_guide/use... it clearly shows a FiniteMap type being provided.
- ggm 2y agoI have some sympathy for "divide and conquer" but for me, libc and libm and libffi seem like very good splits. libgnuc is just having a lend, libobjc is beginning to feel like I'm being trolled and when I learned about stdlib I decided to stop worrying. There was a time when the fastest way to resolve circular dependencies in the library chain was to simply add -Lthing multiple times in sequence so that a subsequent library could be sure the name list of the priors were loaded, including the dependencies down "right" of it in the list. Taking something as fundamental to what FP is like map/reduce and saying "this can live in an adjunct library" feels like somebody took divide and conquer a litte too far.
- eru 2y ago> Taking something as fundamental to what FP is like map/reduce and saying "this can live in an adjunct library" feels like somebody took divide and conquer a litte too far. What are you talking about?
- ggm 2y ago> The Haskell standard library was split off into smaller parts. Map used to be part of the standard library. To date the containers package (which contains Map) is still pre-installed alongside the GHC compiler. So it should be considered part of the standard library. See those words "to date" and "considered" Not Is, is considered, to date. Thats what I am talking about.
- yazzku 2y agoCompiler messages: The big difference here is that the OCaml compiler has a lot less work to do. It's not that the Haskell error messages are inadequate (they are actually pretty good), but that the amount of compiler features and type gymnastics make the errors deeper and more complex. For example, if you get the parens wrong in a >> or >>=, you'll get some rather cryptic error that only hits home once you've seen it a few times, as opposed to "did you mean to put parens over there?"
- yazzku 2y agoMissing from this post: string_of_int, int_of_string, +, +., etc. That alone is a massive turn-off for me, I'd rather write C at that point. Any modern language necessitates some kind of polymorphism and make user-defined types feel like first-class citizens.
- int_19h 2y agoInterestingly enough, OCaml has a great polymorphism story in its OO system. Because it is structurally typed with nearly automatic inference, you can in fact write completely generic code like `x#y(z)`, which magically "just works" for any x that has a method y that accepts z - all inferred and statically type-checked.
- yazzku 2y agoInteresting. Why doesn't the standard lib use that for the examples I listed?
- debugnik 2y agoBecause those types are not object types, so they don't have methods associated with them at all. This is unlike, say, CLR languages in which all types are object types. There's been research on modular implicits for OCaml to solve this more generally, but that's not landing upstream anytime soon.
- instig007 2y ago> Because it is structurally typed with nearly automatic inference, you can in fact write completely generic code like `x#y(z)`, which magically "just works" aka let's mix two jars of jam and shit via this funnel and see what happens.
- int_19h 2y agoOn the contrary, static and structural typing are a match made in heaven.
- 2y ago
- neonsunset 2y agoMassive amounts of headache could have been avoided by using “OCaml but with ecosystem and great tooling support” known as F# :)
- hedora 2y agoI tried that about 10 years ago and spent 2 hours trying to open some files under Linux. Then I gave up. Have things improved?
- bmitc 2y agoVastly. You were probably using Mono. .NET is now fully cross-platform and very good at being so.
- neonsunset 2y agoThe below should work as is: sudo apt install dotnet9 # or dotnet-sdk-9.0 if the repo doesn't have dotnet9 metapackage dotnet new console --language F# There is also a package for Avalonia that lets you write GUI applications in F#: https://funcui.avaloniaui.net https://funcui.avaloniaui.net
- devmunchies 2y agoI didn't use it 10 years ago but I've been using it for the last 4 years on mac and linux exclusively. Microsoft seems to be prioritizing "cloud" on all their developer products (rather than just windows). I don't feel disadvantaged by NOT using dotnet on windows.
- spooneybarger 2y agoVery much so.
- wyager 2y agoF# is good because MSR used to hire a bunch of the top GHC devs and pay them to work on F# part-time. They put all their actual passion into Haskell.
- phplovesong 2y ago
- deleted 2y ago[deleted]
- aidenn0 2y agoFirstly, this doesn't mention the thing that bothered me the most in my few encounters; how baroque and fluid the tooling is. I have regularly run into code that can only be compiled by a rather narrow range of ghc versions; too old or too new and it just won't. > Haskell probably has the most elegant syntax across all languages I’ve seen (maybe Idris is better because dependently typed code can become ugly in Haskell really quickly). I have a general dislike for ML-type syntaxes, and Haskell is my least favorite of the ML-type syntaxes I have encountered. Presumably there is some underlying set of principles that the author would like maximized that I assuredly do not. > There’s utter joy in expressing your ideas by typing as few characters as possible. Disagree; if I did agree, then I would probably use something from the APL family or maybe Factor.
- bmitc 2y agoThat's interesting you dislike ML syntaxes when they're generally thought to be the cleanest syntaxes. What syntax families do you generally like? Also, Haskell isn't really ML-syntax. I love MLs but find Haskell syntax pretty ugly.
- The_Colonel 2y ago> when they're generally thought to be the cleanest syntaxes That might be true for academics. But most engineers don't consider ML syntax to be the cleanest, since most don't know any ML language.
- wyager 2y ago> most engineers don't consider ML syntax to be the cleanest, since most don't know any ML language. This is like saying "most uncontacted Amazonian tribes don't like Shakespeare, because they've never read it". Sure, but why would we care about their opinion on this topic?
- unscaled 2y agoThey might think Shakespeare's story are silly even if they did read it. In fact, there is at least one widely publicized instance where exactly the same thing happened with a culture that wasn't exposed to Shakespeare before: https://law.ubalt.edu/downloads/law_downloads/IRC_Shakespeare_in_the_Bush.pdf https://law.ubalt.edu/downloads/law_downloads/IRC_Shakespear... The same idea is probably true with programmers who have grown used to C-like syntax or even Python-like or Ruby-like syntax. Syntax is at least in great part a cultural thing and your "cultural background" can affect your judgement in many cases: 1. Are braces good? Some programmers find them noisy and distracting and prefer end keywords or significant whitespace, but other programmers like the regularity and simplicity of marking all code blocks with braces. 2. Should the syntax strive for terseness or verbosity? Or perhaps try to keep a middle ground? At one end of the spectrum, Java is extremely verbose, but a lot of Java engineers (who have generally been exposed to at least one less-verbose language) are perfectly OK with it. The trick is that the main way that code gets typed in Java used to be copy-paste or IDE code generation (and nowadays with LLMs typing verbose code is even easier) and reading and navigating the code is done with the help of an IDE, so a lot of the effects of having a verbose language are mitigated. Diffs are harder to review, but in the Enterprise app world, which is Java's bread and butter, code reviews are more of a rubber stamp (if they are done at all). 3. Lisp-like S-expression syntax is also highly controversial. Many people who are introduced with it hate it with passion, mostly because the most important syntax feature (the parentheses) is repeated so often that it can be hard to read, but advocates extol the amazing expressive power, where the same syntax can be use to express code and data and "a DSL" is basically just normal code.
- omoikane 2y agoI thought the main draw of OCaml is that it has imperative features such as for-loops, instead of trying to be purely functional like Haskell. This probably made OCaml easier to pick up for people coming from other programming languages.
- runeks 2y agoAgreed. The main draw of OCaml is that it isn't pure like Haskell. Haskell's purity is really what makes it weird (and great).
- emoII 2y agoFor-loops and mutation are not really encouraged, often loops are implemented with recursion as in normal fp. The big difference to me is that OCaml doesn't try to be pure, so you can perform side effects as needed, instead of forcing the user to jump through hurdles when trying to print to stdout
- re-lre-l 2y agoJust curious - what is the niche for this languages and what's the motivation to choose one?
- jasinjames 2y agoCompilers are a good one. I know Rust's original compiler (before being self hosted) was implemented in OCaml. Darklang's compiler was in OCaml as well.
- delta_p_delta_x 2y agorustc targets LLVM IR by default, and I daresay the bulk of the optimisation and assembly-lowering work is done in LLVM. Which is solidly C++.
- chongli 2y agoThey’re not meant to be niche languages. They’re meant to be general purpose languages. They’re trying to use functional programming to achieve a high degree of correctness with short, readable programs.
- johnisgood 2y agoNot niche, Jane Street uses OCaml (and they contribute a lot to the compiler, too), it is "a research-driven trading firm where curious people work together on deep problems". More about it here: https://www.janestreet.com/what-we-do/overview/ https://www.janestreet.com/what-we-do/overview/
- delta_p_delta_x 2y ago> where curious people work together on deep problems 'curious people': people who got jaded by academia and were attracted by the six- to seven-figure salaries at Jane Street. 'deep problems': Buy X units of Y instrument at A exchange, and sell Z units of said instrument at B exchange, and do this often enough that said company makes a pile of money for itself and its employees (mostly itself, given it can afford to pay its employees six to seven figures).
- bhargav 2y agoMaybe because I haven’t used languages like these in the past, but I hardly think this is elegant, much read readale. I would hate my life trying to parse code like this in a 10k LOC codebase. strSum = sum . map read . words
- solomonb 2y agoIn a production application you generally don't write code like that. I find it tends to be the opposite problem where you often see giant `do` blocks performing all sorts of monadic effects.
- djur 2y agoYou especially wouldn't use `read`.
- fleshmonad 2y agoIt's actually very readable once you get the hang of it. The transition from imperative paradigms to Haskell can be tough, but once you've overcome this barrier, the code reads effortlessly. In your example case: split the string into a list of words, that is tokenize based on spaces. Then map the read function onto this, which will parse each of the "words" in the list into some type. Annotations would likely be needed here. Then sum this list. I much prefer this over 10 levels of class indirections or procedural style.
- brabel 2y agoIsn't it the case that anything is very readable once you get the hang of it? I think the problem is exactly in the "get the hang of it" part. For some languages, that's really difficult, while for others it's almost trivial. From my own experience, Haskell is very very difficult to "get the hang of" despite my multiple attempts, while something like Javascript is trivial for me (interestingly enough, except when it uses too much of the new FP patterns!) even when I do not program on it daily.
- 2y ago
- Tainnor 2y agoThe Haskell examples at the beginning are a bit weirdly chosen. You wouldn't want to write code like that except in scripts etc. because it would crash the program if you encounter bad input. The first example could be more idiomatically written as: strSum :: String -> Maybe Int strSum = fmap sum . sequence . fmap readMaybe . words (You'd also probably want to avoid String and use Text instead.) For more complex parsing scenarios, the various parser combinator libraries can take a while to get used to (and I wish the community would standardise on one or two of them), but they're extremely powerful.
- runeks 2y agoLet's take that further: you wouldn't want to use your code above either, because it would be impossible to tell why the parser failed. Which is going to be really frustrating once it fails. And if it doesn't fail the first version is fine.
- Tainnor 2y agoSure, you can improve this by e.g. import Data.Either.Combinators -- from the either package strSum :: String -> Either String Int strSum = fmap sum . sequence . fmap tryReadInt . words where tryReadInt w = maybeToRight ("not an integer " ++ w) (readMaybe w) This keeps the bulk of the method the same. Being able to go e.g. from Maybe to Either with only few changes (as long as your code is sufficiently general) is one of the nice things you get from all the Haskell abstraction. You can't really do that if you start with exceptions (unless you're in IO).
- brabel 2y agoHm... for anything real, you would need to provide good error reports, i.e. why did it fail to parse. Code like this looks pretty, but once you add in good error reports, I feel like it tends to look almost exactly the same as in an imperative language?
- mrkeen 2y agostrSum :: String -> Either String Int strSum = fmap sum . mapM readEither . words
- achou 2y agoWhat about performance? I wrote my thesis in OCaml and my recollection was that it had an amazing native code generating compiler that not infrequently output code that was almost as fast as C if you wrote it the right way. The story I heard about Haskell was far different at the time (admittedly decades ago).
- kreetx 2y agoAs with all garbage collected languages, optimizing comes down to removing allocations, in Haskell this means strictness and choice of data structures. You can make C-speed programs but you may need to work for it, and you'll also need to know the compiler/evaluation model you're working against.
- achou 2y agoSure, I think what I noticed was that even idiomatic OCaml code was relatively fast, maybe 2-3x slower than C, but plenty fast enough. Whereas I was under the impression that idiomatic Haskell was far more likely to have unexpected and harder to fix performance issues (e.g. requiring more of an architectural rewrite) because of its lazy evaluation model.
- kccqzy 2y agoThe problems brought about by the lazy evaluation (laziness when you don't want it) do not require architectural rewrites. It's mostly just profiling while setting a very low stack size limit, and then discovering which part of your code triggers a stack overflow. It can be solved by adding the right amount of seq (sequences evaluation), or ! (strict patterns). Maybe you'll also change a few incorrect uses of foldl into foldr. Even if you need to change from lazy Map to strict Map the change isn't disruptive; it's just changing some import and done; all the functions work. No architectural changes needed.
- xlii 2y ago(…on Stripe API…) OCaml: 1 (last change was 8 years ago, so it’s more like zero) I’ve been using OCaml for some time, primarily for my pet project, but also and some minor at-work utilities. One such thing was interacting with Datadog which, unsurprisingly, doesn’t provide OCaml SDK. In short: Experience was great. Not only implementing specs with provided specs while using OCaml tooling was fast but also when I got to the rate limiting, I’ve been able to refactor code in around 20 minutes and then it felt like magic transformation. My take away from that experience is that I wouldn’t use library availability as a hard argument. Every external library is liability and if language provides comfortable tooling and helpers then probably having own code on use-adequate level of abstraction (instead of high level kitchen sink) might preferred. For high number of external integration I would use something like Go instead, which has exactly that, but as an API implementer I’d prefer to use OCaml instead.
- cassepipe 2y agoIsn't what you are describing the curse of Lisps ? That is it is so easy to just roll your own but that there is no third-party consensual libraries and since there isn't there is little adoption ?
- skydhash 2y agoThere are libraries like cl—ppcre or alexandria. The fact is most features are trivially implemented that you don’t need that much external libraries. Most are glue code anyway. And with lisp, as soon as you can translate the data structures, you can use the available functions in the standard packages. So you may want that github sdk, but in truth you’re only going to use 2 to 5 functions. Why not get an http package and add the few line of codes for these?
- chshersh 2y agoHey, Author here Happy to answer any questions! At this point, I have 18 months of OCaml experience in production.
- adamddev1 2y agoGreat write-up and I must say a surprising conclusion and good case for OCaml. I also love Haskell but using it for a practical project I came up against some of the pain points mentioned here. If I could suggest some Emglish grammar fixes to this great article, the word order needs to be flipped around for the interrogative sentences. Wait, why doesn't the standard library have docs at all for this version I use? Instead of: > Wait, why the standard library doesn't have docs at all for this version I use? And How can Haskellers live like that without these usability essentials? Instead of: > How Haskellers can live like that without these usability essentials?
- chshersh 2y agoHappy to hear you enjoyed the article! Thanks for the suggestions! English is not my first language, so mistakes could happen. I hope it's not too off-putting, and people can still learn something interesting from articles. I'll incorporate your suggestions :)
- adamddev1 2y agoYour English is great and clear! Those kinds of mistakes (not reordering the word order in interrogative clauses) are so common that in the upcoming years that may become the new standard for English grammar! But for now I will keep trying to correct them. ;-)
- deleted 2y ago[deleted]
- penguin_booze 2y agoLike a moth to flame, I'm drawn to Haskell every 6 months or so. What drives me to it is its ability to express concepts (once you're used to it) parsimoniously - like the point-free style in the example. Monads, I can understand/manage. But by the time I hit Monad Transformers (and the n different packages available), the excitement turns into a headache. It's also a bummer that you need the containers package for basic DS. So, batteries not included, unlike Python. This also means that you need to use a package manager (stack or cabal) even for non-trivial programs, where a one-line ghci command line would have been more ergonomic. That said, learning Haskell has had a very positive effect on how I think about and structure the programs I write in other languages ("functional core, imperative shell"). I don't think I'll ever program in Haskell in any semi-serious capacity. But these days, I get my daily functional fix from using jq on the command line.
- thierrydamiba 2y agoI feel like to use even the most basic python tools I need to use a package manager or find solutions for mix matched dependencies. Is this problem unique to me?
- elbear 2y agoYeah. I feel nobody uses the standard library. Even for stuff like HTTP there is requests.
- reidrac 2y agoIt all depends. For a quick script that I can write in 15 mins that uses an HTTP client, JSON and joins two APIs together, the standard library is OK. To be fair, it could be almost a bash script (using curl and jq or something like that), but I'm more comfortable with Python. So for one-off (or almost one-off) scripts, the standard library is worth avoiding dealing with dependencies.
- thierrydamiba 2y agoAs the comment below alludes to, how many people are just going to import requests as r and then break something else instead of just hitting the client?
- sausagefeet 2y ago> It’s not exciting to write a GitHub API client and parse tons of JSON. While buried in our monorepo, so not very accessible, we just open sourced our product that is written in Ocaml and we have a GitHub client that is generated from the OpenAPI schema. It is separated out from any I/O so it can be used in any I/O context. https://github.com/terrateamio/terrateam/tree/main/code/src/githubc2 https://github.com/terrateamio/terrateam/tree/main/code/src/...
- ceving 2y agoI like this: > A great standard library is a cornerstone of your PL success.
- crvdgc 2y agoI made a similar transition (1 year Haskell, 2 year OCaml) and this pretty matches up my experience. Some more points: 1. Compiler speed: a clear win for OCaml 2. OCaml 's module system is more explicit (always qualified Map.find). Haskell's type class system is more ergonomic (the instance is found through its type, so no explicit annotation needed, e.g. fmap fmap fmap, where the second must be the Reader's fmap). 3. > If I come to an existing OCaml project, the worst thing previous developers could do to it is have poor variable names, minimal documentation, and 200+ LOC functions. That’s fine, nothing extraordinary, I can handle that. Though it's not common, but functor-heavy codebase does give you a headache. On the other hand, unifying type class instances across packages is no fun either. 4. OCaml's mixture of side effects and pure code tends to encourage using that in libraries and codebase. So expect more speed and more crashes.
- 59nadir 2y agoMy problem with OCaml is that it's in an awkward spot where the runtime offers very little, so it can't really be compared with most Haskell use cases where you want green threads (with preemptive scheduling), transactional memory, and so on. The runtimes of the languages aren't really equipped to do the same things, basically. So that leaves OCaml in a spot where it instead competes with more bare runtimes, i.e. compiled languages like Odin, Zig and Rust. In terms of straight forward control of behavior OCaml loses handily to both Odin and Zig. Likewise with how much effort you have to put in to get good performance out of what you're doing, despite what OCaml enthusiasts say it's not magic fairy dust, you still have indirection in terms of expressing your desired allocation patterns, etc., in OCaml that you wouldn't have in Odin/Zig, making it less appropriate for those situations. So, OCaml's final upside: Language simplicity... It's not remotely small or simple enough to be compared to Odin. Zig (despite their best efforts) is still a simpler and leaner language than OCaml as well. Zig also has the interesting quirk that it can express functors just with its `comptime` keyword (returning structs with parameterized functions, all done at compile-time) in a much more straight forward way than OCaml can, making it almost a better OCaml than OCaml in that particular respect. Given the above it seems to me that there's always a [obviously] better language than OCaml for a task; it can't really win because whatever you're doing there's probably something that's better at your most important axis, unless the axis is "Being like OCaml". I liked writing OCaml with BuckleScript, though, compiling it to JS and using OCaml as a JS alternative.
- pjmlp 2y agoAlso opam nowadays is finally working on Windows, which is kind of great, Haskell used to have an advantage there.
- hugodan 2y agoHaskell provides by far the best refactoring experience of all languages I’ve ever used.
- tkz1312 2y agoBoth Haskell and OCaml are fantastic. It is really astonishing the degree to which advancement in mainstream programming languages these days is just copy pasting ideas from either.
- fuzztester 2y agoI thought (based on some posts I've read on HN) that Lisp was the "culprit" for that.
- tkz1312 2y agoFirst class effects and type system enforced purity have made my life as a programmer so much better. They dramatically reduce the size of the state space that must be reasoned about, and having all context being declared in a function definition makes it trivial to really grasp what any given function does. I do agree with the points about language extensions (and I have certainly cursed my fair share of operator heavy point free code), but until someone makes something better (maybe that thing is even lean4?) Haskell still brings me more joy than any other production ready programming language.
- yodsanklai 2y agoNot an expert, but I was paid to write OCaml and Haskell for several years. There are pros and cons but my conclusion is that Haskell has cool features but is too complex. I can iterate faster in OCaml, with the same safety benefits. Learning curve is also less steep for beginners. I think it's also more suitable for programming in the large thanks to the module system. I'm pretty sad that OCaml isn't more popular than it is.
- IWeldMelons 2y agoI think OCaml needs a face lift to make it look like Rust.
- yodsanklai 2y agoFun fact: the first Rust compiler was written in OCaml
- debugnik 2y agoThat's kind of a thing already, the ReasonML syntax (not to be confused with ReScript, which is a fork of both this syntax and the toolchain). The dune build system supports ReasonML out of the box, I think.
- itishappy 2y agoI believe they did that and called it Rust.
- IWeldMelons 2y agoNo. I meant literally, leaving all the semantincs intact.
- frankie_t 2y agoI've used both of the languages previously for my own fun and private mini-projects. From a perspective of an clueless outsider, OCaml was so, so much better to start with than Haskell. I've always been fascinated with Haskell, but it took me around 5 years of attempts to finally get the tooling to work. Some parts always failed me, especially language server and vscode interaction (hardly something to put blame on haskell itself though). Finally I braced myself and with some hacks (like bash code in haskell comments in Setup.hs) made it all work. Still, to the day HLS would repeatedly hang or not start, and the only solution is to restart vscode. Of course, there could be a problem with my setup etc, maybe I configured it "slightly incorrect" way, I'm just rating my experience. OCaml was everything opposite. I made two Ocaml tours in recent years, and both times it literally just worked (tm). Granted, I've been using it less than haskell, but the experience of starting out is just heaven and earth. The only issue I have with ocaml tooling is that ideally I'd like to run the language server for real-time hints from the compiler, but also be able to invoke my program interactively. Unfortunately it seems you either have to run "dune build watch", or you can build and run, but not both as there is some locking happening. As far as the languages themselves go, I'd say haskell is more "fun", in a way that it has a lot of features, and it reads a lot nicer (unless it's point-free code). Monads are pretty fun, although when I finally got through Monad transformers I started feeling "I wish we had no monads tbh" Ocaml feels much more barebone, syntactically less appealing and somewhat clunky. On the other hand there is a kind of spartan appeal to it. Honestly, I like both of the languages a lot and wish for them to continue their development. I can certainly see myself using both in the future.
- debugnik 2y ago> Unfortunately it seems you either have to run "dune build watch", or you can build and run, but not both as there is some locking happening. This is annoying, yes, but for some use cases you can use `dune exec --watch`, which builds and restarts the executable.
- FrustratedMonky 2y ago"You may find a solution in Haskell. But often you’ll discover too many solutions, you won’t know which one to choose." Will this eventually also become a problem with Rust?
- Expurple 2y agoDepends on the domain. For some, there are already de facto standard crates that the ecosystem has concentrated around. For some, like web frameworks, there are many competing choices
- edwardmacnamra 2y ago[dead]
- michaelcampbell 2y agoSo much of this article, and the comments below, can be summarized by one of Rich Hickey's aphorisms: > Everything is hard to read until you learn to read it.
- kqr 2y agoThere's one nebulous property of Haskell that I've never found in other languages – not even F#, which is near OCaml in PL space: Haskell never gets in the way of what I want to express. In many languages I have an idea for what code I want to write, but then some quirk of the language forces me to express it differently lest it looks weird. Haskell never really feels clumsy that way. I know this is not objectively true because there are many cases in which Haskell also forces me to write things a different way than I would have intended (e.g. due to behaviour around resource allocations) but they don't hurt as bad, for some reason. I don't know what it is!
- nh23423fefe 2y agofor me, its the non-strictness
- kqr 2y agoThat helps because it lets you shuffle code around a bit without worrying about computing things in the wrong order.
- norir 2y agoI was thinking about the error message comparison and for me that difference expresses succinctly why I have little interest in using Haskell. Indeed, I have actually started viewing any language with long, detailed and subtle error messages as a red flag. These types of error messages indicate to me that the compiler is trying to do too much and the language would benefit from simplification, especially with respect to trying to infer the programmer's unstated intentions. It of course feels magical when the compiler can infer everything for you, but increasingly I see this as black magic.
- ibgeek 2y agoI think the title is misleading. This isn't really about either language in production environments. As other commenters mentioned, a post about production would cover topics like whether there were any tooling / dependency updates that broke a build, whether they encountered any noticeable bugs in production caused by libraries / run time, and how efficiently the run times handle high load (e.g., with GC). This is more about syntax differences. Even then, I'd be curious how well both languages accommodate themselves to teams and long term projects. In both cases, you will have multiple people working on parts of the code base. Are people able to read and modify code they haven't written -- for example, when fixing bugs? When incorporating new sub components, how well did the type systems prevent errors due to refactoring? It would be interesting to know if Haskell prevents a number of practical problems that occurred with OCaml or if, in practice, there was no difference for the types of bugs they encountered. This blog post feels more like someone is comparing basic language features found in reviews for new users rather than sharing deep experience and gotchas that only come from long-term use.
- pjmlp 2y agoSome production use cases, https://engineering.fb.com/2015/06/26/security/fighting-spam-with-haskell https://engineering.fb.com/2015/06/26/security/fighting-spam... https://www.docker.com/blog/how-docker-desktop-networking-works-under-the-hood https://www.docker.com/blog/how-docker-desktop-networking-wo... https://www.janestreet.com/tech-talks/ocaml-all-the-way-down/ https://www.janestreet.com/tech-talks/ocaml-all-the-way-down...
- ibgeek 2y agoThe Meta post is particularly interesting. Thanks for sharing!