[HN Gopher] OxCaml - a set of extensions to the OCaml programmin...
       ___________________________________________________________________
        
       OxCaml - a set of extensions to the OCaml programming language.
        
       Author : lairv
       Score  : 237 points
       Date   : 2025-06-13 14:20 UTC (8 hours ago)
        
 (HTM) web link (oxcaml.org)
 (TXT) w3m dump (oxcaml.org)
        
       | legobmw99 wrote:
       | The first feature that originated in this fork to be upstreamed
       | is labeled tuples, which will be in OCaml 5.4:
       | 
       | https://github.com/ocaml/ocaml/pull/13498
       | 
       | https://discuss.ocaml.org/t/first-alpha-release-of-ocaml-5-4...
        
         | debugnik wrote:
         | Immutable arrays were ported from this fork as well, and merged
         | for 5.4; although with different syntax I think.
        
         | andrepd wrote:
         | Anonymous labeled structs and enums are some of my top wished-
         | for features in programming languages! For instance, in Rust
         | you can define labelled and unlabelled (i.e. tuple) structs
         | struct Foo(i32, i32);         struct Bar{sum: i32, product:
         | i32}
         | 
         | But you can only e.g. return from functions an anonymous tuple,
         | not an anonymous labelled struct                   fn can() ->
         | (i32, i32)         fn cant() -> {sum: i32, product: i32}
        
           | tialaramex wrote:
           | Hmm. Let me first check that I've understood what you care
           | about                   struct First(this: i8, that: i64)
           | struct Second(this: i8, that: i8)         struct Third(that:
           | i64, this: i8)         struct Fourth(this: i8, that: i64)
           | struct Fifth(some: i8, other: i64)
           | 
           | You want First and Fourth as the same type, but Second and
           | Third are different - how about Fifth?
           | 
           | I see that this is different from Rust's existing product
           | types, in which First and Fourth are always different types.
           | 
           | Second though, can you give me some examples where I'd want
           | this? I can't say I have ever wished I had this, but that
           | might be a different experience.
        
             | cAtte_ wrote:
             | they're not asking for a structural typing overhaul, just a
             | way to make ad-hoc anonymous types with named fields and
             | pass them around. a lot of times with tuple return types
             | you're left wondering what that random `usize` is supposed
             | to represent, so having names for it would be very
             | convenient. i don't see why, under the hood, it couldn't
             | just be implemented the exact same way as current tuple
             | return types
        
               | zozbot234 wrote:
               | > they're not asking for a structural typing overhaul,
               | just a way to make ad-hoc anonymous types with named
               | fields and pass them around.
               | 
               | And their point is that the two boil down to the same
               | thing, especially in a non-trivial program. If switching
               | field positions around changes their semantics, tuples
               | may well the most sensible choice. As for "what that
               | random usize is supposed to represent" that's something
               | that can be addressed with in-code documentation, which
               | Rust has great support for.
        
               | tialaramex wrote:
               | Also, if it's _not_ just a  "random usize" then you
               | should use the new type paradigm. In a language like Rust
               | that's not _quite_ as smooth as it could possibly be, but
               | it 's transparent to the machine code. Rust's
               | Option<OwnedFd> is the same _machine code_ as C 's int
               | file descriptor, but the same _ergonomics_ as a fancy
               | Haskell type. We can 't accidentally confuse "None, there
               | isn't a file descriptor" for an actual file descriptor as
               | we so easily could in C, nor can we mistakenly do
               | arithmetic with file descriptors - which is nonsense but
               | would work (hilarity ensues) in C.
               | 
               | If these aren't "random" usizes but FileSizes or
               | ColumnNumbers or SocketTimeouts then say so and the
               | confusion is eliminated.
        
           | munificent wrote:
           | In Dart, we merged tuples and records into a single
           | construct. A record can have positional fields, named fields,
           | or both. A record type can appear anywhere a type annotation
           | is allowed. So in Dart these are both fine:
           | (int, int) can() => (1, 2);         ({int sum, int product})
           | alsoCan() => (sum: 1, product: 2);         (int, {int
           | remainder}) evenThis() => (1, remainder: 2);
           | 
           | The curly braces in the record type annotation distinguish
           | the named fields from the positional ones. I don't love the
           | syntax, but it's consistent with function parameter lists
           | where the curly braces delimit the named parameters.
           | 
           | https://dart.dev/language/records
        
             | afiori wrote:
             | How do you distinguish a tuple with both positional and
             | named fields from a tuple that has a record as a field
             | 
             | Like how do you write the type of (1, {sum:2}) ? Is it
             | different from (1 , sum :2)?
        
               | munificent wrote:
               | The syntax is a little funny for mostly historical
               | reasons. The curly braces are only part of the record
               | _type_ syntax. There 's no ambiguity there because curly
               | braces aren't used for anything else in type annotations
               | (well, except for named parameters inside a function
               | type's parameter list, but that's a different part of the
               | grammar).
        
           | int_19h wrote:
           | It's interesting that languages which start with purely
           | nominal structs tend to acquire some form of structurally
           | typed records in the long run. E.g. C# has always had
           | (nominally typed) structs, then .NET added (structurally
           | typed) tuples, and then eventually the language added (still
           | structurally typed) tuples with named items on top of that.
        
           | munk-a wrote:
           | PHP has it all!
           | 
           | I think the main dividing line here is whether you want to
           | lean into strict typing or whether you prefer a more loose
           | typing structure. The extremes of both (where, for instance,
           | the length of an array is part of its type definition or
           | there are not contractual guarantees about data) are both
           | awful. I think the level of type strictness you desire as a
           | product is probably best dictated by team and project size
           | (which you'll note changes over the lifetime of the product)
           | with a lack of typing making it much easier to prototype
           | early code while extremely strict typing can serve as a
           | strong code contract in a large codebase where no one person
           | can still comprehend the entirety of it.
           | 
           | It's a constant push and pull of conflicting motivations.
        
         | aseipp wrote:
         | Yeah, pretty excited about this one even though it seems minor.
         | A paper and talk by the author of this particular feature from
         | ML2024, too:
         | 
         | - https://www.youtube.com/watch?v=WM7ZVne8eQE
         | 
         | - https://tyconmismatch.com/papers/ml2024_labeled_tuples.pdf
        
         | munchler wrote:
         | > Because sum:int * product:int is a different type from
         | product:int * sum:int, the use of a labeled tuple in this
         | example prevents us from accidentally returning the pair in the
         | wrong order, or mixing up the order of the initial values.
         | 
         | Hmm, I think I like F#'s anonymous records better than this.
         | For example, {| product = 6; sum = 5 |}. The order of the
         | fields doesn't matter, since the value is not a tuple.
        
           | rwmj wrote:
           | Isn't that just the same as the ordinary OCaml { product = 6;
           | sum = 5 } (with a very slightly different syntax)?
        
             | munchler wrote:
             | The difference between { ... } and {| ... |} is that the
             | latter's type is anonymous, so it doesn't have to be
             | declared ahead of time.
        
               | rwmj wrote:
               | Oh I see, good point. I'm wondering how this is
               | represented internally. Fields alphabetically? I've also
               | desired _extensible_ anonymous structs (with defaults)
               | from time to time, but implementing that would involve
               | some kind of global analysis I suppose.
        
       | IshKebab wrote:
       | So this is "oxidized" because it tries to achieve the same
       | features as Rust (e.g. "fearless concurrency" is mentioned, and
       | avoiding GC)... Not because it actually uses Rust in any way
       | right? Slightly confusing.
        
         | debugnik wrote:
         | Correct, Jane Street has been publishing a series of blog posts
         | titled "Oxidizing OCaml" for a while.
        
         | zozbot234 wrote:
         | Rust will probably become usable with custom tracing GCs (which
         | is helpful if you're dealing with general graph-like data but
         | still want the highest performance as far as practical) way
         | before this effort reaches genuine feature parity with Rust.
         | Not seeing much of a point in this, unless they perhaps intend
         | to focus on the lowest-hanging fruit and have big O(x)Caml
         | codebases that they care about.
        
           | greener_grass wrote:
           | OxCaml takes a different approach to encoding locality to
           | Rust. Rust (arguably) overburdens the type-system with this
           | information whilst in OxCaml this is orthogonal to the return
           | types. In that sense it's a bit like algebraic effects.
           | Personally I'm quite bullish on OCaml these days.
        
           | aseipp wrote:
           | > Not seeing much of a point in this
           | 
           | OCaml is a good language and these extensions are very
           | welcome to existing OCaml programmers and programs, as well
           | as many of the other extensions Jane Street has added. I
           | don't understand what you mean here.
        
             | zozbot234 wrote:
             | > > Not seeing much of a point in this
             | 
             | > ...I don't understand what you mean here.
             | 
             | Yeah it seems there was a mistake there, it looks like my
             | comment got cut off while you were reading it. Try
             | reloading the page maybe?
        
               | aseipp wrote:
               | Your comment remains completely stupid regardless of how
               | much of it is in the quote. OxCaml's goal is to be
               | upstreamed. "I don't see the point in this unless people
               | have programs using OCaml" and it's like, yeah, that's
               | the point of adding features to a computer program. Any
               | computer program. Because people already use the computer
               | program and it will be useful to them.
        
         | aseipp wrote:
         | Yes, they've used this terminology for a while, even the recent
         | technical paper on this effort was titled "Oxidizing OCaml with
         | Modal Memory Management", though the word "oxidize" itself is
         | never actually referenced or defined in the paper. A bit
         | strange, I agree, though it's kind of catchy I admit.
        
         | john-h-k wrote:
         | It's ironic of course because Rust (the language) is named
         | after the fungus called Rust, rather than iron-oxide
        
       | avsm wrote:
       | If anyone's trying out the new opam switch, I found it helpful to
       | use:
       | 
       | env OCAMLPARAM="alert=-unsafe_multidomain,_," opam install
       | cohttp-lwt-unix
       | 
       | Because alerts are promoted to errors, they break existing
       | package installs unnecessarily. The OCAMLPARAM environment
       | variable just forces that alert to be disabled and allows the
       | package installation to continue.
        
       | Lyngbakr wrote:
       | The Janet Street folks, who created this, also did an interesting
       | episode[0] of their podcast where they discuss performance
       | considerations when working with OCaml. What I was curious about
       | was applying a GC language to a use case that must have extremely
       | low latency. It seems like an important consideration, as a GC
       | pause in the middle of high-frequency trading could be
       | problematic.
       | 
       | [0] https://signalsandthreads.com/performance-engineering-on-
       | har...
        
         | enricozb wrote:
         | Haven't looked at the link, but I think for a scenario like
         | trading where there are market open and close times, you can
         | just disable the GC, and restart the program after market
         | close.
        
           | spooneybarger wrote:
           | It is a common strategy.
        
         | rauljara wrote:
         | GC compactions were indeed a problem for a number of systems.
         | The trading systems in general had a policy of not allocating
         | after startup. JS has a library, called "Zero" that provides a
         | host of non-allocating ways of doing things.
        
           | jitl wrote:
           | Couldn't find this after 6 seconds of googling, link?
        
             | jallmann wrote:
             | The linked podcast episode mentions it.
        
               | notnullorvoid wrote:
               | There's no mention of a library called zero, or even
               | JavaScript.
        
               | garbthetill wrote:
               | Im assuming the JS refers to Janes street
        
               | notnullorvoid wrote:
               | That makes sense, I guess I've got web tunnel vision.
        
               | jallmann wrote:
               | > This is what I like to call a dialect of OCaml. We
               | speak in sometimes and sometimes we gently say it's zero
               | alloc OCaml. And the most notable thing about it, it
               | tries to avoid touching the garbage collector ...
        
         | mardifoufs wrote:
         | You just let the garbage accumulate and collect it whenever
         | markets are closed. In most cases, whenever you need ultra low
         | latency in trading, you usually have very well defined time
         | constraints (market open/close).
         | 
         | Maybe it's different for markets that are always open (crypto?)
         | but most HFT happens during regular market hours.
        
           | dmkolobov wrote:
           | Is that really a viable solution for a timeframe of 6+ hours?
        
             | logicchains wrote:
             | You can just add more RAM until it is viable.
        
             | jitl wrote:
             | Sure, if you know how much you allocate per minute (and
             | don't exceed your budget) you just buy enough RAM and it's
             | fine.
        
               | mayoff wrote:
               | (this comment was off topic, sorry)
        
               | robertlagrant wrote:
               | Is this relevant to OCaml?
        
               | mayoff wrote:
               | ha ha oops I got confused
        
               | ackfoobar wrote:
               | This will decrease performance because of reduced
               | locality. Maybe increased jitter because of TLB misses.
        
             | spooneybarger wrote:
             | Yes. It is a very common design pattern within banks for
             | systems that only need to run during market hours.
        
               | iainctduncan wrote:
               | I talk about doing this in an audio context and get met
               | with raised eyebrows, I'd love some references on others
               | doing it, if anyone can share!
        
         | great_wubwub wrote:
         | *Jane Street
        
       | debugnik wrote:
       | I wasn't aware that this fork supported SIMD! Between this,
       | unboxed types and the local mode with explicit stack allocation,
       | OxCaml almost entirely replaces my past interest in F#; this
       | could actually become usable for gamedev and similar consumer
       | scenarios if it also supported Windows.
        
         | TheNumbat wrote:
         | Yeah, this would be great! Currently only 128-bit SSE/NEON is
         | working but AVX is coming very soon. There's also nothing
         | blocking Windows, but it will require some work. (I added the
         | SIMD support in OxCaml)
        
           | aseipp wrote:
           | FWIW, the "Get OxCaml" page actually says that SIMD on ARM
           | isn't supported yet. If it actually works it would be worth
           | removing that from the known issues list
           | https://oxcaml.org/get-oxcaml/
        
             | TheNumbat wrote:
             | Indeed, it says that because we don't have a library of
             | NEON intrinsics (like ocaml_simd_sse) yet, but the
             | extension itself works.
        
               | aseipp wrote:
               | Ah, that clears it up a bit. Thanks! Looking forward to
               | all of this. (For the interested readers, here's the SSE
               | library:
               | https://github.com/janestreet/ocaml_simd/tree/with-
               | extension...)
        
           | debugnik wrote:
           | Cool to hear there aren't any technical blockers to add
           | Windows support! You just convinced me into giving OxCaml a
           | try for a hobby project. 128-bit SSE is likely to be enough
           | for my use case and target specs.
        
             | avsm wrote:
             | David Allsopp had an oxcaml branch compiling on Windows a
             | few months ago, so it's in the queue...
        
       | croes wrote:
       | So OxCaml is the extension of the extension of a dialect of ML.
       | 
       | Can't wait for the next level
        
         | munchler wrote:
         | Can I interest you in F#?
        
         | jasperry wrote:
         | I had a similar thought to this, but then I thought, who is
         | worse: programmers who keep bloating up existing languages with
         | new features, or programmers who create yet another new
         | language to add to the already crowded field? (I'm in that
         | latter category.)
         | 
         | I guess programmers are just genetically incapable of leaving
         | their tools the way they are.
        
       | anthk wrote:
       | OcaML's micro cousin:
       | 
       | http://t3x.org/mlite/index.html
        
       | iLoveOncall wrote:
       | The sunk cost fallacy at Jane Street is strong.
        
         | ackfoobar wrote:
         | Maybe it's sunk cost fallacy for them. But without them there
         | wouldn't be a language that gets me 80/20 benefit/effort of
         | Rust.
        
           | fuzztester wrote:
           | what is the sunk cost fallacy in the Jane Street case?
        
             | ackfoobar wrote:
             | I said "maybe" as granting the root comment's premise - I
             | don't believe that.
        
         | abathologist wrote:
         | What are you talking about?
        
           | wk_end wrote:
           | The implication here, I think, is that "Jane Street has
           | foolishly invested heavily into Ocaml and, rather than
           | sensibly change course and migrate away, they continue to
           | invest heavily into it in the hopes that one day the
           | investment will pay off."
           | 
           | Which is a ridiculous take: Jane Street has done
           | extraordinarily well for themselves, possibly at least in
           | part because of their investment in Ocaml, and any sort of
           | migration would be a huge undertaking, and an absurd and
           | unnecessary risk.
        
         | umanwizard wrote:
         | Wait til you hear about PHP at Meta...
        
           | agumonkey wrote:
           | did they talked about it publicly ? i stopped following
           | around the hiphop vm era
        
       | dingdingdang wrote:
       | Probably spoilt here but being used to the excellent vscode
       | plugin (well vscodium in my case) for Golang but... any plans to
       | integrate with vscode ecosystem? Makes setup so straightforward!
        
         | jasperry wrote:
         | The OCaml vscode plugin seems to have already integrated a lot
         | of new syntaxes (dune, menhir, reason), so if OxCaml gains
         | traction it should only be a matter of time.
         | 
         | (can't really speak for that myself, though, I use emacs)
        
       ___________________________________________________________________
       (page generated 2025-06-13 23:00 UTC)