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.
Does Go have much in the way of GC knobs? It didn't some years ago, but I haven't kept up on latest developments
pjmlp1 hour ago
The knobs aren't on the GC necessarily, rather language features.
With a Go compiler toolchain you have stack and global memory static allocation, use of compiler flags to track down when references escape, manually allocate via OS bindings, there is the unsafe package, and use slices with it, an assembler is part of the toolchain learn to use it, and regardless of CGO is not Go memes, it is another tool to reach for if Assembly isn't your thing.
NaN years ago
undefined
AdieuToLogic7 hours ago
> 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.
Regarding a run-time environment using garbage collection in general, not OCaml specifically, GC pauses can be minimized with parallel collection algorithms such as found in the JVM[0]. They do not provide hard guarantees however, so over-provisioning system RAM may also be needed in order to achieve required system performance.
Another more complex approach is to over-provision the servers such that each can drop out of the available pool for a short time, thus allowing "offline GC." This involves collaboration between request routers and other servers, so may not be worth the effort if a deployment can financially support over-provisioning servers such that there is always an idle CPU available for parallel GC on each.
Java is like C and C++, there isn't the one implementation.
So if you want hard guarantees, you reach out to real time JVM implementations like the commercial ones from PTC and Aicas.
rauljara17 hours ago
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.
jitl17 hours ago
Couldn’t find this after 6 seconds of googling, link?
jallmann16 hours ago
The linked podcast episode mentions it.
NaN years ago
undefined
enricozb17 hours ago
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.
spooneybarger15 hours ago
It is a common strategy.
great_wubwub13 hours ago
*Jane Street
esafak9 hours ago
It's a great name for a competitor :)
mardifoufs17 hours ago
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.
dmkolobov17 hours ago
Is that really a viable solution for a timeframe of 6+ hours?
jitl16 hours ago
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.
NaN years ago
undefined
NaN years ago
undefined
spooneybarger15 hours ago
Yes. It is a very common design pattern within banks for systems that only need to run during market hours.
NaN years ago
undefined
NaN years ago
undefined
NaN years ago
undefined
amw-zero7 hours ago
Are you aware of how many allocations the average program executes in the span of a couple of minutes? Where do you propose all of that memory lives in a way that doesn’t prevent the application from running?
legobmw9919 hours ago
The first feature that originated in this fork to be upstreamed is labeled tuples, which will be in OCaml 5.4:
> 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.
reycharles5 hours ago
One reason why they're not the same is because the memory representation is different (sort of). This will break FFIs if you allow reordering the tuple arbitrarily.
rwmj16 hours ago
Isn't that just the same as the ordinary OCaml { product = 6; sum = 5 } (with a very slightly different syntax)?
NaN years ago
undefined
debugnik18 hours ago
Immutable arrays were ported from this fork as well, and merged for 5.4; although with different syntax I think.
andrepd18 hours ago
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
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:
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.
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.
NaN years ago
undefined
int_19h13 hours ago
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-a13 hours ago
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.
debugnik18 hours ago
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.
TheNumbat18 hours ago
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)
aseipp17 hours ago
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/
NaN years ago
undefined
debugnik17 hours ago
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.
NaN years ago
undefined
avsm19 hours ago
If anyone's trying out the new opam switch, I found it helpful to use:
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.
WEwWGH3U5L18 hours ago
[dead]
dingdingdang12 hours ago
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!
jasperry11 hours ago
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)
clancon7 hours ago
If you follow the installation instructions on oxcaml.org, you’ll get a patched Merlin with LSP support etc. It’s not perfect, but does mostly work out of the box with VSCode and the OCaml Platform extension.
NaN years ago
undefined
bhamta6 hours ago
What are the chances that they are releasing this so that LLMs can index this information for free and they can use public models in their codebase rather than finetuning public models?
debugnik2 hours ago
Given how poor LLMs are at regular OCaml, which has so much more training data that OxCaml, probably none. An MCP for docs would have been more productive for that purpose.
So OxCaml is the extension of the extension of a dialect of ML.
Can’t wait for the next level
jasperry11 hours ago
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.
debugnik4 hours ago
This did actually halt my hobby programming language project, whose features overlap a lot and is advancing slowly anyway.
At the very least I'll give OxCaml a try to compare. Best case I drop mine and use this, worst case I learn what works and what doesn't.
munchler17 hours ago
Can I interest you in F#?
IshKebab19 hours ago
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.
john-h-k16 hours ago
It's ironic of course because Rust (the language) is named after the fungus called Rust, rather than iron-oxide
debugnik19 hours ago
Correct, Jane Street has been publishing a series of blog posts titled "Oxidizing OCaml" for a while.
aseipp17 hours ago
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.
zozbot23418 hours ago
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_grass17 hours ago
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.
aseipp17 hours ago
> 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.
NaN years ago
undefined
JHONWALTER16 hours ago
[dead]
WEwWGH3U5L18 hours ago
[dead]
iLoveOncall15 hours ago
The sunk cost fallacy at Jane Street is strong.
toolslive3 hours ago
You can also argue it's "Stockholm syndrome".
Anyway,it's funny how opinions differ: I still consider Rust to be a poor man's OCaml.
ackfoobar15 hours ago
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.
fuzztester12 hours ago
what is the sunk cost fallacy in the Jane Street case?
NaN years ago
undefined
phplovesong2 hours ago
Why? They have one of the largest Ocaml codebases in the world. It has clearly work out VERY well for them, in terms of productivity and pure ROI in features and revenue.
Ocaml has so much good going on, even being a less known language.
I assume you are a rust fanboy, and i want to see just how long your smirk holds when you compile a 20M LOC project that takes 45 minutes.
iLoveOncall49 minutes ago
I've never written a line of Rust in my life, but I unfortunately had the great displeasure to write OCaml.
OCaml is a terrible choice for (anyone) a company like this. They NEED to be able to hire the very best of the best, but choosing an exotic language that is less palatable than a plate of shit and more cryptic than alien hieroglyphs restricts your talent pool A LOT.
I'm not saying people cannot learn it, I'm saying people won't want to, for multiple very good reasons (it sucks, it's not at all transferable skill, etc.).
umanwizard14 hours ago
Wait til you hear about PHP at Meta...
agumonkey13 hours ago
did they talked about it publicly ? i stopped following around the hiphop vm era
abathologist14 hours ago
What are you talking about?
wk_end11 hours ago
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.
NaN years ago
undefined
NaN years ago
undefined
reverseblade26 hours ago
Just use F# for sake
debugnik4 hours ago
I actually see this as an escape opportunity for F#-ers. I love the language, but the runtime and C# ecosystem are not only holding it back from having cleaner semantics (until the C# team sees the value in them), they've been actively kicking it down the ladder with breaking changes and new incompatible APIs.
reverseblade23 hours ago
F# is mostly liberated from .net thanks to Fable. Although the compiler strictly is .net
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...
The problem is not a GC language per se, people keep putting all GC languages in the same basket.
The real issue is being a GC language, without support for explicit manipulation of stack and value types.
Want a GC language, with productivity of GC languages, with the knobs to do low level systems coding?
Cedar, Oberon language family, Modula-3, D, Nim, Eiffel, C#, F#, Swift, Go.
Does Go have much in the way of GC knobs? It didn't some years ago, but I haven't kept up on latest developments
The knobs aren't on the GC necessarily, rather language features.
With a Go compiler toolchain you have stack and global memory static allocation, use of compiler flags to track down when references escape, manually allocate via OS bindings, there is the unsafe package, and use slices with it, an assembler is part of the toolchain learn to use it, and regardless of CGO is not Go memes, it is another tool to reach for if Assembly isn't your thing.
undefined
> 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.
Regarding a run-time environment using garbage collection in general, not OCaml specifically, GC pauses can be minimized with parallel collection algorithms such as found in the JVM[0]. They do not provide hard guarantees however, so over-provisioning system RAM may also be needed in order to achieve required system performance.
Another more complex approach is to over-provision the servers such that each can drop out of the available pool for a short time, thus allowing "offline GC." This involves collaboration between request routers and other servers, so may not be worth the effort if a deployment can financially support over-provisioning servers such that there is always an idle CPU available for parallel GC on each.
0 - https://docs.oracle.com/en/java/javase/17/gctuning/parallel-...
Java is like C and C++, there isn't the one implementation.
So if you want hard guarantees, you reach out to real time JVM implementations like the commercial ones from PTC and Aicas.
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.
Couldn’t find this after 6 seconds of googling, link?
The linked podcast episode mentions it.
undefined
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.
It is a common strategy.
*Jane Street
It's a great name for a competitor :)
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.
Is that really a viable solution for a timeframe of 6+ hours?
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.
undefined
undefined
Yes. It is a very common design pattern within banks for systems that only need to run during market hours.
undefined
undefined
undefined
Are you aware of how many allocations the average program executes in the span of a couple of minutes? Where do you propose all of that memory lives in a way that doesn’t prevent the application from running?
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...
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
> 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.
One reason why they're not the same is because the memory representation is different (sort of). This will break FFIs if you allow reordering the tuple arbitrarily.
Isn't that just the same as the ordinary OCaml { product = 6; sum = 5 } (with a very slightly different syntax)?
undefined
Immutable arrays were ported from this fork as well, and merged for 5.4; although with different syntax I think.
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
But you can only e.g. return from functions an anonymous tuple, not an anonymous labelled structIn 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:
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
undefined
Hmm. Let me first check that I've understood what you care about
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.
undefined
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.
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.
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.
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)
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/
undefined
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.
undefined
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.
[dead]
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!
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)
If you follow the installation instructions on oxcaml.org, you’ll get a patched Merlin with LSP support etc. It’s not perfect, but does mostly work out of the box with VSCode and the OCaml Platform extension.
undefined
What are the chances that they are releasing this so that LLMs can index this information for free and they can use public models in their codebase rather than finetuning public models?
Given how poor LLMs are at regular OCaml, which has so much more training data that OxCaml, probably none. An MCP for docs would have been more productive for that purpose.
OcaML's micro cousin:
http://t3x.org/mlite/index.html
So OxCaml is the extension of the extension of a dialect of ML.
Can’t wait for the next level
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.
This did actually halt my hobby programming language project, whose features overlap a lot and is advancing slowly anyway.
At the very least I'll give OxCaml a try to compare. Best case I drop mine and use this, worst case I learn what works and what doesn't.
Can I interest you in F#?
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.
It's ironic of course because Rust (the language) is named after the fungus called Rust, rather than iron-oxide
Correct, Jane Street has been publishing a series of blog posts titled "Oxidizing OCaml" for a while.
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.
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.
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.
> 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.
undefined
[dead]
[dead]
The sunk cost fallacy at Jane Street is strong.
You can also argue it's "Stockholm syndrome". Anyway,it's funny how opinions differ: I still consider Rust to be a poor man's OCaml.
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.
what is the sunk cost fallacy in the Jane Street case?
undefined
Why? They have one of the largest Ocaml codebases in the world. It has clearly work out VERY well for them, in terms of productivity and pure ROI in features and revenue.
Ocaml has so much good going on, even being a less known language.
I assume you are a rust fanboy, and i want to see just how long your smirk holds when you compile a 20M LOC project that takes 45 minutes.
I've never written a line of Rust in my life, but I unfortunately had the great displeasure to write OCaml.
OCaml is a terrible choice for (anyone) a company like this. They NEED to be able to hire the very best of the best, but choosing an exotic language that is less palatable than a plate of shit and more cryptic than alien hieroglyphs restricts your talent pool A LOT.
I'm not saying people cannot learn it, I'm saying people won't want to, for multiple very good reasons (it sucks, it's not at all transferable skill, etc.).
Wait til you hear about PHP at Meta...
did they talked about it publicly ? i stopped following around the hiphop vm era
What are you talking about?
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.
undefined
undefined
Just use F# for sake
I actually see this as an escape opportunity for F#-ers. I love the language, but the runtime and C# ecosystem are not only holding it back from having cleaner semantics (until the C# team sees the value in them), they've been actively kicking it down the ladder with breaking changes and new incompatible APIs.
F# is mostly liberated from .net thanks to Fable. Although the compiler strictly is .net
undefined