Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial on Mutability and Imperative Programming #1529

Merged
merged 41 commits into from
Dec 14, 2023
Merged

Conversation

cuihtlauac
Copy link
Collaborator

Mutable Data: references, records and arrays/bytes
Imperative
Exceptions
Howto mix styles without getting into trouble
Refunctionalization techniques

@Tchou
Copy link

Tchou commented Nov 27, 2023

Hi,
some low-level remarks.

# #show ref;;

why not #show_type ref ? This would only show the type definition (which is what is interesting) and would allow you to remove the awkward reference to binding with C (also I haven't checked but I think makemutable is not a C function but a compiler primitive).

"Note: This example will not run in the REPL, since the function Array.truncate is not defined."

Why not use Array.sub then ? it only adds a 0 parameter and the code can actually be tested (and replace the paragraph about the fake truncate by on explaining in passing what Array.sub does).

Not too sure about the "Analytics" example. I would avoid depending on code that is left to the reader to imagine. I think you could achieve the same effect by logging something in a or on stderr. I would maybe start this part by a more general remark saying that in OCaml, side-effects do not occur in types (whether they are modification of mutable state or exceptions). That is a strength (allows you to use local side effects, or functions that behaves as-if they were pure but more efficient) but also a problem since, when the side effect is actually part of the spec, one has to rely on documentation to be aware of that (e.g. a function that mutates its argument).

As for side effects in arguments I would generalize a bit saying that this also apply to constructor argument and that code such as:

let r = ref 0 in
((incr r; !r), (incr r; !r))

may return different values depending on the back-end, optimization level, version of the compiler etc…

@cuihtlauac
Copy link
Collaborator Author

cuihtlauac commented Nov 27, 2023

why not #show_type ref ? This would only show the type definition (which is what is interesting) and would allow you to remove the awkward reference to binding with C (also I haven't checked but I think makemutable is not a C function but a compiler primitive).

Fixed

"Note: This example will not run in the REPL, since the function Array.truncate is not defined."

If we show code which is bad but somehow working, it will be copied and used. truncate is way to work around that (analytics undefined too).

Not too sure about the "Analytics" example. I would avoid depending on code that is left to the reader to imagine. I think you could achieve the same effect by logging something in a or on stderr. I would maybe start this part by a more general remark saying that in OCaml, side-effects do not occur in types (whether they are modification of mutable state or exceptions). That is a strength (allows you to use local side effects, or functions that behaves as-if they were pure but more efficient) but also a problem since, when the side effect is actually part of the spec, one has to rely on documentation to be aware of that (e.g. a function that mutates its argument).

I like the idea you suggest about adding text. What I like about analytics is the discrepancy between copying an array and opening a network connection. But you are right, we should not assume everybody knows about analytics and provide some details

let r = ref 0 in
((incr r; !r), (incr r; !r))

Excellent example!

Copy link
Collaborator

@christinerose christinerose left a comment

Choose a reason for hiding this comment

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

Questions found in my review

data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
```
In this example, the first two expressions are `print_endline` function calls, which produce side effects (printing to the console), and the last expression is simply the integer `42`, which becomes the value of the entire sequence. The `;` operator is used to separate these expressions.

**Remark** Even thought it's called the sequence operator, the semicolon is not truly an operator because it is not a function of type `unit -> 'a -> 'a`. It is rather a _construct_ of the language. That allows terminating sequences with a semicolon, which is ignored.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please check my revision here to ensure it's still accurate. 🙂

data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
Comment on lines +478 to +479
# let state = ref [] in try loop state with Exit -> state_to_string !state;;
```
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this doesn't return anything but just leaves a space for more input, should we mention that or clarify it's necessary to return twice to get back to the prompt?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I need to fix offline

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We need to say something like:

Type and edit any single line text, and then press return to get back to the repl

data/tutorials/language/0it_06_imperative.md Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Show resolved Hide resolved
Copy link
Collaborator

@christinerose christinerose left a comment

Choose a reason for hiding this comment

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

A few questions

data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
data/tutorials/language/0it_06_imperative.md Outdated Show resolved Hide resolved
@sabine
Copy link
Collaborator

sabine commented Dec 14, 2023

Anything left to do before me merge this?

@cuihtlauac cuihtlauac merged commit e3c6fa8 into main Dec 14, 2023
3 checks passed
@cuihtlauac cuihtlauac deleted the doc-imperative branch December 14, 2023 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mutable State / Imperative Programming
4 participants