OCaml
ocaml.org
OCaml
@ocaml.org
Four Ps for Building Massive Collective Knowledge Systems
dlvr.it
November 27, 2025 at 3:37 PM
OCaml Weekly News
Hello Archive: https://discuss.ocaml.org/t/ann-tapak-experimental-web-framework-based-on-eio/17507/1 Syaiful Bahri announced Hello! I am a newcomer to the OCaml community, and this is my first post. I would like to share an experimental web framework I have been working on, based on Eio. I am a happy user of Dream and Opium, but I felt there was still room for improvement. I’ve shared my motivation here: https://www.sbahri.com/projects/tapak/ I would love to hear your suggestions and opinions regarding the API. What important features do you feel are missing in existing libraries? Personally, I miss the type-safe routing that Servant offers, as well as the Phoenix real-time API. Native debugging on macOS (DWARF support) Archive: https://discuss.ocaml.org/t/native-debugging-on-macos-dwarf-support/17509/1 Joel Reymont announced With DWARF v5 support, the compiler now includes proper debug info — line mappings, symbols, and variable names — so LLDB can actually follow your code. A small LLDB Python plug-in reads OCaml values at runtime and prints them in a readable form: lists, tuples, closures, strings, etc. It follows DWARF location lists to track where each variable lives and uses the runtime headers to decode them. The p and ocaml_vars commands work like normal LLDB commands but understand OCaml values. It’s not complete yet (records and variants still show as tuples), but it makes debugging native OCaml code straightforward. You can finally set breakpoints by source, inspect locals, and understand what’s in memory without switching to disassembly. https://joel.id/native-binary-debugging-for-ocaml/ opam 2.5.0~rc1 and opam-publish 2.7.1 Kate announced Hi everyone, We are happy to announce the first release candidate of opam 2.5.0, which boasts a grand total of zero (0) changes compared to 2.5.0~beta1! We also take this opportunity to announce the release of opam-publish 2.7.1, whose full release notes can be seen here. Changes in opam-publish 2.7.1 In 2.7.0, opam-publish changed the way user's branches are pushed to their GitHub forks before opening a PR, switching from using SSH keys to using the GitHub API token that opam-publish already requires. 2.7.1 fixes a couple of bugs related to that where opam-publish stopped working if the GitHub Action workflow files of upstream opam-repository are changed, owing to the way GitHub token permissions work. Thanks to @filipeom both for the original contribution in 2.7.0 and for subsequent work on it in 2.7.1. Read our blog post for more details. Please report any issues to the opam bug-tracker or the opam-publish bug-tracker. Try the new opam 2.5.0 release candidate: The upgrade instructions are unchanged: For Unix systems bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.5.0~rc1" or from PowerShell for Windows systems Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.5.0~rc1" Please report any issues to the bug-tracker. Happy hacking, <> <> The opam team <> <> :camel: ocaml-protoc 4.0, pbrt 4.0 Simon Cruanes announced Dear caml riders, I'm happy to announce the release of ocaml-protoc 4.0, alongside its runtime libraries pbrt, pbrt_yojson, and pbrt_services. Ocaml-protoc is a pure OCaml implementation of a protobuf compiler and runtime. Protobuf is a binary serialization format and IDL (interface description language) first introduced by Google in the early 00s, and still in pervasive use there and elsewhere. It is faster (to encode/decode) and more compact than JSON, and is designed for backward compatibility on the wire. Anyway, this new major release is breaking because it finally follows the standard's semantics about field presence. By default, many fields in protobuf are somewhat optional[^1] and are not serialized at all if not present. Ocaml-protoc now tracks this for every non-required field, even scalars, moving towards better compliance with the standard. It does that either via option or via a presence bitfield. Because of this, the generated code has changed significantly and looks more like what the official protoc produces. In a nutshell, each protobuf message now becomes a private record type with mutable fields and a presence bitfield. All modification and creation for a type foo is done via make_foo and foo_set_<field> functions; presence can be checked with foo_has_<field>. This means the runtime knows which fields have been explicitly modified. I don't think ocaml-protoc is 100% compliant with the fine print on default values in proto3, etc. but this is a lot closer than it used to be. Thanks to the work of @lupus there's also a new option validation layer. detailed example Let's look at this simple example: syntax = "proto3"; message Person { string name = 1; sint64 age = 2; } message Store { string address = 1; repeated Person employees = 2; repeated Person clients = 3; } message Company { string name = 1; repeated Store stores = 2; repeated Company subsidiaries = 3; } (* generated from "orgchart.proto", do not edit *) (** {2 Types} *) type person = { name : string; age : int64; } type store = { address : string; employees : person list; clients : person list; } type company = { name : string; stores : store list; subsidiaries : company list; } (** {2 Basic values} *) val default_person : ?name:string -> ?age:int64 -> unit -> person (** [default_person ()] is the default value for type [person] *) val default_store : ?address:string -> ?employees:person list -> ?clients:person list -> unit -> store (** [default_store ()] is the default value for type [store] *) val default_company : ?name:string -> ?stores:store list -> ?subsidiaries:company list -> unit -> company (** [default_company ()] is the default value for type [company] *) (** {2 Formatters} *) val pp_person : Format.formatter -> person -> unit (** [pp_person v] formats v *) val pp_store : Format.formatter -> store -> unit (** [pp_store v] formats v *) val pp_company : Format.formatter -> company -> unit (** [pp_company v] formats v *) (** {2 Protobuf Encoding} *) val encode_pb_person : person -> Pbrt.Encoder.t -> unit (** [encode_pb_person v encoder] encodes [v] with the given [encoder] *) val encode_pb_store : store -> Pbrt.Encoder.t -> unit (** [encode_pb_store v encoder] encodes [v] with the given [encoder] *) val encode_pb_company : company -> Pbrt.Encoder.t -> unit (** [encode_pb_company v encoder] encodes [v] with the given [encoder] *) (** {2 Protobuf Decoding} *) val decode_pb_person : Pbrt.Decoder.t -> person (** [decode_pb_person decoder] decodes a [person] binary value from [decoder] *) val decode_pb_store : Pbrt.Decoder.t -> store (** [decode_pb_store decoder] decodes a [store] binary value from [decoder] *) val decode_pb_company : Pbrt.Decoder.t -> company (** [decode_pb_company decoder] decodes a [company] binary value from [decoder] *) ``` new code: ```ocaml (** Code for orgchart.proto *) (* generated from "orgchart.proto", do not edit *) (** {2 Types} *) type person = private { mutable _presence: Pbrt.Bitfield.t; (** presence for 2 fields *) mutable name : string; mutable age : int64; } type store = private { mutable _presence: Pbrt.Bitfield.t; (** presence for 1 fields *) mutable address : string; mutable employees : person list; mutable clients : person list; } type company = private { mutable _presence: Pbrt.Bitfield.t; (** presence for 1 fields *) mutable name : string; mutable stores : store list; mutable subsidiaries : company list; } (** {2 Basic values} *) val default_person : unit -> person (** [default_person ()] is a new empty value for type [person] *) val default_store : unit -> store (** [default_store ()] is a new empty value for type [store] *) val default_company : unit -> company (** [default_company ()] is a new empty value for type [company] *) (** {2 Make functions} *) val make_person : ?name:string -> ?age:int64 -> unit -> person (** [make_person … ()] is a builder for type [person] *) val copy_person : person -> person val person_has_name : person -> bool (** presence of field "name" in [person] *) val person_set_name : person -> string -> unit (** set field name in person *) val person_has_age : person -> bool (** presence of field "age" in [person] *) val person_set_age : person -> int64 -> unit (** set field age in person *) val make_store : ?address:string -> ?employees:person list -> ?clients:person list -> unit -> store (** [make_store … ()] is a builder for type [store] *) val copy_store : store -> store val store_has_address : store -> bool (** presence of field "address" in [store] *) val store_set_address : store -> string -> unit (** set field address in store *) val store_set_employees : store -> person list -> unit (** set field employees in store *) val store_set_clients : store -> person list -> unit (** set field clients in store *) val make_company : ?name:string -> ?stores:store list -> ?subsidiaries:company list -> unit -> company (** [make_company … ()] is a builder for type [company] *) val copy_company : company -> company val company_has_name : company -> bool (** presence of field "name" in [company] *) val company_set_name : company -> string -> unit (** set field name in company *) val company_set_stores : company -> store list -> unit (** set field stores in company *) val company_set_subsidiaries : company -> company list -> unit (** set field subsidiaries in company *) (** {2 Formatters} *) val pp_person : Format.formatter -> person -> unit (** [pp_person v] formats v *) val pp_store : Format.formatter -> store -> unit (** [pp_store v] formats v *) val pp_company : Format.formatter -> company -> unit (** [pp_company v] formats v *) (** {2 Protobuf Encoding} *) val encode_pb_person : person -> Pbrt.Encoder.t -> unit (** [encode_pb_person v encoder] encodes [v] with the given [encoder] *) val encode_pb_store : store -> Pbrt.Encoder.t -> unit (** [encode_pb_store v encoder] encodes [v] with the given [encoder] *) val encode_pb_company : company -> Pbrt.Encoder.t -> unit (** [encode_pb_company v encoder] encodes [v] with the given [encoder] *) (** {2 Protobuf Decoding} *) val decode_pb_person : Pbrt.Decoder.t -> person (** [decode_pb_person decoder] decodes a [person] binary value from [decoder] *) val decode_pb_store : Pbrt.Decoder.t -> store (** [decode_pb_store decoder] decodes a [store] binary value from [decoder] *) val decode_pb_company : Pbrt.Decoder.t -> company (** [decode_pb_company decoder] decodes a [company] binary value from [decoder] *) [^1]: the precise semantics of presence are, imho, quite messy. Cmdliner 2.1.0 – The powershell edition Brian Ward announced Hello, It's my pleasure to announce the version 2.1.0 of cmdliner Cmdliner is an ISC-licensed library that allows the declarative and compositional definition of command lines with excellent support for command line interface user conventions and standards. This releases consolidates additional work on command line completion. I added: Significant improvements to the bash completion. I'd like to thank @dbuenzli for his gracious feedback on these changes, and importantly for telling me “no” to several others beforehand :) For all the other details see the release notes. Other OCaml News From the ocaml.org blog Here are links from many OCaml blogs aggregated at the ocaml.org blog.
dlvr.it
November 26, 2025 at 7:35 PM
Reading the Gas Meter
My gas supplier has tried and failed to install a smart gas meter, so I’ll give it a go myself.
dlvr.it
November 26, 2025 at 3:37 AM
Gagallium : Testing a priority queue with Monolith
A priority queue is a data structure whose specification is non-deterministic: indeed, if a priority queue contains several key-value pairs whose key is minimal, then any such pair can be legally returned by pop. In this blog post, I describe how to test an OCaml implementation of a priority queue using Monolith. Suppose that we have written (or someone has given us) an implementation of (immutable) priority queues. The signature of this module might look like this (LeftistHeap.mli): module Make (Key : sig type t val compare: t -> t -> int end) : sig (**A key. *) type key = Key.t (**An immutable priority queue. *) type 'a t (**[empty] is the empty queue. *) val empty : 'a t (**[singleton k v] is a singleton queue containing the key-value pair [(k, v)]. *) val singleton : key -> 'a -> 'a t (**[merge q1 q2] merges the queues [q1] and [q2]. The result is a new queue. *) val merge : 'a t -> 'a t -> 'a t (**[pop q] extracts a key-value pair whose key is minimal out of the queue [q]. [None] is returned only in the case where [q] is empty. *) val pop: 'a t -> ((key * 'a) * 'a t) option end The implementation of this module might be based on Chris Okasaki’s leftist heaps, a simple and beautiful data structure (LeftistHeap.ml). But this does not matter. Let’s see how to test this implementation as a black box using Monolith (paper). Monolith expects us to provide a reference implementation of a priority queue. This reference implementation does not need to be very efficient; what matters is that it should be simple and correct. The simplest possible approach is to use an unsorted list of key-value pairs, along the following lines (reference.ml) : type t = (Key.t * Val.t) list let empty : t = [] let singleton k v : t = [(k, v)] let merge q1 q2 : t = q1 @ q2 (* missing [pop], for now *) Here comes the interesting part. pop is a non-deterministic operation: if a priority queue contains several minimal key-value pairs, then any of them can be legally returned by pop. In such a situation, the candidate implementation of pop makes a choice. It would not make sense for the reference implementation of pop to also make a choice: because the two choices might be different, the candidate and the reference could become out of sync. Instead, we want the reference implementation of pop to check that the choice made by the candidate implementation is legal and to obey this choice, that is, to make the same choice. Therefore, the reference implementation of pop cannot have type t -> ((Key.t * Val.t) * t) option, as one might expect. Instead, it must take two arguments, namely the queue on the reference side and the result returned by pop on the candidate side. It is expected to return a diagnostic, that is, an indication of whether this candidate result is valid or invalid. The type diagnostic is defined by Monolith (documentation); its constructors are Valid and Invalid. The reference implementation of pop can be written as follows (link): let pop (q : t) (result : ((Key.t * Val.t) * _) option) : (((Key.t * Val.t) * t) option) diagnostic = match result with | Some (kv, _cq) -> (* The candidate has extracted the key-value pair [kv] and has returned a candidate queue [_cq] that we cannot inspect, as it is an abstract data structure. Fortunately, there is no need to inspect it. *) (* Check that the key-value pair [kv] chosen by the candidate is a minimal element of the queue [q], and return [q] minus [kv]. *) handle @@ fun () -> let q = remove_minimal kv q in valid (Some (kv, q)) | None -> (* The candidate has returned [None]. Check that the reference queue [q] is empty; if it isn't, fail. *) if q = [] then valid None else invalid @@ fun _doc -> format "(* candidate returns None, yet queue is nonempty *)" The auxiliary function remove_minimal kv kvs (link) checks that the key-value pair kv is a minimal element of the list kvs and returns this list deprived of this element. It fails, by raising an exception, if kv is not in the list or not minimal. The auxiliary function handle (link) handles the exceptions raised by remove_minimal and returns an invalid diagnostic in these cases. The reference implementation is now complete. There remains to tell Monolith about the operations that we want to test. For each operation, we must provide a specification (that is, roughly, a type), a reference implementation, and a candidate implementation. This is done as follows (test.ml): let spec = t in declare "empty" spec R.empty C.empty; let spec = value ^> key ^> t in declare "singleton" spec R.singleton C.singleton; let spec = t ^> t ^> t in declare "merge" spec R.merge C.merge; let spec = t ^> nondet (option ((key *** value) *** t)) in declare "pop" spec R.pop C.pop; In the case of pop, we have used the combinator nondet (documentation) to tell Monolith that pop is a non-deterministic operation, whose reference implementation is written in the unusual style that we have shown above. There remains to run the test, which runs forever and prints the problematic scenarios that it detects. It is worth noting that the result of pop is a composite value: it is partly concrete, partly abstract, as it is an (optional) pair of a key-value pair (concrete data that can be observed) and a priority queue (abstract data that cannot be directly observed). This does not create any problem: Monolith is able to automatically decompose this composite value and submit the priority queue component to further testing. To illustrate this, let us intentionally introduce the following bug in the candidate implementation: let pop q = match pop q with | Some (kv, q') -> ignore q'; Some (kv, q) (* return the original queue, unchanged *) | None -> None Then, the test immediately fails and prints the following scenario: (* @03: Failure in an observation: candidate and reference disagree. *) open Bitsets.LeftistHeap.Make(Int);; #require "monolith";; module Sup = Monolith.Support;; (* @01 *) let x0 = singleton 6 11;; (* @02 *) let (Some ((_, _), x1)) = pop x0;; (* @03 *) let observed = pop x1;; (* candidate returns (6, 11), which does not exist *) The priority queue returned by the first pop operation is extracted, named x1, and submitted to a second pop operation, where an observable problem appears.
dlvr.it
November 25, 2025 at 7:34 PM
A Vision for OCaml in the AI Era - Thibaut Mattio - FUN OCaml 2025
A Vision for OCaml in the AI Era Nicolás Ojeda Bär ABSTRACT AI is reshaping software development, yet OCaml's adoption in AI workflows remains limited. This talk explores how the OCaml community can proactively embrace AI to make OCaml a productive language in the AI era—both for writing AI applications and for AI-assisted development. We examine two critical questions: First, how can OCaml become a viable alternative to Python for machine learning? By addressing ecosystem breadth and developer experience, we can solve real problems—from unifying research and production codebases to enabling scalable deployment with OCaml's performance guarantees. Second, how can we make OCaml more productive for AI-assisted development? Strong type systems and integrated tooling give OCaml a natural advantage for coding agents, but we need specialized, open-source tools built for the OCaml ecosystem. This talk introduces Raven, a modern scientific computing ecosystem for OCaml that mirrors Python's ML stack, and Spice, an upcoming local-first, OCaml-native coding agent. Beyond tooling, we'll discuss how the community can anticipate changes in onboarding, documentation, and workflows to ensure OCaml thrives in an AI-driven future—while maintaining equal opportunity and access for all developers. Session page: https://fun-ocaml.com/2025/a-vision-for-ocaml-in-the-ai-era/ Connect with FUN OCaml: Twitter: https://x.com/FunOCaml Bluesky: https://bsky.app/profile/fun-ocaml.com #ocaml --- Big Thanks(TM) go to our generous sponsors who made FUN OCaml possible! * Octra Labs - https://octra.org/ - Platinum Sponsor * Ahrefs - https://ahrefs.com/ - Platinum Sponsor * Dialo - https://dialo.ai/ - Gold Sponsor * LexiFi - https://www.lexifi.com - Bronze Sponsor * Jane Street - https://www.janestreet.com/ - Bronze Sponsor * LightSource - Volunteer / Organizer Commitment * Tarides - Volunteer / Organizer Commitment
www.youtube.com
November 25, 2025 at 3:38 PM
OCaml Weekly News
Hello Here is the latest OCaml Weekly News, for the week of November 11 to 18, 2025. opam 2.5.0~beta1 Archive: https://discuss.ocaml.org/t/ann-opam-2-5-0-beta1/17469/1 Kate announced Hi everyone, We are happy to announce the first beta release of opam 2.5.0. This version is a beta, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release. Try it! The upgrade instructions are unchanged: For Unix systems bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.5.0~beta1" or from PowerShell for Windows systems Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.5.0~beta1" Please report any issues to the bug-tracker. Happy hacking, <> <> The opam team <> <> :camel: Announcing the first release of Alice, a radical OCaml build system Archive: https://discuss.ocaml.org/t/announcing-the-first-release-of-alice-a-radical-ocaml-build-system/17472/1 Steve Sherratt announced I’m pleased to announce the initial release of Alice, a radical, experimental OCaml build system, package manager, and environment manager for Windows, macOS, and Linux. Its goal is to allow anyone to program in OCaml with as little friction as possible. To build your first program with Alice, run: $ alice tools install # Skip this if you already have an OCaml compiler! $ alice new hello $ cd hello $ alice run Compiling hello v0.1.0 Running hello/build/packages/hello-0.1.0/debug/executable/hello Hello, World! The UI is heavily inspired by Cargo. An important distinction between Alice's and Opam's packaging philosophies is that in Alice, the OCaml compiler and development tools are not packages. The alice tools install command will install a pre-compiled (relocatable!) OCaml compiler, a compatible ocamllsp, and ocamlformat user-wide, similar to how rustup installs the Rust compiler and LSP server. This lets you go from zero to OCaml really fast because you don't have to build the compiler from source. This speedup is particularly noticeable on Windows where building the compiler can take upwards of 10 minutes. Alice supports building packages with dependencies on other packages, but currently only local packages are supported, and it can only build Alice packages, not Opam packages. See an example here. I'll probably add Opam compatibility in the future. It's still early days and a lot is missing before Alice could feasibly be used for real projects. If you want to try it out anyway, install the alice Opam package, the github:alicecaml/alice Nix flake, or run the interactive install script: curl -fsSL https://alicecaml.org/install.sh | sh More details about installing Alice are here. If you want read more, check out the blog.
dlvr.it
November 24, 2025 at 11:29 PM
Analyzing Programs with SMT Solvers - Tikhon Jelvis - FUN OCaml 2025
Analyzing Programs with SMT Solvers Tikhon Jelvis (Semgrep) ABSTRACT We can use SMT solvers like Z3 to analyze programs and answer difficult questions about our code. By generating and solving complex constraints, we can improve error message localization, attack cryptographic protocols, check refinement types, search for proofs, verify invariants, compare programs against specifications or even synthesize code. Z3 is the goto state-of-the-art SMT solver, available under and open source license and has a first-class OCaml library. In this talk, I'll walk through a simple OCaml program to generate SMT constraints that represent a bounded model of programs in a simple imperative language. Algebraic data types and pattern matching are a perfect fit for this kind of work. Session page: https://fun-ocaml.com/2025/analyzing-programs-with-smt-solvers/ Connect with FUN OCaml: Twitter: https://x.com/FunOCaml Bluesky: https://bsky.app/profile/fun-ocaml.com #ocaml --- Big Thanks(TM) go to our generous sponsors who made FUN OCaml possible! * Octra Labs - https://octra.org/ - Platinum Sponsor * Ahrefs - https://ahrefs.com/ - Platinum Sponsor * Dialo - https://dialo.ai/ - Gold Sponsor * LexiFi - https://www.lexifi.com - Bronze Sponsor * Jane Street - https://www.janestreet.com/ - Bronze Sponsor * LightSource - Volunteer / Organizer Commitment * Tarides - Volunteer / Organizer Commitment
www.youtube.com
November 23, 2025 at 3:36 AM
OCaml Weekly News
Hello Here is the latest OCaml Weekly News, for the week of November 04 to 11, 2025. Opam-repository, signed! conex is in beta now :) Archive: https://discuss.ocaml.org/t/opam-repository-signed-conex-is-in-beta-now/17461/1 Hannes Mehnert announced Dear everyone, we’re proud to announce that conex, in an initial version, is now live! You can receive signed updates of the opam-repository. A quick guide: To setup opam with conex on your machine, you need to install conex (and/or conex-mirage-crypto, see below) - currently only available as opam package (sorry about the bootstrap problem - hopefully it will be integrated into opam at some time). Then, in your “\~/.opam/config” you need to specify the repository-validation-command: repository-validation-command: [ "/path/to/conex_verify_mirage_crypto" "--quorum=%{quorum}%" "--trust-anchors=%{anchors}%" "--repository=%{repo}%" {incremental} "--dir=%{dir}%" {!incremental} "--patch=%{patch}%" {incremental} "--incremental" {incremental} ] Instead of “conex_verify_mirage_crypto”, you can as well use “conex_verify_openssl” (fewer dependencies, calls out to OpenSSL as the cryptographic provider, is slower). Then you can run opam repo add conex-robur https://conex.robur.coop 1 sha256=ad5eb0e4a77abfbc6c1bb5661eba46049404e0222588dd059c87f12436d41a28. Thereafter you can opam repo remove default, and then you’re only using signed metadata. The “1” is the quorum of root keys for signatures to be valid, the “sha256=ad5eb0e4a77abfbc6c1bb5661eba46049404e0222588dd059c87f12436d41a28” is the hash of the public root key. Read the full article at https://hannes.robur.coop/Posts/ConexRunning – happy to receive feedback. The development of conex is supported by the OCaml Software Foundation and by ahrefs.
dlvr.it
November 22, 2025 at 7:34 PM
From OCaml 4 to 5 and from Parmap to Effects: A legacy code transition story - FUN OCaml 2025
From OCaml 4 to 5 and from Parmap to Effects: A legacy code transition story SPEAKERS Nathan Taylor (Semgrep) Nat Mote (Semgrep) ABSTRACT OCaml 5's support for shared memory parallelism and effects-based concurrency opens up new ways for developers to build new OCaml programs for modern hardware, but it isn't trivial to migrate existing software to this new world. We've spent the last few months porting a large (~3MM LoC) OCaml codebase from process-based parallelism to multi-domain Eio, and learned a lot along the way. In this talk, we'll discuss the fundamentals of shared-memory parallism, our incremental migration approach which used a combination of static and dynamic analysis, the pitfalls (both expected and unexpected) that we encountered along the way, and some lessons that others can adopt for their own journey. Session page: https://fun-ocaml.com/2025/from-ocaml-4-to-5/ Connect with FUN OCaml: Twitter: https://x.com/FunOCaml Bluesky: https://bsky.app/profile/fun-ocaml.com #ocaml --- Big Thanks(TM) go to our generous sponsors who made FUN OCaml possible! * Octra Labs - https://octra.org/ - Platinum Sponsor * Ahrefs - https://ahrefs.com/ - Platinum Sponsor * Dialo - https://dialo.ai/ - Gold Sponsor * LexiFi - https://www.lexifi.com - Bronze Sponsor * Jane Street - https://www.janestreet.com/ - Bronze Sponsor * LightSource - Volunteer / Organizer Commitment * Tarides - Volunteer / Organizer Commitment
www.youtube.com
November 21, 2025 at 3:37 PM