Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions data/tutorials/language/0it_00_values_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ short_title: Values and Functions
description: |
Functions, values, definitions, environments, scopes, closures, and shadowing. This tutorial will help you master the fundamentals.
category: "Introduction"
prerequisite_tutorials:
- "toplevel-introduction"
- "installing-ocaml"
---

## Introduction
Expand All @@ -13,10 +16,6 @@ In OCaml, functions are treated as values, so you can use functions as arguments

We use UTop to understand these concepts by example. You are encouraged to modify the examples to gain a better understanding.

**Prerequisites**:
- The [Introduction to the OCaml Toplevel](https://ocaml.org/docs/toplevel-introduction) guide covers how to use UTop.
- Ensure you have completed the [Get Started](https://ocaml.org/docs/installing-ocaml) series before proceeding with this tutorial.

## What is a Value?

Like most functional programming languages, OCaml is an [expression-oriented](https://en.wikipedia.org/wiki/Expression-oriented_programming_language) programming language. That means programs are expressions. Actually, almost everything is an expression. In OCaml, statements don't specify actions to be taken on data. All computations are made through expression evaluation. Computing expressions produce values. Below, you'll find a few examples of expressions, their types, and the resulting values. Some include computation and some do not:
Expand Down
7 changes: 4 additions & 3 deletions data/tutorials/language/0it_01_basic_datatypes.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l 23 should be turned into something like:

**Note**: As in previous tutorials, expressions after `#` and ending with `;;` are for the toplevel, like UTop.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ short_title: Basic Data Types and Pattern Matching
description: |
Predefined Types, Variants, Records, and Pattern Matching
category: "Introduction"
prerequisite_tutorials:
- "tour-of-ocaml"
- "values-and-functions"
---

## Introduction
Expand All @@ -13,9 +16,7 @@ This document covers atomic types, such as integers and Booleans; predefined com

In OCaml, there are no type checks at runtime, and values don't change type unless explicitly converted. This is what being statically- and strongly-typed means. This allows safe processing of structured data.

<!--End edit-->

**Prerequisites**: Before proceeding, it's necessary to have completed the [Get Started](https://ocaml.org/docs/get-started) series of tutorials as well as [Functions and Values](/docs/values-and-functions). As in previous tutorials, expressions after `#` and ending with `;;` are for the toplevel, like UTop.
**Note**: As in previous tutorials, expressions after `#` and ending with `;;` are for the toplevel, like UTop.

<!--
The goal of this tutorial is to provide for the following capabilities:
Expand Down
4 changes: 2 additions & 2 deletions data/tutorials/language/0it_04_labels.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ short_title: Labelled and Optional Arguments
description: >
Provide labels to your functions arguments
category: "Introduction"
prerequisite_tutorials:
- "values-and-functions"
---

It is possible to give names and default values to function parameters. This is broadly known as labels. In this tutorial, we learn how to use labels.

Throughout this tutorial, the code is written in UTop. In this document parameters that are not labelled are called _positional parameters_.

**Prerequisites**: [Values and Functions](/docs/values-and-functions)

## Passing Labelled Arguments

The function `Option.value` from the standard library has a parameter labelled `default`.
Expand Down
7 changes: 5 additions & 2 deletions data/tutorials/language/0it_05_imperative.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ short_title: Mutability and Imperative Control Flow
description: >
Write stateful programs in OCaml. Use for and while loops, if-then-else, mutable record fields, and references.
category: "Introduction"
prerequisite_tutorials:
- "basic-data-types"
- "values-and-functions"
- "lists"
- "modules"
---

<!--
Expand All @@ -27,8 +32,6 @@ This document has two main teaching goals:

Imperative and functional programming both have unique merits, and OCaml allows combining them efficiently. In the first part of this tutorial, we introduce mutable state and imperative control flow. See the second part for examples of recommended or discouraged use of these features.

**Prerequisites**: [Basic Data Types](/docs/basic-data-types), [Values and Functions](/docs/values-and-functions), [Lists](/docs/lists), and [Modules](/docs/modules).

## Immutable vs Mutable Data

When you use `let … = …` to bind a value to a name, this name-value binding is [immutable](https://en.wikipedia.org/wiki/Immutable_object), so it is impossible to _mutate_ (which is a fancy term for “change,” “update,” or “modify”) the value assigned to the name.
Expand Down
7 changes: 3 additions & 4 deletions data/tutorials/language/3ds_05_seq.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ short_title: Sequences
description: >
Learn about sequences, of OCaml's most-used, built-in data types
category: "Data Structures"
prerequisite_tutorials:
- "lists"
- "options"
---

## Prerequisites

You should be comfortable with writing functions over lists and options.

## Introduction

Sequences are very much like lists. However, from a pragmatic perspective, one
Expand Down
4 changes: 2 additions & 2 deletions data/tutorials/language/5rt_00_memory_representation.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ external_tutorial:
contribute_link:
url: https://github.com/realworldocaml/book/blob/master/book/runtime-memory-layout/README.md
description: "You are encouraged to contribute to the original sources of this page at the Real World OCaml GitHub repository."
prerequisite_tutorials:
- "basic-data-types"
---

This is an adaptation of the chapter [Memory Representation of Values](https://dev.realworldocaml.org/runtime-memory-layout.html) from the book [Real World OCaml](https://dev.realworldocaml.org/), reproduced here with permission.
Expand All @@ -36,8 +38,6 @@ code is spending its time.
At the end of this document, you will be able to translate between OCaml
values and their memory representation.

**Prerequisites:** [Basic Data Types and Pattern Matching](/docs/basic-data-types)

## OCaml Types Disappear at Runtime

The OCaml compiler runs through several phases during the compilation
Expand Down
2 changes: 2 additions & 0 deletions src/ocamlorg_data/data.mli
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ module Tutorial : sig
}

type recommended_next_tutorials = string list
type prerequisite_tutorials = string list

type t = {
title : string;
Expand All @@ -230,6 +231,7 @@ module Tutorial : sig
toc : toc list;
body_html : string;
recommended_next_tutorials : recommended_next_tutorials;
prerequisite_tutorials : prerequisite_tutorials;
}

val all : t list
Expand Down
17 changes: 17 additions & 0 deletions src/ocamlorg_frontend/pages/tutorial.eml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rendering is ok, although the font looks bigger than other <h2> / ## header.

We need to find a way to have the prerequisite list after the title, as I suggested, it looks clumsy. Sorry, I hadn't realized that issue when writing the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into it.

Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,27 @@ let render_related_exercises exercises =
else
""

let render_prerequisite_tutorials tutorials =
if List.length tutorials > 0 then
<div class="mb-6 pt-8 border-t border-gray-200">
<h2 class="mb-4 mt-0 text-lg font-bold leading-6"">Prerequisites</h2>
<ul class="list-disc marker:text-primary">
<% tutorials |> List.iter (fun (tutorial : Data.Tutorial.t) -> %>
<li class="mb-1">
<a href='/docs/<%s tutorial.slug %>'><%s tutorial.title %></a>
</li>
<% ); %>
</ul>
</div>
else
""

let render
(tutorial : Data.Tutorial.t)
~tutorials
~related_exercises
~recommended_next_tutorials
~prerequisite_tutorials
~canonical
=
let href, description = match tutorial.external_tutorial with
Expand Down Expand Up @@ -73,6 +89,7 @@ Learn_layout.three_column_layout
<div class="prose prose-orange dark:prose-invert max-w-full">
<%s! render_external_tutorial_banner tutorial.external_tutorial %>
<%s! render_title tutorial %>
<%s! render_prerequisite_tutorials prerequisite_tutorials %>
<%s! tutorial.body_html %>
<%s! render_related_exercises related_exercises %>
<%s! Learn_components.contribute_footer ~href ~description ~recommended_next_tutorials %>
Expand Down
9 changes: 8 additions & 1 deletion src/ocamlorg_web/lib/handler.ml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parsing tutorial's Yaml header should not produce an option list but a list. The absence of the prerequisite_tutorials header should result in an empty list; wrapping in an option is redundant.

I'd also prefer having List.map over the prerequisite_tutorials string list to turn it into a Data.Tutorial.t list.

Original file line number Diff line number Diff line change
Expand Up @@ -408,10 +408,17 @@ let tutorial req =
all_tutorials |> List.filter is_in_recommended_next
in

let is_prerequisite (tested : Data.Tutorial.t) =
List.exists (fun r -> r = tested.slug) tutorial.prerequisite_tutorials
in

let prerequisite_tutorials = all_tutorials |> List.filter is_prerequisite in

Dream.html
(Ocamlorg_frontend.tutorial ~tutorials
~canonical:(Url.tutorial tutorial.slug)
~related_exercises ~recommended_next_tutorials tutorial)
~related_exercises ~recommended_next_tutorials ~prerequisite_tutorials
tutorial)

let exercises req =
let all_exercises = Data.Exercise.all in
Expand Down
20 changes: 15 additions & 5 deletions tool/ood-gen/lib/tutorial.ml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type external_tutorial = {
type recommended_next_tutorials = string list
[@@deriving of_yaml, show { with_path = false }]

type prerequisite_tutorials = string list
[@@deriving of_yaml, show { with_path = false }]

type metadata = {
id : string;
title : string;
Expand All @@ -37,6 +40,7 @@ type metadata = {
category : string;
external_tutorial : external_tutorial option;
recommended_next_tutorials : recommended_next_tutorials option;
prerequisite_tutorials : prerequisite_tutorials option;
}
[@@deriving of_yaml]

Expand All @@ -53,17 +57,18 @@ type t = {
body_md : string;
body_html : string;
recommended_next_tutorials : recommended_next_tutorials;
prerequisite_tutorials : prerequisite_tutorials;
}
[@@deriving
stable_record ~version:metadata ~add:[ id ]
~modify:[ recommended_next_tutorials ]
~modify:[ recommended_next_tutorials; prerequisite_tutorials ]
~remove:[ slug; fpath; section; toc; body_md; body_html ],
show { with_path = false }]

let of_metadata m =
of_metadata m ~slug:m.id ~modify_recommended_next_tutorials:(function
| None -> []
| Some u -> u)
of_metadata m ~slug:m.id
~modify_recommended_next_tutorials:(function None -> [] | Some u -> u)
~modify_prerequisite_tutorials:(function None -> [] | Some u -> u)

let id_to_href id =
match id with
Expand Down Expand Up @@ -132,7 +137,10 @@ let check_tutorial_references all =
^ " were not found: [" ^ String.concat "; " missing ^ "]"
in
let has_missing_tuts_exn t =
match List.filter tut_is_missing t.recommended_next_tutorials with
match
List.filter tut_is_missing t.recommended_next_tutorials
@ List.filter tut_is_missing t.prerequisite_tutorials
with
| [] -> ()
| missing -> raise (Missing_Tutorial (missing_tut_msg t missing))
in
Expand Down Expand Up @@ -184,6 +192,7 @@ type external_tutorial =
; contribute_link : contribute_link
}
type recommended_next_tutorials = string list
type prerequisite_tutorials = string list
type t =
{ title : string
; short_title: string
Expand All @@ -197,6 +206,7 @@ type t =
; toc : toc list
; body_html : string
; recommended_next_tutorials : recommended_next_tutorials
; prerequisite_tutorials : prerequisite_tutorials
}

let all = %a
Expand Down