{"id":13484465,"url":"https://github.com/realworldocaml/book","last_synced_at":"2025-05-15T16:04:27.770Z","repository":{"id":6002509,"uuid":"7225543","full_name":"realworldocaml/book","owner":"realworldocaml","description":"V2 of Real World OCaml","archived":false,"fork":false,"pushed_at":"2024-07-08T13:57:53.000Z","size":236430,"stargazers_count":1208,"open_issues_count":361,"forks_count":177,"subscribers_count":47,"default_branch":"master","last_synced_at":"2025-04-11T21:12:32.344Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://dev.realworldocaml.org","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/realworldocaml.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-12-18T15:26:58.000Z","updated_at":"2025-03-24T03:54:33.000Z","dependencies_parsed_at":"2024-09-25T00:34:39.715Z","dependency_job_id":null,"html_url":"https://github.com/realworldocaml/book","commit_stats":{"total_commits":6125,"total_committers":95,"mean_commits":64.47368421052632,"dds":0.6746122448979592,"last_synced_commit":"0f8ea69ad66f745bd52ecae7189b72f8b6d50da8"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realworldocaml%2Fbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realworldocaml%2Fbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realworldocaml%2Fbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/realworldocaml%2Fbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/realworldocaml","download_url":"https://codeload.github.com/realworldocaml/book/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248480429,"owners_count":21110937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T17:01:24.832Z","updated_at":"2025-04-11T21:12:44.096Z","avatar_url":"https://github.com/realworldocaml.png","language":"OCaml","funding_links":[],"categories":["OCaml","OCaml (14)"],"sub_categories":[],"readme":"Real World OCaml v2\n-------------------\n\nThis is the source code for the Real World OCaml 2nd edition, which is\nstill a work in progress.  The original edition was written by Yaron\nMinsky, Anil Madhavapeddy and Jason Hickey, and the revised edition is\nbeing led by Yaron Minsky and Anil Madhavapeddy.  There have been\nsignificant contributions to the revised tooling from Ashish Agarwal,\nJeremy Yallop, Frederic Bour, and Sander Spies.\n\nAn online snapshot of the development book is available from\n\u003chttps://dev.realworldocaml.org\u003e.  There is a Feedback pane on each\nchapter which leads to a dedicated section on the OCaml [discussion\nforum](https://discuss.ocaml.org) where you can register broader\nfeedback.  More specific issues such as typos can be reported on the\n[issue tracker](https://github.com/realworldocaml/book/issues).\n\n## Repository layout\n\nEach chapter of the book sits in a separate subfolder of the `book/`\ndirectory.  The `README.md` file contains the text of the chapter,\nwritten in markdown.  Each OCaml or shell code block in the chapter is\nvalidated using [mdx](https://github.com/realworldocaml/mdx). The more\ncomplex and structured examples live in an `examples/` sub folder and\nmdx is used to keep the examples and the chapter's code block in sync.\n\nThe `bin/` folder contains the OCaml scripts used to generate the books HTML\nand PDF versions.\n\nAll of the code and examples are built using OCaml 4.09.0.\n\n## Building\n\nHere are the commands to build the website:\n\n### Installing Dependencies\n\nYou can install system dependencies by running:\n\n```\nmake depext\n```\n\nAll OCaml dependencies are vendored in the `duniverse/` directory except\nfor the `dune` build system itself. It's preferable to use an empty opam switch\nwith only `dune` installed to avoid conflicts between the opam and local\nlibraries. To set up your RWO development environment you can run:\n\n```\nopam switch create rwo 4.13.1\nopam install dune=3.0.2\n```\n\n### Generating the HTML\n\nTo generate the HTML pages:\n\n```\nmake\n```\n\nThe HTML pages are created in `_build/default/static/`.\nOpen `_build/default/static/index.html` to start browsing the\nfreshly built version of the book.\n\n#### WIP Chapters\n\nIt is possible to mark a chapter as WIP so that it won't be included in the main\nwebsite or PDF.  To do so, you can wrap your chapter in a\n`(wip \u003cchapter-folder\u003e)` in the table of content file, `book/toc.scm`, e.g.:\n\nYou can run `dune build @site-wip` or `dune build @pdf-wip` to generate the\nwebsite or PDF versions of the book including all WIP chapters. You can find\nthem respectivey in `_build/default/static-wip/index.html` and\n`_build/default/static-wip/book.pdf`.\n\nOnce the chapter is ready, you can simply replace `(wip \u003cchapter-folder\u003e)` with\n`\u003cchapter-folder\u003e` in `book/toc.scm`.\n\n### Testing the code examples\n\nIt is possible to automatically test that\nthe [the code examples](./examples/code) files work fine. To check that shell\nscripts and `.ml` files do what they are expected:\n\n```\nmake test\n```\n\nThis will run all the tests in \"determinitic mode\", which is suitable for the\nCI and it will display the diff between what is expected and what is produced.\n\nTo accept the changes:\n\n```\nmake promote\n```\n\n### Testing non-deterministic examples\n\nA few code examples are not deterministic: for instance benchmarks. In\nthis case, there is a specific dune profile to use:\n\n```\ndune runtest --profile non-deterministic ...\n```\n\nTo accept the changes:\n\n```\nmake promote\n```\n\n### Standalone examples\n\nExamples in each chapter's `examples/` folder are split between\n`correct/` and `erroneous/`.  Each individual example is a valid\ndune-project that lives in its own sub folder.  Examples that contain\nerrors on purpose, for instance to showcase some specific compile\nerrors, go into the latter. All other examples should go in\n`correct/`.\n\nExamples in the `correct/` folder are automatically built and tested\nin the CI.  It's possible to build and test them individually using\nthe dune alias corresponding to the example folder name. For instance,\nto build and test the example in\n`book/imperative-programming/examples/correct/dictionary`, one can\nrun:\n\n```\ndune build @dictionary\n```\n\nNote that the `runtest` alias will also build and test examples so\nrunning `make test` will build all of the book's examples.\n\nWhen adding a new chapter, the example folder should have the\nfollowing structure:\n\n```\nexamples/\n├── correct/\n├── dune\n├── dune.inc\n└── erroneous/\n```\n\nWith the following dune file:\n\n```\n(data_only_dirs correct erroneous)\n\n(rule\n (deps\n  (source_tree ./))\n (action\n  (with-stdout-to dune.gen\n   (run rwo-examples-rules ./))))\n\n(rule\n (alias runtest)\n (action (diff dune.inc dune.gen)))\n\n(include dune.inc)\n```\n\nFrom that point forward, running `dune runtest` will generate the\nright dune rules for each folder in `correct/`. When the rules change,\nthey must be accepted through promotion first.\n\nEach example must explicitly define its external dependencies in a\n`.rwo-example`. For instance, if your example requires `base` and\n`core`, it must include the following `.rwo-example` file at its root:\n\n```\n(packages base core)\n```\n\n## Dependencies\n\nRWO's dependencies are managed using the `opam-monorepo` plugin. The dependencies are expressed\nin the `rwo.opam` opam file as they would be for any project. The plugin is used to generate a\n`rwo.opam.locked` lockfile from this deps specification using the `opam monorepo lock`\ncommand. Running `opam monorepo pull` will then fetch the sources locally into the `duniverse/`\nfolder so that rwo and its dependencies can all be built together in a single dune-workspace.\n\nYou can install it by running:\n```\nopam install opam-monorepo\n```\n\nBefore running `opam-monorepo lock` it's important to have the proper opam configuration.\nWe need to both add the `opam-overlays` repo which contains dune port of some of our dependencies.\nWe also use a pinned version of ctypes until the dune-port is stable. To set these up, you can run:\n```\nopam repository add dune-opam-overlays git+https://github.com/dune-universe/opam-overlays.git\nopam pin add ctypes.0.20.1+dune https://github.com/avsm/ocaml-ctypes.git#dune-port\nopam pin add ctypes-foreign.0.20.1+dune https://github.com/avsm/ocaml-ctypes.git#dune-port\n```\n\n### Upgrading or adding dependencies\n\nBefore upgrading or adding any dependency, you should make sure they are up-to-date according to the\n`rwo.opam` file by running:\n```\nopam monorepo lock\nopam monorepo pull\n```\nand committing the resulting `duniverse/` and `rwo.opam.locked` if they changed. This preliminary\nstep will help distinguish how new dependency specifications actually impact the lockfile and\nduniverse by splitting out the unrelated updates.\n\nOnce the above is done, you can modify the `dune-project` package definition by adding a new dependency\nor modifying the bounds on an existing one. Then run:\n```\ndune build rwo.opam\nopam monorepo lock\nopam monorepo pull\n```\nto update the opam file, the lockfile and the duniverse folder.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealworldocaml%2Fbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frealworldocaml%2Fbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frealworldocaml%2Fbook/lists"}