277 rader
21 KiB
HTML
277 rader
21 KiB
HTML
<!DOCTYPE html>
|
||
<!-- Page generated by OCaml with Ocsigen.
|
||
See http://ocsigen.org/ and http://caml.inria.fr/ for information -->
|
||
<html class="ocaml" lang="en" id="h" xmlns="http://www.w3.org/1999/xhtml">
|
||
|
||
<head>
|
||
<title>Functional programming in OCaml</title>
|
||
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
|
||
<link media="all" href="ystyle.css" rel="stylesheet" />
|
||
<script src="Scripts/yfold.js"></script>
|
||
</head>
|
||
|
||
<body>
|
||
<div class="header" id="header">
|
||
<h1 id="title">Functional programming in OCaml</h1>
|
||
</div>
|
||
<main>
|
||
<section class="yfold">
|
||
<h2 class="yfold-title" onclick="toggleYfold('f6c61644')"><span class="arrow" id="arrow-f6c61644">▸</span>Introduction</h2>
|
||
<div class="yfold-content flex" id="content-f6c61644" data-yfold-default="hide">
|
||
<section class="debug flex2 card">
|
||
<h3 class="debug">About the course</h3>
|
||
<p class="debug">Intended for functional beginners already familiar with some programming language.</p>
|
||
<h4 class="debug">Goals</h4>
|
||
<p class="debug">If all goes well, by the end of this course, you shall be able to:</p>
|
||
<ul class="debug success">
|
||
<li>Understand <b class="debug">lambda-terms</b> and write <b class="debug">pure functional programs</b>. </li>
|
||
<li>Design <b class="debug">recursive functions</b> to iterate over recursive <b class="debug">data types</b>. </li>
|
||
<li>Wonder how you have survived so far without <b class="debug">algebraic data types</b> and <b class="debug">parameterized types</b>. </li>
|
||
<li>Think in terms of <b class="debug">higher-order functions</b> in order to write reusable code. </li>
|
||
<li>Astonish yourself by writing <b class="debug">polymorphic functions</b> without even noticing. </li>
|
||
</ul>
|
||
<h4 class="debug">Evaluation</h4>
|
||
<p class="debug">The exam is on october, 12th: a list of exercises, on computer.</p>
|
||
</section>
|
||
<section class="debug flex1 card">
|
||
<h3 class="debug">Setup</h3>
|
||
<ul class="debug steps">
|
||
<li>To use OCaml at INSA, copy to your homedir <span class="debug file">/mnt/commetud/GEI/OCaml/.profile</span> and <b class="debug">read it.</b></li>
|
||
<li>Open a new terminal and launch utop: <code class="debug command">utop</code><br class="debug vskip" />You should get a nice greeting message. Press CTRL+D to quit.</li>
|
||
<li>Alternatively, you can write small OCaml programs directly on <a class="debug" target="_blank" href="https://try.ocamlpro.com/">Try OCaml</a>. </li>
|
||
</ul>
|
||
</section>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('f6c61644');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
<section class="yfold">
|
||
<h2 class="yfold-title" onclick="toggleYfold('bf745052')"><span class="arrow" id="arrow-bf745052">▸</span>Programming assignments (lessons)</h2>
|
||
<div class="yfold-content" id="content-bf745052" data-yfold-default="hide">
|
||
<p>Each lesson must be worked <b>individually</b>, and completed before starting the next one.</p>
|
||
<aside class="answers">
|
||
<h4>Answers</h4>
|
||
<ul>
|
||
<li>Lesson 1: <a class="caml_c" href="OCaml/all-answers/xkzb/lesson1.ml.html" data-eliom-c-onclick="1E4MGQOS9wC5">lesson1.ml</a></li>
|
||
<li>Lesson 2: <a class="caml_c" href="OCaml/all-answers/hitj/lesson2.ml.html" data-eliom-c-onclick="Grw/MZP+WPeg">lesson2.ml</a></li>
|
||
<li>Lesson 3: <a class="caml_c" href="OCaml/all-answers/lcdz/lesson3.ml.html" data-eliom-c-onclick="xypUTosu6RUM">lesson3.ml</a></li>
|
||
<li>Lesson 4: <a class="caml_c" href="OCaml/all-answers/pmyd/lesson4.ml.html" data-eliom-c-onclick="PCFy+czkv2Rs">lesson4.ml</a></li>
|
||
<li>Lesson 5: <a class="caml_c" href="OCaml/all-answers/fwiz/lesson5.ml.html" data-eliom-c-onclick="R4j/cMya1IJ+">lesson5.ml</a></li>
|
||
<li>Lesson 6: <a class="caml_c" href="OCaml/all-answers/dmug/lesson6.ml.html" data-eliom-c-onclick="vZsEvcolLYjP">lesson6.ml</a></li>
|
||
</ul><small class="pcom">Some solutions might be out of date, or unclear—<br />signal them to Mr. Le Botlan, then.</small>
|
||
</aside>
|
||
<ul class="lessons">
|
||
<li><a class="caml_c" href="OCaml/sujet1.html" data-eliom-c-onclick="a9t25dVDYCcf"><span class="lbutton">Lesson 1</span>The ocaml interpreter, ground types, built-in types.</a></li>
|
||
<li><a class="caml_c" href="OCaml/sujet2.html" data-eliom-c-onclick="v9VgLpqlyO9u"><span class="lbutton">Lesson 2</span>Functions, curryfication.</a></li>
|
||
<li><a class="caml_c" href="OCaml/sujet3.html" data-eliom-c-onclick="nVoR9pY+HmLK"><span class="lbutton">Lesson 3</span>Pattern matching, inner let.</a></li>
|
||
<li><a class="caml_c" href="OCaml/sujet4.html" data-eliom-c-onclick="x/OhOTSgZ4w2"><span class="lbutton">Lesson 4</span>Type structures.</a></li>
|
||
<li><a class="caml_c" href="OCaml/sujet5.html" data-eliom-c-onclick="B3smUwRNlwiX"><span class="lbutton">Lesson 5</span>Algorithms and more type structures</a></li>
|
||
<li><a class="caml_c" href="OCaml/sujet6.html" data-eliom-c-onclick="s69LFl2Iqlfj"><span class="lbutton">Lesson 6</span>Compilation, exceptions, side effects.</a></li>
|
||
</ul><br class="vskip" />
|
||
<h4>For the curious, some complementary information</h4>
|
||
<ul>
|
||
<li><a target="_blank" href="https://reasonml.github.io/">Facebook's REASON</a>, or how to program in OCaml while pretending to write Javascript.</li>
|
||
<li>Xavier Leroy, proficient developper of the Ocaml compiler, tells <a target="_blank" href="http://gallium.inria.fr/blog/intel-skylake-bug/">how he ran into a bug in some Intel processors</a>. </li>
|
||
<li>Watch 👁<a target="_blank" href="https://youtu.be/-PX0BV9hGZY">Tail-call recursion, the musical</a>, which explains how call-stacks work.</li>
|
||
<li>Learn why OCaml's <a target="_blank" href="http://www.ocamlpro.com/2020/03/23/ocaml-new-best-fit-garbage-collector/">Garbage collector</a> is efficient.</li>
|
||
</ul>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('bf745052');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
<section class="yfold">
|
||
<h2 class="yfold-title" onclick="toggleYfold('39af12ce')"><span class="arrow" id="arrow-39af12ce">▸</span>Exam-type exercises</h2>
|
||
<div class="yfold-content" id="content-39af12ce" data-yfold-default="hide">
|
||
<aside class="answers">
|
||
<h4>Answers</h4>
|
||
<ul>
|
||
<li>Ex. 1: <a class="caml_c" href="OCaml/all-answers/cnkv/exo1.ml.html" data-eliom-c-onclick="34UoL/1d4mYp">exo1.ml</a></li>
|
||
<li>Ex. 2: <a class="caml_c" href="OCaml/all-answers/viuq/exo2.ml.html" data-eliom-c-onclick="pRryOPK+/Lta">exo2.ml</a></li>
|
||
<li>Ex. 3: <a class="caml_c" href="OCaml/all-answers/mfmd/exo3.ml.html" data-eliom-c-onclick="DaTtfOf8fMb5">exo3.ml</a></li>
|
||
</ul>
|
||
</aside>
|
||
<ul>
|
||
<li>Exam questions are only intended to test your skills. They are not intended to be smart or enlightening. Thus, do not get surprised if examples are totally unmeaningful.</li>
|
||
<li>You do not have to write tail-recursive functions, unless explicitly required.</li>
|
||
</ul>
|
||
<ul class="lessons">
|
||
<li><a class="caml_c" href="OCaml/exercises1.html" data-eliom-c-onclick="/knwUQOtRXuQ"><span class="lbutton">Ex. 1</span>Basic types, curried functions, polymorphism, pattern matching</a></li>
|
||
<li><a class="caml_c" href="OCaml/exercises2.html" data-eliom-c-onclick="fQtG/3W6LzgO"><span class="lbutton">Ex. 2</span>Lists, records, variants.</a></li>
|
||
<li><a class="caml_c" href="OCaml/exercises3.html" data-eliom-c-onclick="xYhuiXiN7rkq"><span class="lbutton">Ex. 3</span>Recursive structures, exceptions</a></li>
|
||
<li><a target="_blank" href="https://ocaml.org/learn/tutorials/99problems.html"><span class="lbutton">Ex. 99</span>A list of 99 problems of various difficulty.</a><small class="pcom"> (Some of them are easier than the exam, some are
|
||
harder.)</small></li>
|
||
<li><a class="caml_c" href="OCaml/exam-2017.html" data-eliom-c-onclick="gcIDKoTkIR6N"><span class="lbutton">Ex. 2017</span>Exam questions, 2017.</a></li>
|
||
<li><a class="caml_c" href="OCaml/exam-2019.html" data-eliom-c-onclick="bvximRdiy7/t"><span class="lbutton">Ex. 2019</span>Exam questions, 2019.</a></li>
|
||
<li><a class="caml_c" href="OCaml/exam-2020.html" data-eliom-c-onclick="wNGyeoaEg24S"><span class="lbutton">Ex. 2020</span>Exam questions, 2020.</a></li>
|
||
</ul><br class="vskip" />
|
||
<h4 id="get-prepared">Get prepared for the exam:</h4>
|
||
<p>The following works only on INSA computers (purposely).</p>
|
||
<ul>
|
||
<li>You must have configured your account to use ocaml (see Setup above) </li>
|
||
<li>In a terminal, launch <code class="command">/mnt/commetud/GEI/run-exam &</code></li>
|
||
<li>Choose the <b>OCaml Test Exam</b>. The expected password is <kbd>exam</kbd></li>
|
||
<li>This test exam contains two easy questions.</li>
|
||
</ul>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('39af12ce');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
<section class="yfold">
|
||
<h2 class="yfold-title" onclick="toggleYfold('0836c5b9')"><span class="arrow" id="arrow-0836c5b9">▸</span>Project</h2>
|
||
<div class="yfold-content" id="content-0836c5b9" data-yfold-default="hide">
|
||
<p>The project is to be done by pairs of students having the same level.</p>
|
||
<h4>Requirements</h4>
|
||
<p>➪ You have completed all the lessons, and know how to write <a target="_blank" href="https://ocaml.org/learn/tutorials/modules.html">OCaml Modules. </a></p>
|
||
<h4>How it goes</h4>
|
||
<ul class="steps">
|
||
<li>The goal is to implement an algorithm computing the max-flow of a flow graph, using the Ford–Fulkerson algorithm, and optionally improve it to take into account other constraints (e.g. minimize cost).<br />See the <a class="caml_c"
|
||
href="OCaml/project.html" data-eliom-c-onclick="N1JNdzMrXJaN">details of the project</a>. </li>
|
||
<li>You are free to propose another project, by considering another graph algorithm — check with the teacher.</li>
|
||
</ul>
|
||
<h4>Evaluation</h4>
|
||
<ul>
|
||
<li>Before <b>december, 12th</b>, you have to send to your teacher (D. Le Botlan or A. Bit-Monnot) a link to your github project <small class="pcom">(or any other similar repository)</small>. </li>
|
||
<li>Manage to meet your teacher and show him a very quick demo (2 minutes). He will then ask you questions about your project (5-10 minutes).</li>
|
||
</ul>The final grade takes into account:<ul>
|
||
<li>your achievements (how much is in your project)</li>
|
||
<li>your code's modularity (do you use modules, abstract types?)</li>
|
||
<li>the level of abstraction and genericity (do you take advantage of polymorphism, parameterized types?)</li>
|
||
<li>code quality (comments, conciseness)</li>
|
||
<li>your answers to questions during the quick demo</li>
|
||
</ul>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('0836c5b9');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
<section class="yfold">
|
||
<h2 class="yfold-title" onclick="toggleYfold('577bfcbf')"><span class="arrow" id="arrow-577bfcbf">▸</span>Getting help</h2>
|
||
<div class="yfold-content flex" id="content-577bfcbf" data-yfold-default="hide">
|
||
<section class="debug flex2 card">
|
||
<h3 class="debug">Resources</h3>
|
||
<ul class="debug resources">
|
||
<li>Many resources about OCaml: <a class="debug url" target="_blank" href="https://ocaml.org/">//ocaml.org/</a></li>
|
||
<li><a class="debug" target="_blank" href="https://ocaml.org/learn/books.html">Books </a>to learn OCaml.</li>
|
||
<li>The very <b class="debug">official </b><a class="debug" target="_blank" href="http://caml.inria.fr/pub/docs/manual-ocaml/">OCaml manual</a>. </li>
|
||
<li>A well-written french book about functional programming (Bib'INSA): <br /><b class="debug">Mini Manuel de Programmation Fonctionnelle</b>—<i class="debug">Éric Violard</i>—DUNOD 978-2-10-070385-2</li>
|
||
<li><a class="debug" target="_blank" href="https://ocamlverse.github.io/">OCamlverse </a>: some documentation about OCaml.</li>
|
||
</ul>
|
||
</section>
|
||
<section class="debug flex3 card">
|
||
<h3 class="debug">OCaml at home</h3>
|
||
<ul class="debug">
|
||
<li>See <a class="debug" target="_blank" href="https://ocaml.org/docs/install.html">how to install</a>. <br /><small class="debug pcom">The recommended way is OPAM on linux.</small></li>
|
||
<li>Install packages text, utop and ocaml-top.</li>
|
||
<li>On windows, see how to install <a class="debug" target="_blank" href="https://www.typerex.org/ocaml-top.html">ocaml-top</a>. <small class="debug pcom"> (Have you considered switching to a decent, free OS ?)</small></li>
|
||
</ul>
|
||
</section><br />
|
||
<section class="stupid-flex-separator mml">
|
||
<h5>A stupid separator, because flex sucks in css.</h5>
|
||
</section>
|
||
<section class="yfold card flex3">
|
||
<h3 class="yfold-title" onclick="toggleYfold('19360194')"><span class="arrow" id="arrow-19360194">▸</span>Trouble?</h3>
|
||
<div class="yfold-content" id="content-19360194" data-yfold-default="hide">
|
||
<h4>Packages</h4>
|
||
<ul>
|
||
<li>If you need to use a package, e.g. <code class="inline">text</code> in an interpreter, you must start your program as follows:<br /><code class="block"><span class="directive">#use</span> <span
|
||
class="string">"topfind"</span> <span class="semi">;;</span> <span class="comment">(* Done once *)</span>
|
||
<span class="directive">#require</span> <span class="string">"text"</span> <span class="semi">;;</span> <span class="comment">(* For every package you need. *)</span>
|
||
</code></li>
|
||
</ul>
|
||
<h4>Pitfalls</h4>
|
||
<ul>
|
||
<li><b>Sequence</b>: when writing a sequence, do not put a <code class="block">;
|
||
</code> on the last statement.<br /><code class="block"><span class="kw">let</span> <span class="letvar">f</span> () =
|
||
<span class="uident">Printf</span>.printf <span class="string">"Meet"</span> ;
|
||
<span class="uident">Printf</span>.printf <span class="string">"John"</span> ;
|
||
<span class="uident">Printf</span>.printf <span class="string">"Doe"</span> ;
|
||
|
||
<span class="kw">let</span> <span class="letvar">g</span> x = x + <span class="number">1</span> <span class="comment">(* Error detected here. *)</span>
|
||
|
||
<span class="kw">let</span> <span class="letvar">h</span> x = x - <span class="number">1</span>
|
||
</code>
|
||
<ul>
|
||
<li>An error is detected at the end of the definition of g.</li>
|
||
<li>It is difficult to understand why the error appears there (try to find out).</li>
|
||
<li>The real error is the extra <code class="inline">;</code> at the end of <var>f</var><small class="pcom"> (after "Doe")</small>. </li>
|
||
</ul>To avoid this problem, always finish a sequence with unit (and no semicolumn), in order to mark clearly the end of the sequence:<br /><code class="block"><span class="kw">let</span> <span class="letvar">f</span> () =
|
||
<span class="uident">Printf</span>.printf <span class="string">"Meet"</span> ;
|
||
<span class="uident">Printf</span>.printf <span class="string">"John"</span> ;
|
||
<span class="uident">Printf</span>.printf <span class="string">"Doe"</span> ;
|
||
()
|
||
|
||
<span class="kw">let</span> <span class="letvar">g</span> x = x + <span class="number">1</span> <span class="comment">(* No error. *)</span>
|
||
|
||
<span class="kw">let</span> <span class="letvar">h</span> x = x - <span class="number">1</span>
|
||
</code>
|
||
</li>
|
||
<li><b>Nested pattern-matching: </b>be careful when a <code class="block"><span class="kw">match</span>
|
||
</code> occurs inside another pattern-matching:<br /><code class="block"><span class="comment">(* This (curried) function expects two arguments. *)</span>
|
||
<span class="kw">let</span> <span class="letvar">f</span> x = <span class="kw">function</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">match</span> x <span class="kw">with</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">true</span>
|
||
| <span class="number">2</span> -> <span class="kw">true</span>
|
||
| _ -> <span class="kw">false</span>
|
||
</code><br />It does not behave as you think. If you auto-indent the code, you get the real meaning: <br /><code class="block"><span class="kw">let</span> <span class="letvar">f</span> x = <span class="kw">function</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">match</span> x <span class="kw">with</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">true</span>
|
||
| <span class="number">2</span> -> <span class="kw">true</span>
|
||
| _ -> <span class="kw">false</span>
|
||
</code><br />To fix it, use <code class="kw">begin</code>...<code class="kw">end</code> or parentheses:<br /><code class="block"><span class="kw">let</span> <span class="letvar">f</span> x = <span class="kw">function</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">begin</span> <span class="kw">match</span> x <span class="kw">with</span>
|
||
| <span class="number">0</span> -> <span class="kw">false</span>
|
||
| <span class="number">1</span> -> <span class="kw">true</span>
|
||
<span class="kw">end</span>
|
||
| <span class="number">2</span> -> <span class="kw">true</span>
|
||
| _ -> <span class="kw">false</span>
|
||
</code><br />When a <mark>match is nested in another pattern-matching</mark>, it is good practice to put <code class="kw">begin</code>...<code class="kw">end</code> around it.</li>
|
||
</ul>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('19360194');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
<section class="card">
|
||
<h3>Tutorials</h3>
|
||
<ul>
|
||
<li><a target="_blank" href="http://baturin.org/docs/ocaml-faq/">What I wish I knew when learning OCaml.</a></li>
|
||
<li><a target="_blank" href="https://ocaml.org/learn/tutorials/structure_of_ocaml_programs.html">Local variables (<code class="inline">let .. in ..</code>)</a></li>
|
||
<li><a target="_blank" href="https://medium.com/@bobbypriambodo/getting-your-feet-wet-with-ocaml-ea1045b6efbc">Getting your feet wet with OCaml</a><small class="pcom"> (how to gently install and discover OCaml)</small>. </li>
|
||
<li><a target="_blank" href="https://www.fun-mooc.fr/courses/course-v1:parisdiderot+56002+session04/about">Le MOOC OCaml</a><small class="pcom"> (démarre en septembre 2019)</small></li>
|
||
</ul>
|
||
</section><span class="lbutton mml">❯ contact.lebotlan ❅ insa-toulouse.fr ❮</span>
|
||
</div>
|
||
<script>
|
||
//<![CDATA[
|
||
initYfold('577bfcbf');
|
||
//]]>
|
||
</script>
|
||
</section>
|
||
</main>
|
||
<footer><a target="_blank" href="http://www.insa-toulouse.fr"><img title="INSA Toulouse" style="width:194px;height:42px;" alt="INSA logo" src="Images/logo-insa.jpg" /></a><a target="_blank" href="https://www.laas.fr/"><img title="LAAS"
|
||
style="width:82px;height:42px;" alt="LAAS logo" src="Images/laas.png" /></a><a target="_blank" href="http://www.univ-toulouse.fr/"><img title="University of Toulouse" style="width:84px;height:42px;" alt="University of Toulouse logo"
|
||
src="Images/univt.jpg" /></a><small class="pcom"><a class="caml_c" href="yversion.html" data-eliom-c-onclick="HbfuNl/oa5yN">Version information</a></small><a target="_blank" href="http://ocaml.org/"><img title="Powered by OCaml code"
|
||
style="width:42px;height:42px;" alt="OCaml logo" src="Images/ocaml-small.png" /></a><a target="_blank" href="http://ocsigen.org/"><img title="Website generated by ocsigen & eliom" style="width:38px;height:32px;" alt="Ocsigen logo"
|
||
src="Images/ocsigen-small.png" /></a><a target="_blank" href="http://jigsaw.w3.org/css-validator/check/referer"><img title="Validate css stylesheet" style="width:28px;height:32px;" alt="CSS3 logo" src="Images/css3.png" /></a><a
|
||
target="_blank" href="http://validator.w3.org/check/referer"><img title="Validate html5 content" style="width:32px;height:32px;" alt="HTML5 logo" src="Images/html5.png" /></a></footer>
|
||
</body>
|
||
|
||
</html>
|