From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 350537EF28 for ; Thu, 25 Jun 2015 18:51:29 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of philippe.wang.lists@gmail.com) identity=pra; client-ip=209.85.160.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="philippe.wang.lists@gmail.com"; x-sender="philippe.wang.lists@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of philippe.wang.lists@gmail.com designates 209.85.160.180 as permitted sender) identity=mailfrom; client-ip=209.85.160.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="philippe.wang.lists@gmail.com"; x-sender="philippe.wang.lists@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-yk0-f180.google.com) identity=helo; client-ip=209.85.160.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="philippe.wang.lists@gmail.com"; x-sender="postmaster@mail-yk0-f180.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CJAQDWMIxVlLSgVdFbg2VfBoMYu1uHNgdMAQEBAQEBEgEBAQEHCwsJHzCEIgEBAQMBEhEdATgBAwwBBQULDQICJgICIhIBBQEcBhMIGod4AwoIrCQ+MYs/hGSLQCcNhWcBJQEFDoETiSeBAoQtBwEBgz+BQwEElAZKhA6GeoE6QpJhghESI4EWF0mDQjwxgQMJF4ElAQEB X-IPAS-Result: A0CJAQDWMIxVlLSgVdFbg2VfBoMYu1uHNgdMAQEBAQEBEgEBAQEHCwsJHzCEIgEBAQMBEhEdATgBAwwBBQULDQICJgICIhIBBQEcBhMIGod4AwoIrCQ+MYs/hGSLQCcNhWcBJQEFDoETiSeBAoQtBwEBgz+BQwEElAZKhA6GeoE6QpJhghESI4EWF0mDQjwxgQMJF4ElAQEB X-IronPort-AV: E=Sophos;i="5.13,678,1427752800"; d="scan'208";a="167292219" Received: from mail-yk0-f180.google.com ([209.85.160.180]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 25 Jun 2015 18:51:28 +0200 Received: by ykdr198 with SMTP id r198so43624506ykd.3 for ; Thu, 25 Jun 2015 09:51:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=pUeVKrTCEsZw8O0OJYvJWrnEmfplpwfFIVmMnGtU6Ig=; b=c3KSN8Xehv/cdQW5cdseGiqdjifEtlpGodbTOGIhdDqS0TPls0vW4Of6OdF5EikPcA 6W9TSHfGIICBkGluHd65r5+WyysJ4QF7g1FScUgj8hpmW5AMU1ypWiXNF5/DFkKetRpL 0wkqqnLFmpnR6Fh9+Asxy85AogzaH59GVP50UT7T9zxs3HHot9VVr/JF9kinfHAiqGOu bKvsaPAL/jwr8XvGJMCdIROSrseqVutZz7B+WloTF5JzcBHIIHbi1IlGx4qAcoatOjCk Ea9CfbAijGXIGjCa6iU0wOCitrLOwuhzMEAm7lgDDPiNJFJ1OsK3kpwMun2I0wvXhIy4 s+pw== MIME-Version: 1.0 X-Received: by 10.170.121.210 with SMTP id n201mr34472989ykb.97.1435251087238; Thu, 25 Jun 2015 09:51:27 -0700 (PDT) Sender: philippe.wang.lists@gmail.com Received: by 10.37.203.135 with HTTP; Thu, 25 Jun 2015 09:51:27 -0700 (PDT) In-Reply-To: References: Date: Thu, 25 Jun 2015 18:51:27 +0200 X-Google-Sender-Auth: mW-rDdhKxohWt-JO_o4PwinrENk Message-ID: From: Philippe Wang To: Alan Schmitt Cc: OCaml Mailing List Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] use of ";;" when teaching Ocaml On Tue, Jun 23, 2015 at 3:27 PM, Alan Schmitt wrote: > Hello, > > Thanks to everyone for your answers, this has given me much food for > thought. > > On 2015-06-23 01:41, Philippe Wang writes: > >> In my opinion, it's a lot more relevant to use a very limited and very >> simple subset of OCaml when teaching to beginners. And this subset >> does not involve expressions at top-level because it's not worth the >> trouble. > > I like this approach because it amounts to saying "one always starts > a phrase with 'let' or 'type'" (and later in the year there can be > 'open', 'module', 'include'). I sure can live without top-level > expressions. > > On the other hand, I also like the idea of terminating phrases, simply > because explaining when it terminates is not trivial otherwise, as > a 'let' may not be the beginning of a phrase. Well, a computer is (by definition) stupid, and languages made by humans are like human: none is perfect! :) So... there's the global `let` and the local `let...in`, it sucks a little but everyone is free to propose a new language (yeah, that's what i used to tell student who would complain about design) :) >> Also, using the interactive top-level loop is, in my opinion, not good >> for beginners. It should only be presented to those who already >> understand very well the "core" of OCaml. The most frequent issue with >> the top-level loop is that it gets in the way of the notion of >> compiling a program, and it might give the false impression that OCaml >> can be interpreted. > > I am curious about this. My goal is to teach the language, and I find > that a REPL backed with a file works great to do this (using tuareg or > ocaml-top). What do you use to make sure students have a fast > compile/debug cycle? Well, it depends a lot on the skills of the students: for beginners, I believe it doesn't help a lot to have the REPL. The one very annoying thing that goes with REPLs is understanding the difference between the result of a program and what is printed on stdout (or even stderr). For instance, lots of students would mix "42;;" and "print_int 42;;" and you would need to spend quite sometime explaining this and repeating they are not the same at all, and spend quite some energy containing the bomb that wants to detonate inside of you when they keep repeating that mistake! But, if you have some experimented programmers, or some extremely smart beginners, you may have fun with this kind of things because there actually are so many of them in OCaml, like a gigantic gold mine. (I have to admit, I kind of like it. But when I want efficiency, I don't go there.) So, fast compile/debug cycle? Well, my suggestion is to use a Makefile and invoke make as often as possible (meaning as soon ). If the program is small enough, I won't even use make, I will directly call ocamlc. (Not ocamlopt, because ocamlc is faster at compiling than ocamlopt.) Well, then when the program becomes "big" enough, I will use a Makefile. The errors messages of ocamlc/ocamlopt are not worse than ocaml REPL's, sometimes they are even better. Also, it will avoid the awkward situation where your program works fine with ocaml but won't compile with ocamlc/ocamlopt, because there's a weirdo that has weak types... ;-) Note that it's possible to use `ocaml program.ml`, so you don't have to do something like `ocamlc program.ml && ./a.out`. Also, it's not bad to tell your students to declare all their functions before implementing them. Use for instance let koala food = failwith "koala not implemented yet", especially when they have mutually recursive functions: this way they may compile their programs before they have (wrongly-)implemented everything, and look for errors, instead of having to have a giant mess to deal with... Cheers, Philippe Wang