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

A lesson to help beginners dodge various syntax traps #117

Merged
merged 1 commit into from
Mar 7, 2013
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
2 changes: 1 addition & 1 deletion ocaml-lessons/lesson5/lesson.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<h3>-</h3>
<h3>Syntax Traps</h3>
20 changes: 17 additions & 3 deletions ocaml-lessons/lesson5/step1/step.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
<h3>This lesson is not yet available</h3>
<h3>Sequence of expressions</h3>

<p>Use <code>lessons ()</code> to get the list of all lessons.
Use <code>back ()</code> to return to the previous step.</p>
<p>It is easy to get confused by OCaml syntax since it's different from
mainstream languages. So you'd better be aware of a few things before digging
any deeper.</p>

<p>To begin with, you should know that a proper command must normally ends with
<em>';;'</em> to be processed by the top-level. This tutorial automatically adds
the double semicolon as soon as you hit enter but the normal top-level won't.
The double semicolon is only required when interacting with the top level
interpreter and as such is not part of OCaml syntax.</p>

<p>What <em>is</em> part of OCaml syntax, though, is the simple semicolon
<em>';'</em> which is commonly used as an expression terminator, except that in
OCaml it's a <b>separator</b>. In other words, you must not write <code>expr1;
expr2;</code> but <code>expr1 ; expr2</code>.</p>

<p>You may now enter <code>next ()</code> to check your understanding.</p>
2 changes: 1 addition & 1 deletion ocaml-lessons/lesson5/step1/step.ml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
fun input output ->
find_in "- : char =" output
false
16 changes: 16 additions & 0 deletions ocaml-lessons/lesson5/step2/step.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h3>Exercise: Get the Punctuation Right!</h3>

<p>Let's see if you got this right. Here is a sequence of erroneous
commands. Your task is to fix all of them in order to get the correct
answer at the end.</p>

<p><code>let fernand = "King of Castille";</code></p>

<p><code>let rodrigue = "The cid"; let diegue = "cid's father"</code></p>

<p><code>characters = [ fernand;; rodrigue;; diegue ]</code></p>

<p><code>rodrigue.[4] <- 'C' ; diegue.[0] <- rodrigue.[4] ;</code></p>

<p><code>characters</code></p>

3 changes: 3 additions & 0 deletions ocaml-lessons/lesson5/step2/step.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun input output ->
find_in "characters" input &&
output = "- : string list = [\"King of Castille\"; \"The Cid\"; \"Cid's father\"]\n"
18 changes: 18 additions & 0 deletions ocaml-lessons/lesson5/step3/step.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<h3>The <em>let</em> keyword</h3>

<p>The other source of confusion for newcomers is the <em>let</em> keyword
which acts differently in the toplevel than in normal OCaml expressions.</p>

<p>In the toplevel <code>let x = 1</code> binds the name <em>x</em> to the
integer 1 as seen in <code>lesson 2</code>. If x was already bound to something
it's previous binding is lost:</p>
<code>let x = "I am now a string!"</code>

<p>The <em>let</em> keyword is also used to form an expression in which a name
is given to some value temporarily, for the evaluation of a subexpression only:
<code>let x = 41 in x + 1</code>. The value of <em>x</em> is <em>41</em> during
the evaluation of <em>x + 1</em> only; the global binding of <em>x</em> to
<code>"I am now a string!"</code> is preserved.</p>

<p>See what <code>x</code> is evaluated to now, and type <code>next ()</code>
for a little practice.</p>
2 changes: 2 additions & 0 deletions ocaml-lessons/lesson5/step3/step.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fun input output ->
false
18 changes: 18 additions & 0 deletions ocaml-lessons/lesson5/step4/step.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<h3>Exercise: let there be lets!</h3>

<p>Fix all these <em>let</em> expressions in order to get the expected result
at the end:</p>

<pre><code>let xy =
let x = 'x' and let y = 'y' in x ::[y]</code></pre>

<pre><code>let ab =
let a = 'a'
let b = 'B' in Char.lowercase b
in a ::[b]
</code></pre>

<pre><code>let up = Char.uppercase in
big_xy = List.map up xy ;
big_ab = List.map up ab ;
big_ab @ big_xy</code></pre>
3 changes: 3 additions & 0 deletions ocaml-lessons/lesson5/step4/step.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fun input output ->
find_in "Char.uppercase" input &&
output = "- : char list = ['A'; 'B'; 'X'; 'Y']\n"
23 changes: 23 additions & 0 deletions ocaml-lessons/lesson5/step5/step.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h3>Parentheses</h3>

<p>With regard to grouping expression or enforcing order of evaluation,
OCaml syntax is surprisingly easy: you can use pervasively either parentheses
of <em>begin</em>/<em>end</em> keywords.</p>

<p>Example grouping expressions in an <em>if</em> form:</p>
<pre><code>if 1+2 = 3 then (
print_string "did you knew that?\n" ;
print_string "amazing!\n"
)
</code></pre>

<p>Or forcing order of evaluation with <em>begin</em>/<em>end</em> (although
you won't find this often!):</p>
<code>begin 1 + 2 end * 3</code>

<p>Also, as function application takes precedence over infix operators you will
frequently uses parentheses to make explicit the expected evaluation order, as
in: <code>square (1 + 1)</code> since <code>square 1+1</code> would yield
<em>2</em>.

<p>Enter <code>next ()</code> when you are ready to practice.</p>
2 changes: 2 additions & 0 deletions ocaml-lessons/lesson5/step5/step.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fun input output ->
false
25 changes: 25 additions & 0 deletions ocaml-lessons/lesson5/step6/step.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<h3>Exercise: Fix the grouping</h3>

<p>A Lisp programmer stole all our parentheses!
Get them back in order to get the proper result at the end.</p>

<pre><code>let ten =
let double x = x+x in
double 3 + 2</code></pre>

<pre><code>let hundred =
if true or false then
print_string "May I help you?\n" ;
100
else 0</code></pre>

<pre><code>let one =
let accum = ref -54 in
for i = 1 to ten do accum := !accum + i done ;
!accum </code></pre>

<pre><code>one + match hundred with
| 42 -> match ten with 10 -> 52 | _ -> 0
| 100 -> match ten with 10 -> 110 | _ -> 0
</code></pre>

2 changes: 2 additions & 0 deletions ocaml-lessons/lesson5/step6/step.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fun input output ->
find_in "match" input && output = "- : int = 111\n"