[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)