72 lines
No EOL
19 KiB
HTML
72 lines
No EOL
19 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> |