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