Let's start by problems I didn't cause.
= Not my fault =
== Environment ==
* OCamlWinPlus, in its current incarnation, is just awful. To improve
it, one would need to fix the bugx, make it possible to remember the
list of modules loaded, link it to the documentation, etc.
* Camelia IDE is simple and good but difficult to install, as it
requires Cygwin. It lacks project management, though -- and, now,
ocamlbuild support. I believe that it could draw some inspiration from
Dr.Java.
* Students just can't install LablGtk, LablGl, Camlimage... by
themselves, nor would I expect them to. A nice, centralised, installer,
would be nice.
* Building projects is just too hard. I hope ocamlbuild will solve this.
* It seems that Graphics doesn't work with Cygwin, hence with Camelia
for Windows. Which is bad, as they seem to enjoy both Graphics and
Camelia. What prevents Graphics in Cygwin+X ?
== Error messages ==
* Error messages of the type system are somewhat obscure. The reflex of
many students is "OCaml wants it to be of type XXX", rather than "there
is a contradiction in what I wrote". It would be nice if there was a way
to ask OCaml to display additional information on type errors. Say
something like, whenever typing of an expression fails, restarting the
type algorithm but printing out the various unifications as they take
place.
== Documentation ==
* Documentation of LablTk is non-existent. I'm thinking about taking a
student to write a more OCaml-ish layer on top of LablTk but I don't
know if/when this will happen.
* Type 'option' doesn't appear in the list of types of the
documentation. Nor do 'Some' and 'None' appear in the list of values.
* A nice *beginner-oriented* tutorial is really missing for students who
failed to pay attention to the beginning of the lecture. Something more
applied than _Developing applications with OCaml_ and less technical
than http://ocaml-tutorial.org . Say, leading a beginner to define a
Connect 4 game. I'm willing to participate into writing this, but not
alone. I might launch a thread on this subject on the ML.
= My fault =
* That's not OCaml-specific but there must be some construction better
suited than "for" or "while" to write loops without having to handcode a
recursive loops. Right now, I can't think of anything better than a
"hidden" Y combinator, but there must be something.
* Arrays of arrays (of arrays...) are a bit obscure for students,
although they're getting better at it.
* Some students rely too much on references.
* The usual note-taking/attention deficit/motivation deficit problems.
* Anonymous functions are still beyond most of them.
--
David Teller ------------------------------------------
Security of Distributed Systems -----------------------
-- http://www.univ-orleans.fr/lifo/Members/David.Teller
----- Laboratoire d'Informatique Fondamentale d'Orleans
_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs
> * Type 'option' doesn't appear in the list of types of the
> documentation. Nor do 'Some' and 'None' appear in the list of values.
Huh? It's there in section 19.1 of the manual -- Built-in types and
pre-defined exceptions.
William D. Neumann
---
"There's just so many extra children, we could just feed the
children to these tigers. We don't need them, we're not doing
anything with them.
Tigers are noble and sleek; children are loud and messy."
-- Neko Case
Life is unfair. Kill yourself or get over it.
-- Black Box Recorder
> Third and (probably) last part of my Teaching bottomline. I hope some of
> you find this useful.
Thanks David. I'm not even a teacher (well not currently) and I
still found that an interesting read.
Erik
--
-----------------------------------------------------------------
Erik de Castro Lopo
-----------------------------------------------------------------
"Copyrighting allows people to benefit from their labours,
but software patents allow the companies with the largest
legal departments to benefit from everyone else's work."
-- Andrew Brown
(http://www.guardian.co.uk/online/comment/story/0,12449,1387575,00.html)
> * Error messages of the type system are somewhat obscure. The reflex of
> many students is "OCaml wants it to be of type XXX", rather than "there
> is a contradiction in what I wrote". It would be nice if there was a way
> to ask OCaml to display additional information on type errors.
This is a long standing peeve of mine. Lets face it: Ocaml just lies.
If it has inferred a type, then finds a contradiction, it should
report both the location of the contradication AND all of the source
lines that contributed to the inference.
I understand that is may be hard, if not impossible, to implement,
as it would require a unification engine that could manage
source references in parallel with deductions .. still the information
IS available originally.
I bet this would be an interesting and valuable PhD project,
and, IMHO, without it type inferencing languages are useless
in industry. Type errors in Ocaml code are very common for the
simple reason they're just about the only error you can make :)
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
> * Students just can't install LablGtk, LablGl, Camlimage... by
> themselves, nor would I expect them to. A nice, centralised, installer,
> would be nice.
This sound like your School's fault. Why aren't they running
Debian or Ubuntu?
Because on those systems .. installing Ocaml packages is a breeze.
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
_______________________________________________
On Tuesday 22 May 2007 23:10:23 David Teller wrote:
> * OCamlWinPlus...Camelia IDE...LablGtk, LablGl, Camlimage ...
> ... It seems that Graphics doesn't work with Cygwin, hence with Camelia ...
There are two possibilities here:
You want to use Windows => Use F#, Visual Studio and F# for Visualization and
not OCaml.
You want good free software => Use Linux and not Windows.
> == Error messages ==
>
> * Error messages of the type system are somewhat obscure. The reflex of
> many students is "OCaml wants it to be of type XXX", rather than "there
> is a contradiction in what I wrote". It would be nice if there was a way
> to ask OCaml to display additional information on type errors. Say
> something like, whenever typing of an expression fails, restarting the
> type algorithm but printing out the various unifications as they take
> place.
F# currently has better graphical throwback of inferred type information but
slightly worse messages, IMHO.
> * Documentation of LablTk is non-existent. I'm thinking about taking a
> student to write a more OCaml-ish layer on top of LablTk but I don't
> know if/when this will happen.
You get what you pay for as far as documentation is concerned. OCaml is
largely undocumented (the compiler, several code libraries, the top-level,
camlp4). There is some additional documentation (e.g. my book) but you must
pay for it.
> * A nice *beginner-oriented* tutorial is really missing for students who
> failed to pay attention to the beginning of the lecture. Something more
> applied than _Developing applications with OCaml_ and less technical
> than http://ocaml-tutorial.org . Say, leading a beginner to define a
> Connect 4 game. I'm willing to participate into writing this, but not
> alone. I might launch a thread on this subject on the ML.
I'm very interested in writing an introduction to OCaml and publishing it as a
very cheap book, maybe through O'Reilly.
> * That's not OCaml-specific but there must be some construction better
> suited than "for" or "while" to write loops without having to handcode a
> recursive loops. Right now, I can't think of anything better than a
> "hidden" Y combinator, but there must be something.
I often use a nest function:
let rec nest n f x = if n=0 then x else nest (n-1) f (f x)
F# also provides sequences and comprehensions:
let factorial n = Seq.fold ( * ) 1 {2 .. n}
> * Arrays of arrays (of arrays...) are a bit obscure for students,
> although they're getting better at it.
F# provides multidimensional arrays, arbitrary-size arrays, immutable arrays,
resizeable arrays, allows array subscript syntax to be overloaded and is
faster than OCaml on array code. Arrays are a real weak point of OCaml ATM,
along with div and mod, functors, concurrency and some other things.
> * Some students rely too much on references.
F# doesn't help you there.
> * The usual note-taking/attention deficit/motivation deficit problems.
Or there...
> * Anonymous functions are still beyond most of them.
SML can do them with one fewer letters!
If you want your students to be future proof then you would do well to prepare
them for massively parallel computing on CPUs with hundreds or even thousands
of cores. OCaml it completely ill-equipped for this. In contrast, F# provides
native threads/locks/semaphores/threads/threadpools inherited from .NET as
well as async programming via extra syntax. Concurrency is beautiful in F#
and it works today.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e
--- skaller <ska...@users.sourceforge.net> wrote:
____________________________________________________________________________________Ready for the edge of your seat?
Check out tonight's top picks on Yahoo! TV.
http://tv.yahoo.com/
> This is a long standing peeve of mine. Lets face it: Ocaml just lies.
> If it has inferred a type, then finds a contradiction, it should
> report both the location of the contradication AND all of the source
> lines that contributed to the inference.
Reporting all of the source lines has been investigated; see
C. Haack and J. B. Wells. Type error slicing in implicitly typed
higher-order languages. Science of Computer Programming, 50(1-
3):189–224, 2004.
My intuition is there are many situations where this gives you too much
information just as one location gives you too little.
Switching to personal horn-tooting mode, you may be interested in a
paper we have in PLDI next month where we take a completely different
approach to presenting Caml type-errors -- we don't report any types at
all, but rather we report a similar program that does type-check.
See http://www.cs.washington.edu/homes/blerner/seminal.html. The PLDI
paper is the place to start. The prototype implementation may prove
useful to the very brave of heart, but it's really designed to
demonstrate the idea.
--Dan
> * That's not OCaml-specific but there must be some construction better
> suited than "for" or "while" to write loops without having to handcode a
> recursive loops. Right now, I can't think of anything better than a
> "hidden" Y combinator, but there must be something.
What about map fold, filter, and the like? Sure, they are somewhat
specialized, but most can be rewritten for many data structures.
If you are really desperate, You can write The Recursive Loops
(terminal and not terminal, 3 lines each). But I guess you tried.
> * Arrays of arrays (of arrays...) are a bit obscure for students,
> although they're getting better at it.
>
> * Some students rely too much on references.
If they are used to for and while loops, they will think more often in
terms of references (as I did). Then, we have the array, a collection
of references. Do you think your students could learn some purely
functional data structures instead? Should they?
> * Anonymous functions are still beyond most of them.
That sounds surprising, for anonymous function are no different from named ones:
5;; (* a value *)
fun x -> x+1;; (* another value, which happens to be a function *)
a = 5;; (* a bound value *)
b = fun x -> x+1;; (* another bound value, which happens to be a function *)
Did your students used map and fold-like functions much? These almost
require anonymous functions.
regards,
Loup Vaillant
I agree, this is one of the worst thing about ocaml type inference,
and you sometimes end up to have to put explicit type to functions to
find the offending lines (usually hundreds lines before the actual line
that's printed), defeating the whole thing...
Cheers,
--
Vincent Hanquez
Just what I was going to say!
Hopefully it'll be a breeze on Fedora soon too.
Rich.
--
Richard Jones
Red Hat
> (...)
>> * Anonymous functions are still beyond most of them.
>
> That sounds surprising, for anonymous function are no different
> from named ones:
>
> 5;; (* a value *)
> fun x -> x+1;; (* another value, which happens to be a function *)
Those are typically the comments of a "used-to-functional-
programming" guy.
It certainly doesn't match what a beginner would think (no beginner
will call a
function a "value").
Or do you really think that seeing functions as first-class object is
the natural way ?
IMHO this is not the case, and therefore not the case of a beginner.
To my eyes, there are (I mean, "in human mind" or at least in an
ocaml beginner's mind)
values AND functions. A function turns into a value (in the mind of
the programmer)
only when it is used by a higher order function.
> a = 5;; (* a bound value *)
> b = fun x -> x+1;; (* another bound value, which happens to be a
> function *)
>
> Did your students used map and fold-like functions much? These almost
> require anonymous functions.
Indeed, using map and fold puts the focus on the fact that functions
_can_ be values.
Thus their importance in a pedagogical context.
Maybe all this is just a matter of belief...
Regards,
Vincent
>On Wed, May 23, 2007 at 09:16:44AM +1000, skaller wrote:
>
>
>>On Tue, 2007-05-22 at 18:10 -0400, David Teller wrote:
>>
>>
>>
>>>* Error messages of the type system are somewhat obscure. The reflex of
>>>many students is "OCaml wants it to be of type XXX", rather than "there
>>>is a contradiction in what I wrote". It would be nice if there was a way
>>>to ask OCaml to display additional information on type errors.
>>>
>>>
>>This is a long standing peeve of mine. Lets face it: Ocaml just lies.
>>If it has inferred a type, then finds a contradiction, it should
>>report both the location of the contradication AND all of the source
>>lines that contributed to the inference.
>>
>>
>
>I agree, this is one of the worst thing about ocaml type inference,
>and you sometimes end up to have to put explicit type to functions to
>find the offending lines (usually hundreds lines before the actual line
>that's printed), defeating the whole thing...
>
>Cheers,
>
>
Hundreds of lines? I've seen ten's of lines, but never hundreds.
Of course, I generally type annotate at the level of functions at least
(using .mli files is to be encouraged, IMO). So type errors generally
don't escape functions. And I keep functions reasonably short- tens of
lines long at most...
Brian
You are quite right. My point was to find a way to tell the beginners.
A way to stress upon the fact that functions are values like any other
(in Ocaml, at the very least).
I see some difficulties, thought :
First, the syntax:
b = fun x -> x+1;; (* b defined as a functionnal value *)
b x = x+1;; (* b defined as a mere function *)
Second, imperative languages, where b can only be defined as a mere
function. Many courses begin with an imperative language.
Third, high school, where the only functions we dare name as such are
of type number -> number. Derivation and composition, for instance,
are named "operations", not functions. As if they have anything
special (usefulness excepted). Finally, each function has a name in
high shool mathematics.
> Or do you really think that seeing functions as first-class object is
> the natural way ?
> IMHO this is not the case, and therefore not the case of a beginner.
I agree. I just hope it can become A natural way.
> To my eyes, there are (I mean, "in human mind" or at least in an
> ocaml beginner's mind)
> values AND functions. A function turns into a value (in the mind of
> the programmer)
> only when it is used by a higher order function.
I think there are some other uses, too : data structures can contain
closures for instance. A lazily evaluated value is a function (a
closure).
> > Did your students used map and fold-like functions much? These almost
> > require anonymous functions.
>
> Indeed, using map and fold puts the focus on the fact that functions
> _can_ be values.
> Thus their importance in a pedagogical context.
Not only : most loops in a list or an array can be expressed as a
combination of map and fold (and filter, and...). Using these
significantly reduce the amount of code.
> Maybe all this is just a matter of belief...
I am quite a zeelot of abstraction. :)
Regards,
Loup
I can confirm that: hundreds. This happens especially for mismatching
class types, because the compiler tries to break the mismatch down.
But beginners shouldn't use classes.
> Of course, I generally type annotate at the level of functions at
> least (using .mli files is to be encouraged, IMO). So type errors
> generally don't escape functions. And I keep functions reasonably
> short- tens of lines long at most...
There is certainly a point. The length of type errors depends on your
programming style. A teacher can give hints how to make everything
easier to handle. (Although it is also a valid point in education to let
the students find their limits.)
Gerd
--
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany
ge...@gerd-stolpmann.de http://www.gerd-stolpmann.de
Phone: +49-6151-153855 Fax: +49-6151-997714
------------------------------------------------------------
When did you go to school? These days many people have their own
computers and aren't working in school maintained computer labs. ;-)
>
> There is certainly a point. The length of type errors depends on your
> programming style.
It can also depend on the size of the type involved,
which is not nearly as much of a stylistic thing.
If you have several polymorphic variants types of
20-30 constructors each, recursively included in
each other .. you can get errors many hundreds of lines
long, involving scores of invented type variables, and
for me, when i get such errors, the information in the
diagnostic is more or less entirely useless.
I use the error location and knowledge of my last
change to track down where to add coercions and
annotations to help find the error ..
I got one a couple of days ago in code generated
by dypgen .. and just gave up .. since I didn't write
the code and had no idea what the types were (my
types were involved too .. the combination was
a type about 80 lines long .. :)
Ocaml has improved though: today it often gives a nasty
message and the kindly tells you which constructor is
causing the mismatch. This helps a LOT!
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net
_______________________________________________
Not only hundreds of lines, but usually in a completely different file, too.
This expression has type exactly_what_it_should be, but is here used with
type compeletly_off_the_mark.
How I hate it.
Yours, Florian.
>Brian Hurt schrieb:
>
>
>>Hundreds of lines? I've seen ten's of lines, but never hundreds.
>>
>>
>
>Not only hundreds of lines, but usually in a completely different file, too.
>
>This expression has type exactly_what_it_should be, but is here used with
>type compeletly_off_the_mark.
>
>How I hate it.
>
>
>
mli files. Use them. Trust me.
Simply because code compiles doesn't necessarily mean it's right. Often
times I write the .mli file first, as it's a convient level to think
about what the interface to a module should be. But at the very least
you should use ocamlc -i to generate the .mli file when you are more or
less done with the module, and then hand verify it as correct. And then
keep it around, to make sure the module remains correct in the face of
future changes. Doing this will keep type errors in the same file, at
least.
Brian
Essentially, the game involves having person A come up with a rule.
Person B will have to provide an input value, and A has to faithfully
give the result of the rule/computation. Examples of functions could be
\x->x+2, \x->2*x, etc. More interesting examples involves the function
that returns the first letter of the name of the input (f "one" = "o"),
or the successor of a "red, yellow, green" traffic light symbol.
When doing this, A and B will quickly have to agree on the allowed input
values (the domain) and in order to have a chance it is also helpful if
B knows the range of output values (the image). And for sure - they will
have to agree that the rule x = y => f(x) = f(y) has to hold in order to
be able to guess what "f" is. [I would also disallow closures for this
game - otherwise it would be too hard to guess.]
The reason this exercise is good is that it teaches the students (in a
fun way) the important concepts behind a function. It will make them
understand that a function is just a computation, but also point out the
importance of defining the types (sets) of inputs and outputs. I think
that after playing this game, you can venture to talk about the "name"
of the function, and they will realize that it does not matter what the
name of the function is - just what it does.
Perhaps after this, you can teach the concept of treating a function as
a value, or input to another function? Person A makes a function that
takes person B's function, etc.
Thanks,
PKE
--
Pål-Kristian Engstad (eng...@naughtydog.com), Lead Graphics & Engine Programmer,
"Uncharted"-team, Naughty Dog, Inc., 1601 Cloverfield Blvd, 6000 North,
Santa Monica, CA 90404, USA. Ph.: (310) 633-9112.
"Most of us would do well to remember that there is a reason Carmack
is Carmack, and we are not Carmack.",
Jonathan Blow, 2/1/2006, GD Algo Mailing List
~~ Robert.
_______________________________________________
F# scales to hundreds or thousands of cores?
If the OP wants to teach his students about massively parallel
computing, he should avoid the Microsoft lock-in and teach them about
it on Linux clusters.
Rich.
--
Richard Jones
Red Hat
_______________________________________________
~~ Robert.
Richard Jones wrote:
> On Wed, May 23, 2007 at 12:39:29AM +0100, Jon Harrop wrote:
>
>> If you want your students to be future proof then you would do well
>> to prepare them for massively parallel computing on CPUs with
>> hundreds or even thousands of cores. OCaml it completely
>> ill-equipped for this. In contrast, F# provides native
>> threads/locks/semaphores/threads/threadpools inherited from .NET as
>> well as async programming via extra syntax. Concurrency is beautiful
>> in F# and it works today.
>>
>
> F# scales to hundreds or thousands of cores?
>
> If the OP wants to teach his students about massively parallel
> computing, he should avoid the Microsoft lock-in and teach them about
> it on Linux clusters.
>
> Rich.
>
>
_______________________________________________
Then he should not be using Microsoft Windows.
I think Linux users should use OCaml and Windows users should use F#. Anything
else is just perverted.
I suspect the reality is that both Windows and zero-budget have been imposed
upon David, which is simply insane because Windows is a very expensive
commercial platform and the quality of free software on Windows is far below
that on Linux.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e
_______________________________________________
> ...and locks and threads are not a viable long-term solution to the
> problem of concurrency in general. You're future-proofing enough by
> teaching them functional languages: Erlang and Cilk are closer to the
> needed future.
>
I think you mean "Haskell+STM" instead of Cilk. Cilk isn't a
particularly functional language (being effectively C plus a little bit).
Brian
Robert Fischer
IT Firefighter
Smokejumper Consulting
Absolutely, that's why we have parallel iter, map, fold etc.
> You're future-proofing enough by teaching them functional languages
Functional programming is not a panacea. GUI programming is one application
area where functional programming, immutability and the parallelizable
constructs that I just mentioned are not so beneficial.
To solve GUI programming you need different constructs (events, message pumps
etc.).
Look at some of the example F# programs on our site. This Sudoku solver uses a
worker thread to keep the GUI responsive while it solves puzzles:
http://www.ffconsultancy.com/dotnet/fsharp/sudoku/index.html
This ray tracer uses concurrency for incremental update of a responsive GUI:
http://www.ffconsultancy.com/dotnet/fsharp/raytracer/index.html
This particle simulator runs the simulation thread in parallel with the GUI
thread, for real-time visualization of the particle system:
http://www.ffconsultancy.com/products/fsharp_for_visualization/demo3.html
In the future, I hope OCaml will support concurrency not only to handle
parallel constructs but also to handle GUI programming elegantly. If there is
one thing that I have been singularly impressed by from .NET, it is GUI
programming.
--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e
_______________________________________________
It's happening sometimes, and it's a major pain. It usually because you
got the wrong type returned, and you got lots of passthrough functions.
when it gets into the function that actually do something with the data,
ocaml see a mismatch obviously... in this case you want to correct the
source function, not where the error happened ...
> Of course, I generally type annotate at the level of functions at least
> (using .mli files is to be encouraged, IMO). So type errors generally
> don't escape functions. And I keep functions reasonably short- tens of
> lines long at most...
this is certainly a very good thing to do, but some people doesn't do
this unfortunately :(
For .mli file, it's not always an advantage to have them; having 2
files to edit each time you make a modification is quite annoying..
I wish there was an inline signature ala Haskell for OCaml, something
along the line of:
=== string.ml ====
val length : string -> int
...
let length s = ...
...
==================