[HN Gopher] OCaml at First Glance ___________________________________________________________________ OCaml at First Glance Author : todsacerdoti Score : 232 points Date : 2022-08-29 11:00 UTC (12 hours ago) (HTM) web link (batsov.com) (TXT) w3m dump (batsov.com) | JassicaB4 wrote: | nerdponx wrote: | This pretty much squares with my experience as well. I also want | to shout out CS3110 as being an excellent (free!!) learning | resource, and that having both a well-written textbook with | exercises and short accompanying video lectures is a wonderful | combination. I will never not be amazed at and grateful for high- | quality university learning material like this being made freely | available. | acka wrote: | For those who are interested in the CS3110 textbook and don't | like Google sending them wristwatch shopping instead, here is a | link to the textbook{1]. | | [1] https://cs3110.github.io/textbook/ | a-nikolaev wrote: | Just to add to this, I wrote additional lecture notes for the | class on OCaml I taught, which was largely based on this | book. | | http://a-nikolaev.github.io/fp/ - if anyone is interested in | more learning resources. | gavinray wrote: | I really want to like OCaml, as a more practical Haskell, but the | syntax to me is just weird. | | I think the ReasonML/ReScript guys had the right idea tbh, but | I'm not interested in writing JS with it. | donut2d wrote: | You can actually compile ReasonML to native code with dune. | | What are some of the things that weird you out about OCaml's | syntax? | gavinray wrote: | > You can actually compile ReasonML to native code with dune. | | Yeah but the community doing native ReasonML is small and the | maintenance has really petered off. | | With OCaml 5 looming you're better off just biting the bullet | and writing OCaml if you're going to do it IMO. | > What are some of the things that weird you out about | OCaml's syntax? | | For whatever reason, I really dislike the named-argument | syntax -- and some of the operators make it hard to read | compared to named alternatives IMO. | | Below examples showcases some of these: let | variables = (json_variables :> (string * | Graphql_parser.const_value) list) ~resolve:(fun | info () -> Lwt_result.ok (Lwt_unix.sleep duration | >|= fun () -> duration) ) | AzzieElbab wrote: | I had a very brief experience with OCaml debugging some seriously | complicated networking code. Putting aside the quirkiness of the | language, its compiler is a wonder of the world. It is | practically as fast as GO which is a miracle given how much more | sophisticated OCaml is. | yodsanklai wrote: | I'm surprised people care about the syntax... that's pretty much | the least important part of the language. | | I've got a few issues with OCaml | | 1. The standard library is inconsistent. Different projects use | different alternatives and it's annoying to switch between then. | | 2. Concurrency using Lwt/Async. Monads feel more ad-hoc in OCaml | than Haskell because there's no type classes and again no | consensus on how it should be done. Some projects use tons of | variation of `>>=`, other use `let%bind`. Again, no clear | consensus and reliance on external libraries which aren't always | well documented. I find code relying too much on monads to be | much less elegant and simple that plain OCaml. | | 3. "includes". I tend to get lost in codebase which abuse | includes. | | 4. It's a small community. If you want to work on "real world" | stuff, most likely you will stumble into tooling/libraries | issues. Not all of these things are very mature or documented and | they're evolving fast. | | I'm wondering if F# suffers from the same issues. | momentoftop wrote: | > Some projects use tons of variation of `>>=`, other use | `let%bind` | | It gets better. Since 4.08, the preference would be `let*`. | daxfohl wrote: | As others have said, F# addresses these issues. The main | complaint I have with F# is when using other dotnet libraries | you end up having to deal with things like nulls again, which | can make the F# feel more cumbersome than it should be. I still | like it though. | pjmlp wrote: | My main complaint is that after all these years, Microsoft's | management still seems not to have a clear picture what they | want it for, althought it seems to have replaced Visual Basic | in feature love for newer .NET versions. | daxfohl wrote: | I worked in Azure for four years in a couple different | teams. I didn't see a single line of F# code while I was | there. I don't think they have any plan beyond supporting | it as somebody's side project. | | Edit: I forgot about https://github.com/microsoft/qsharp- | compiler. IDK if any server code is in F#, but at least the | compiler is. | hvs wrote: | F# has the entire .NET library available, so that won't be an | issue. | oaiey wrote: | I was surprised that the article mentions dozen of languages | but no word of F# which is a mainstream clone/derivate of | OCaml. Especially considering exactly that point. | lf-non wrote: | I think that's understandable. | | Those dozens of the languages are the ones that the author | has personally dabbled with in the past. The focus of | article is their personal experience & first impressions. | | It was not intended to be an exploration of what else is | available in the market and how ocaml compares to them. | adelarsq wrote: | 1. For F# you can can use both .NET and JavaScript libraries | (with tool called Fable), so isn't a issue. | | 2. There a lot of ways to the that, which one with pros and | cons, but isn't a issue in my opinion | | 3. For imports there are a thing called AutoOpen that is | strange at first. Just need to be carefull where to use | | 4. .NET documentation tend to be writed for C#. So you need to | understand at least a little of C# if you want to use that | libraries. But also there are a lot that can be use | idiomaticaly with F#, so isn't a big issue. | freedomben wrote: | > _I 'm surprised people care about the syntax... that's pretty | much the least important part of the language._ | | Eh, I don't think I can agree. There are definitely more | important things about a language than syntax, but a language | with a great syntax can be a lot more enjoyable to use, | particularly when reading a lot of code. Prior to learning Ruby | I would have agreed with you, but since Ruby and Elixir, the | syntax adds much to my enjoyment of working with the language. | When I think of ES7 v. ES5 I feel the same way as well. You can | do everything in ES5, but in ES7 the syntactical sugar makes it | so much more enjoyable. | phist_mcgee wrote: | I've found newbie JS devs do confuse the meanings of `=>` and | `function` to mean the same thing in JS and think that it's | just a sugar. I wonder if there's a nice way to 'unfold' | sugars via a linter or something to explain in code the | subtleties. | bmitc wrote: | Interesting, because I find Elixir's syntax to be rather | busy, especially coming to it from F#. I love Elixir and | Erlang, but Ruby's influence on Elixir is probably my least | favorite thing about Elixir. | mattpallissard wrote: | I think your comment is the most accurate depiction of the | warts. | | Yeah, the standard library is inconsistent, and they don't seem | keen to merge in some features when they're readily available | in other libraries. Plus there are some odd implementation | details in the Unix module (for example, read/write and | friends) at the C level that don't seem to get much traction on | fixing despite fairly clear paths to resolution. | | I personally don't care about the difference between binding | something to a variable and the infix operator. | | What I don't like are the multiple concurrency stories, this is | similar to the problem seen with the standard library vs | janestreet's. Although with the module system being what it is | it's usually not too big a deal to support either concurrency | library (even though some libraries force you to use one or the | other). | | Although I'm hopeful that with multicore finally being a real | thing, the community will settle on a single concurrency | library that can be pulled into the standard library in the | future. | | Despite the issues, it is still my favorite language. | devmunchies wrote: | syntax doesn't typically matter as long as you are at least as | productive as in other languages. i.e. if editors can do the | same things with keybindings. | | The problem with the (* *) comments is that I can select a | block of text, a portion of which is already commented out, and | commented the whole selection. You can't solve this without | lossy commenting (e.g. removing the inner comment). The portion | that is already commented will screw it up. This doesn't matter | in single line comments since it will just add an additional | "//" in front of a commented line. | pie_flavor wrote: | Does OCaml not have nested comments? Typically a language | supporting /* */ will treat them like parentheses and require | each opener to match a closer. (Not that this doesn't make | documenting the behavior of files/static/* harder - hence | Rust and C# preferring to document with line comments.) | octachron wrote: | OCaml has nested comments (and comments are also aware of | string literals). Thus any fragments of valid OCaml code | can be commented without changes. In other words, the whole | line below is commented-out. (* let x = | "*)" (* inner comment *) *) | folmar wrote: | > Typically a language supporting /* */ will treat them | like parentheses | | This is not the case for C, C++ or JavaScript for a start. | 0x457 wrote: | Syntax is what you deal with every time you read or write in | any language. It can't be "the least important". It's probably | one of the most important part when you _read_ the code, and | reading the code is an important part of programming. | | Just take a look at this: [1, 2; 3, 4] | | is the same as: [(1, 2); (3, 4)] | | That's just hard to read. I don't mind `;` being a separator, | but tuples without parentheses is just annoying to look at in | 9/10 places. | Quekid5 wrote: | There was a Revised Syntax (not sure if it's still a thing) | which smooths out some of the most egregious warts. It | requires preprocessing, but it was part of the standard | distribution last I looked. | | The most egregious for me was actually ;; being so close to ; | to type and you'd be staring at weird type errors for ages | before realizing what had gone wrong. I realize that this may | be hard to convey to people who haven't used OCaml, but: The | ;; terminates a top-level definition -- which was usually | type-inferred when I was using OCaml... so it would lead to | all sorts of "weird" type errors, when all that was missing | was a simple ; | | EDIT: Just for context, last looked (seriously) at OCaml ~15 | years ago, last wrote it ~20+ years ago. It's cool, but it | ended up just being my gateway drug to Haskell... for which I | thank it :) | yodsanklai wrote: | I agree the second form is preferable to the first one. But I | think, most people will use the second form anyway. In my | projects, ocamlformat chooses the second option. | | In the case of OCaml, we can certainly find a few oddities, | but really, I never found the OCaml syntax to be such an | issue or to make me unproductive in any way. I'm much more | prone to syntax errors in Haskell actually. | | I suspect people who complain are mostly used to C-like | syntax and aren't familiar with any language of the ML | tradition. I agree that the barrier to entry would be lower | if the syntax was more "mainstream", but I don't find there's | really anything wrong with OCaml syntax, except that it's | "different". | 0x457 wrote: | Oh, I don't think Ocaml syntax is an issue at all, I like | most of it. I'm saying that, syntax isn't the least | important part of a language - look at how many languages | compile to JavaScript without bringing anything new ("new" | being something like types in TypeScript). | | > I suspect people who complain are mostly used to C-like | syntax and aren't familiar with any language of the ML | tradition | | Yes, that's probably it. Can't really blame them - C, C++, | Java, C#, PHP been very popular for long time. When I first | saw Erlang, I thought it's a language for aliens. | kevinmgranger wrote: | I can't say I'm very familiar with OCaml, but I'm excited to | see where multicore takes it regarding your second point. | goto11 wrote: | > I'm surprised people care about the syntax... that's pretty | much the least important part of the language. | | The syntax is the user interface of a language. It matters. | dmitriid wrote: | > I'm surprised people care about the syntax... that's pretty | much the least important part of the language. | | Until the syntax starts impeding with your understanding of the | code, or is impossible to look up in documentation/google. | | OCaml IMO is a bit over the line with the number of ascii art | used. | | I definitely agree with your other points. Though I only | touched OCaml very briefly. | lou1306 wrote: | I feel like F# addresses quite a few items on the "dislike" list: | | * It has // for single-line comments | | * You can use newlines as a list separator, as in: | let some_list = [ 1 2 3 ] | | * Similarly, multiple let-bindings can be separated by newlines | and the "in" is optional in most cases | | This comes from some drawbacks: for starters, when I mention | "newlines", it's actually significant whitespace, so you may or | may not like it (as a heavy Python user, I just don't care). | devmunchies wrote: | Yes, and if you use a code formatter, like Fantomas, it can | automatically modify code to be in the more legible format | (like Prettier.js), so you don't confuse tuples with list | elements. | | I've been using f# for a couple years, and after the honeymoon | phase is over, I've started to really value the benefit of | native interop with dotnet libraries. | | Most enterprise SDKs/libraries (e.g. AWS S3, Stripe, Twilio, | Rollbar, etc) have a dotnet SDK, and it just drops into an F# | codebase as if it were a 1st party lib (you reference them | using object-oriented dot notation instead of functional style, | but still it just works). | | Even when Microsoft puts work into, for example, cryptography | security updates or JSON parsing performance, F# benefits from | that. | yallop wrote: | > Things I Disliked > [...] > * using ; heavily as | element separator (e.g. in lists and records): > > | let some_list = [1; 2; 3; 4; 5] > > You get used | to this, but it's a pretty big departure from the norm to use | commas. I wonder what's the reasoning behind this. | | It appears to be a result of the limitations of early parser | technology, as Dave MacQueen explains: "One of | the kind of interesting things is that the parser was written | based on Vaughan Pratt's precedence parser [...] and it had the | peculiar property that it was hard to reuse symbols for multiple | syntactic purposes, and hence you get things like comma used for | pairing that means you have to use semicolon for list separator, | that means you have to use semicolon-semicolon for statement | separator, so there's some peculiarities based on the fact that | we didn't really know how to parse and we accepted this quick | hack from Vaughan Pratt" | (https://www.youtube.com/watch?v=ua3EYopCURo&t=179s) | acjohnson55 wrote: | My biggest frustration with OCaml is having to deal with all of | that cruft. I've learned many languages over the years, and I | think I've just reached the point where I've lost patience with | having to deal with what I would consider substandard syntactic | elegance. | cardanome wrote: | I don't mind the cruft. I think a bit of harmless quirks can | give a language character. | | It actually makes the learning easier. Now that I know the | story why, I have memorized how elements are seperated in | OCaml for probably the rest of my life. I just need to | remember the story. | | Plus not reusing symbols for multiple syntactic purposes | actually fits nicely into the general Ocaml philosophy. Plus | is makes my complexity-hating, minimalist heart happy. | | Though I am at that point in my life where I don't really | care about syntax that much to begin with. Yes syntactic | complexity matters. How fast it can be parsed, how easy | macros are implemented, these things can matter but the | actual syntax: boring. White-space sensitive or not, curly | braces or begin/end and all that stuff is so dull. I am happy | with whatever. | p4bl0 wrote: | If using semicolons instead of commas is enough of a | showstopper for you it's probably that you just don't have a | need for the language :). | WastingMyTime89 wrote: | Yes but OCaml syntax is Pascal inspired. It's always going to | be a lot more elegant that anything inspired by the horror | that is the B syntax. It's just less familiar to people who | grew up using C, Java or JavaScript. | tialaramex wrote: | This sort of thing is why Rust's Editions are great and why | Vittorio Romeo's Epochs (P1881) for C++ would have been the | right choice. | | I like Editions because of the cultural consequences, Rust's | community assumes they _can_ fix things and so they set out | with that goal, even in cases where Editions won 't quite do | it - while the C++ community tends to accept the state of the | language as a static fact and just "take it". But this sort | of thing isn't about the cultural effects, it's a direct | technical achievement. | | If OCaml had Editions, it could say OK, that syntax was a bit | rubbish, here's 2023 syntax which fixes two things everybody | hated, get back to us over the next few years and we'll | decide if there are further changes needed. _Without_ losing | all existing OCaml software or demanding expensive rewrites. | | Even better, changes of the sort in Editions are mechanical. | It can take a bit of creative work to do it _nicely_ but the | transformations can be automated, so people who have "old | OCaml" and wish they had "new OCaml" can push a button and | get on with their day. Having both this and the feature which | keeps old code working unchanged, add up to an experience | where the community can move forward, on syntax at least, and | not be trapped with yesterday's mistakes. | zumu wrote: | The syntax is a little unorthodox, but just having a literal | syntax _at all_ for things like lists/arrays beats having to | call `new` on some random class you have to import and then | doing a bunch of in place updates to add all the data. | dmitriid wrote: | In this respect C# has knocked it out of the park with | shorthand initialisation syntax for arrays and objects. But | it's newer and could look at what other languages are | doing/not doing in that regard. | toolslive wrote: | what's your stance on the curly braces (which is also a | consequence of early parser technology) ? | galangalalgol wrote: | What are some good alternatives? I don't find begin and end | as easy to spot at a glance if the indentation is off. I'm | not sure why I don't like indentation based, but I don't in | practice. A good IDE helps me care less, and I don't think | I could write python well without a good IDE anyway. | acjohnson55 wrote: | I think they're often helpful for reading, but I admire | what Scala did in Scala 3 to eliminate their necessity. | yawaramin wrote: | Scala 3 actually doesn't really eliminate braces in any | meaningful way. Sure, they're optional for delimiting | traits, classes, and objects. But braces are heavily used | for block scoping in Scala too. E.g. a very common | pattern: retry(Seq(1.second, 2.second, | 3.second)) { // some action that can fail | } | | This still requires the braces as of right now. I think | the syntax changes will just confuse more people than it | helps, at least for the time being. | AzzieElbab wrote: | That is a curried parameter in {}. Those braces are not | for scoping. They basically define a lambda. You can | probably use () instead | | you can also use import language.experimental.fewerBraces | with nightly builds to write code like this | | List(1,2,3).map: c => ... | tomp wrote: | No, it's actually because , (comma) denotes a tuple. | [1, 2; 3, 4] | | is a list of tuples, of type (int * int) list, equivalent to | [(1, 2); (3, 4)] | cwzwarich wrote: | This phenomenon is actually another example of the phenomenon | he mentions. In strict precedence parsing, operators are | assigned meaning rather than productions of a grammar (which | would could those operators in distinct contexts), so once | you've decided a comma indicates a tuple, it's easier to just | allow this syntax. | Athas wrote: | I never understood the motivation for allowing tuples without | surrounding parens. There are a few very simple functions | that look cuter this way, but it constantly trips me up in | more complex situations. | a-nikolaev wrote: | No parentheses can be nice for cleaner pattern matching, | e.g. something like this: match a, b with | | 1, 2 -> x | _ -> y | goodoldneon wrote: | The "comma makes a tuple" behavior is a big gotcha I've | experienced in Python. I wish that behavior didn't exist | LynxInLA wrote: | Which version of that are you talking about in Python? The | biggest related gotcha I've seen in Python is when you have | a trailing comma `x = 1,` and accidentally create a tuple. | goodoldneon wrote: | Yea that's the most common gotcha | tshaddox wrote: | The article briefly mentions ReasonML, which offers a different | syntax which aims to be more familiar to JavaScript programmers | but is also likely to be more familiar to most programmers of | C-family languages. | | There's also ReScript, which is a very similar alternate syntax | which sort of split off from the ReasonML community in a | confusing and complicated sequence of events which is | frustrating to try to follow for someone who was just | interested in the programming language and tooling: | https://rescript-lang.org/blog/bucklescript-is-rebranding | dmitriid wrote: | That split was really bad. At the height if its popularity | (yes, there was a brief moment in the sun) it was also | influencing the OCaml community IIRC, bringing improvements | like friendly error messages and syntax improvements. | | Now though... Who cares about either of the Re* languages? | sairion wrote: | I think ReScript community is pretty active right now, I | have big expectations about future 10.x releases (I'm | working for a company uses ReScript as a main programming | language) there are less buzz recently though. | kn8 wrote: | ReScript community is well and alive and is actively | working on improving the ReScript compiler and tooling. V10 | just came out with records with optional fields - | https://forum.rescript-lang.org/t/ann- | rescript-v10-released/.... Async/await is in the works. The | language is really really good (especially say comparing to | TypeScript). Make sure to check it out. | splintercell wrote: | ReScript is amazing. I really don't know much about the | split (it's not like I didn't try to understand it, I just | can't understand the anger of non-Ocaml developers at the | split). | | Rescript allows me to write Javascript in a sound type | system, while remaining very close to how you would write | code in Javascript. | | Rescript to me feels like Typescript + a very prescriptive | linting system which prevents a lot of problems, and since | the linting system wouldn't let you do certain things, | might as well get rid of them from the Type checker, this | results in a much faster compiler. | sairion wrote: | I have been using ReScript for (almost) a year as a | production programming language. There were a few | limitations and confusions at first, (and I don't think | it will be replacing TypeScript in any near future) but I | can't even think about going back to a work environment | uses TypeScript, the dev experience is so good :) | rtlfe wrote: | > The article briefly mentions ReasonML, which offers a | different syntax which aims to be more familiar to JavaScript | programmers but is also likely to be more familiar to most | programmers of C-family languages. | | One thing I don't like about this is that they've replaced: | | > let x = 1 in | | with | | > let x = 1; | | In plain OCaml you only use semicolons on lines that evaluate | to unit, so they're a clear indicator that you've done | something with side effects. ReasonML loses this useful | visual distinction in order to look more like JavaScript. | cheriot wrote: | Agree. ReasonML threw the baby out with the bathwater. If | ever there's a language to not immatate it's Javascript. | | Would be interesting to see a something that updated some | ocaml quirks, but stayed true to the spirit of the syntax. | Ie comments and multiply but not ; | dustingetz wrote: | How is macros or metaprogramming or anything that fills a similar | role? | toolslive wrote: | there's BER MetaOCaml | | https://okmij.org/ftp/ML/MetaOCaml.html | sleepydog wrote: | Not great, not terrible; the language supports annotations | which mean nothing to the compiler but which pre-processors can | take advantage of, and there is a framework called ppx which | you can use to write your own preprocessor. There exist many | pre-processors to do things like add inline tests, generate | getter/setter/pretty-printing functions, and so on. Here is an | example: | | https://github.com/ocaml-ppx/ppx_deriving ___________________________________________________________________ (page generated 2022-08-29 23:00 UTC)