From: Jon Harrop
Subject: Concentration in OCaml
Date: 
Message-ID: <4309da18$0$97131$ed2619ec@ptn-nntp-reader03.plus.net>
Wade Humeniuk wrote:
> Here is an example
> of a program in Lisp which is non-trivial (no macros, well not
> quite true... capi:define-interface is one such builtin LispWorks
> macro, oh ... and defclass and capi:with-geometry, etc etc.).

I have implemented a completely different version of the same game in OCaml
for comparison. It took me 2hrs 20mins to complete (without proper testing)
and is 164LOC.

I used our in-house vector graphics library "Smoke" and Glut instead of
Motif. I believe the program complexity is roughly the same as yours so it
is still useful for comparison but Smoke allowed me to do some interesting
things:

1. Hardware accelerated rendering via OpenGL.
2. 2D vector graphics.
3. Embedded Computer Modern fonts.
4. OpenGL picking.

The code could still do with some work but this is ok for a first draft.
You'd need a copy of Smoke to compile it (which you can't have, sorry) but
it should compile on Mac OS X and Windows as is.

Of course, there are many advantages to using OpenGL instead of Motif. It
would be easy to make the cards rotate and shrink. It would also be quite
cool to use 3D objects instead of glyphs.

I'll put a binary up ASAP. Here's the source:

open Printf
open Utility
open VecMat
open Smoke
open SceneGraph
open Cmfont

let time = Unix.gettimeofday

let board_w = 6 and board_h = 6

let list_rev_chop i l =
  let rec aux i fr ba = match i, fr, ba with
    | 0, fr, ba -> (fr, ba)
    | i, fr, h::t -> aux (i-1) (h :: fr) t
    | _ -> invalid_arg "list_rev_chop" in
  aux i [] l

let list_extract i l = match list_rev_chop i l with
  | fr, h :: t -> h, List.rev_append fr t
  | _ -> invalid_arg "list_extract"

let list_randomise l =
  let extract_rand l = list_extract (Random.int (List.length l)) l in
  let rec aux accu = function
    | [] -> accu
    | l -> (fun (h, t) -> aux (h :: accu) t) (extract_rand l) in
  aux [] l

(* Generate a board containing random pairs of characters *)
let new_board () : int option array array =
  let board = Array.create_matrix board_w board_h None in
  let symbols = Array.to_list (Array.init (126-33) (fun i -> 33+i)) in
  let pos =
    Array.init (board_w*board_h) (fun i -> (i mod board_w, i / board_w)) in
  let pos = list_randomise (Array.to_list pos) in
  let rec aux pos symbols = match pos, symbols with
    | (x1, y1) :: (x2, y2) :: pos, symbol :: symbols ->
        board.(x1).(y1) <- Some symbol;
        board.(x2).(y2) <- Some symbol;
        aux pos symbols
    | _ -> () in
  aux pos symbols;
  board

let scene = ref (new scene
                   ~fills:base_fills
                   ~styles:base_styles
                   ~geometries:Store.empty (make_group []))

let geometry_of_card =
  let segs =
    [line_to 0. 0.; line_to 1. 0.; line_to 1. 1.; line_to 0. 1.] in
  let contour = Contour.make (Contour.Closed, segs) in
  let geo = ContourGeometry.make [contour] in
  let rgeo, scene' = !scene#add_geometry geo in
  scene := scene';
  rgeo

(* Stroke the outside of the card with a thick line *)
let stroke =
  let stroke = Style.make_stroke 0.03 in
  let stroke, scene' = !scene#add_style stroke in
  scene := scene';
  stroke

(* Graph of an overturned card *)
let graph_of_overturned = make_contour_object [white, odd] geometry_of_card

(* Graph of a facing card *)
let graph_of_facing symbol =
  let rgeo, scene' = !scene#get_glyph "cmr10.ttf" symbol in
  scene := scene';
  let glyph = make_contour_object [white, stroke; green, odd] rgeo in
  let glyph = scale_graph 0.05 glyph in
  let glyph = translate_graph 0.2 0.2 glyph in
  make_group [
    make_contour_object [black, odd; white, stroke] geometry_of_card;
    glyph
  ]

(* Generate a Smoke scene graph from a board *)
let graph_of_board pos board =
  let graphs = ref [] in
  for x = 0 to board_w - 1 do
    let graphs2 = ref [] in
    for y = 0 to board_h - 1 do
      let symbol = board.(x).(y) in
      let graph = match pos, symbol with
        | Some (pos, _), Some symbol when (x, y) = pos ->
            graph_of_facing symbol
        | Some (_, Some pos), Some symbol when (x, y) = pos ->
            graph_of_facing symbol
        | _, None -> make_group []
        | _ -> graph_of_overturned in
      let graph = translate_graph (1.2 *. float x) (1.2 *. float y) graph in
      graphs2 := graph :: !graphs2;
    done;
    graphs := make_group (List.rev !graphs2) :: !graphs;
  done;
  make_group (List.rev !graphs)

let board = new_board ()
let selection_time = ref 0.
let selection = ref None
let viewport = ref None
let width = ref 512 and height = ref 512
let delta = ref (make_vec 1. 1.)

(* Use Smoke to display the board. *)
let display () =
  GlClear.color (0.3, 0., 0.);
  GlClear.clear [`color];

  let scene = !scene#replace_root (graph_of_board !selection board) in

  let d, vp = Smoke.set_projection scene#get_bound !width !height in
  delta := d;
  viewport := vp;
  let renderdata = RenderData.make d vp in

  GlMat.load_identity ();
  scene#render renderdata;

  Gl.flush ();
  Glut.swapBuffers ()

(* Quit if "escape" is pressed *)
let keyboard ~key ~x ~y = match char_of_int key with
  | '\027' when Glut.getModifiers() = 0 -> exit 0
  | _ -> ()

(* Reshape the window *)
let reshape ~w ~h =
  GlDraw.viewport 0 0 w h;
  let d, vp = Smoke.set_projection !viewport w h in
  delta := d;
  viewport := vp;
  width := w;
  height := h

(* Turn cards back over after 1 sec *)
let idle () =
  Glut.postRedisplay ();
  match !selection with
  | Some (_, Some _) when time() > !selection_time +. 1. -> selection :=
None
  | _ -> ()

(* Select a card *)
let select x y = match !selection with
  | Some (_, Some _) | None ->
      (* New selection *)
      selection := Some ((x, y), None)
  | Some ((x2, y2), None) when x<>x2 || y<>y2 ->
      if board.(x).(y) = board.(x2).(y2) then begin
        (* Remove duplicate *)
        board.(x).(y) <- None;
        board.(x2).(y2) <- None;
        selection := None;
      end else begin
        (* Display wrong answer *)
        selection_time := time();
        selection := Some ((x, y), Some (x2, y2))
      end
  | _ -> ()

(* Mouse click callback *)
let mouse ~button ~state ~x ~y =
  let r = make_vec ((float x) /. (float !width))
    (1. -. (float y) /. (float !height)) in
  let r = match !viewport with
      None -> make_vec 0. 0.
    | Some (l, u) ->
        let e = u -| l in
        l +| (make_vec (r.x *. e.x) (r.y *. e.y)) in
  let scene = !scene#replace_root (graph_of_board !selection board) in
  if button=Glut.LEFT_BUTTON && state=Glut.DOWN then begin
    let old_viewport = !viewport in
    let d = 4. *| !delta in
    let viewport = Some (r -| d, r +| d) in
    let delta, viewport = set_projection viewport !width !height in
    let data = RenderData.make delta viewport in
    begin match pick (fun () -> scene#render data) with
    | Some (x :: y :: _) -> select (x-1) (y-1)
    | _ -> ()
    end;
    let delta, viewport = set_projection old_viewport !width !height in
    Glut.postRedisplay ();
  end

(* Main program *)
let () =
  Glut.initWindowSize ~w:!width ~h:!height;
  let argv = Glut.init Sys.argv in
  Glut.initDisplayMode ~double_buffer:true ~depth:true ();
  Glut.initWindowSize ~w:!width ~h:!height;
  ignore(Glut.createWindow ~title:"Concentration Game");

  Glut.reshapeFunc reshape;
  Glut.displayFunc display;
  Glut.idleFunc (Some idle);
  Glut.keyboardFunc keyboard;
  Glut.mouseFunc mouse;

  Glut.mainLoop ()

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com

From: Julian Squires
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <femOe.78314$Ph4.2464397@ursa-nb00s0.nbnet.nb.ca>
On 2005-08-22, Jon Harrop <······@jdh30.plus.com> wrote:
> I have implemented a completely different version of the same game in OCaml
> for comparison. It took me 2hrs 20mins to complete (without proper testing)
> and is 164LOC.

It's important to note that your version is less flexible than the
original Lisp version.  (Though I think a similarly featureful
implementation in OCaml should be possible in about the same size at the
Lisp version -- I'd rather see something that used bignums, macros, and
restarts and the comparative OCaml implementation.)

Cheers.

-- 
Julian Squires
From: ···········@gmail.com
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1124748114.015545.17860@g49g2000cwa.googlegroups.com>
actually, the lisp version is 159 non-comment non-blank lines (counting
docstrings as comments), so the ocaml one has -5 lines of breathing
room to get the remaining functionality.
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <430a54fc$0$97131$ed2619ec@ptn-nntp-reader03.plus.net>
···········@gmail.com wrote:
> actually, the lisp version is 159 non-comment non-blank lines (counting
> docstrings as comments), so the ocaml one has -5 lines of breathing
> room to get the remaining functionality.

Damn. How long was the C again? ;-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: ···········@gmail.com
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1124771117.343247.108890@o13g2000cwo.googlegroups.com>
I stopped counting when a fixnum overflowed.

It is interesting that ocaml is so close, though.  It, haskell, and
smalltalk have been on my list of languages to learn for some time.
You may have answered this somewhere-how did you get to ocaml?  Every
person I have ever met who even knows what it is is either a comp sci
PhD, a language enthusiast, or a lisper.
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <430afbe6$0$17470$ed2e19e4@ptn-nntp-reader04.plus.net>
···········@gmail.com wrote:
> I stopped counting when a fixnum overflowed.
> 
> It is interesting that ocaml is so close, though.  It, haskell, and
> smalltalk have been on my list of languages to learn for some time.
> You may have answered this somewhere-how did you get to ocaml?  Every
> person I have ever met who even knows what it is is either a comp sci
> PhD, a language enthusiast, or a lisper.

Although I read nat-sci at Cambridge, I was friends with many comp-scis.
Several of them used to ramble about OCaml and my lab mat, a physicist, was
the first person I knew to pick it up and apply it to scientific computing.
He found OCaml to be ideal for many tasks and, when it wasn't fast enough,
he found that working OCaml programs were easier to port to C than writing
from scratch in C.

I really picked OCaml up between handing my PhD in and being viva'd. I had
four months and I successfully ported Smoke (my vector graphics library)
from C++ to OCaml. Here's the old C++ one on my academic site:

  http://www.chem.pwf.cam.ac.uk/~jdh30/programming/opengl/smoke/

I was so impressed with the result that I continued to develop the software,
wrote a book on OCaml, involved OCaml in our company and now we're
developing much more serious software based upon those results. I don't
really use C/C++ at all any more, just OCaml and Mathematica.

If you want to get into OCaml, particularly if you're a scientist, then the
first chapter of my book is freely available:

  http://www.ffconsultancy.com/products/ocaml_for_scientists/

I keen to learn other languages and, in particular, I'd like to gain a
better understanding of what Lisp can do that OCaml can't, and vice-versa.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <4309f348$0$97131$ed2619ec@ptn-nntp-reader03.plus.net>
Julian Squires wrote:
> It's important to note that your version is less flexible than the
> original Lisp version.

Can you be more specific? I'm sure that sword cuts both ways...

> (Though I think a similarly featureful 
> implementation in OCaml should be possible in about the same size at the
> Lisp version -- I'd rather see something that used bignums, macros, and
> restarts and the comparative OCaml implementation.)

Yes. I'd be very interested to see useful Lisp programs that are difficult
to write in the other languages that I know. Bignums would not be a good
example but macros and restarts might be.

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: André Thieme
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <dee5rs$qv9$1@ulric.tng.de>
Jon Harrop schrieb:
> Julian Squires wrote:
> 
>>It's important to note that your version is less flexible than the
>>original Lisp version.
> 
> 
> Can you be more specific? I'm sure that sword cuts both ways...
> 
> 
>>(Though I think a similarly featureful 
>>implementation in OCaml should be possible in about the same size at the
>>Lisp version -- I'd rather see something that used bignums, macros, and
>>restarts and the comparative OCaml implementation.)
> 
> 
> Yes. I'd be very interested to see useful Lisp programs that are difficult
> to write in the other languages that I know. Bignums would not be a good
> example but macros and restarts might be.
> 

OCaml is a nice language, it offers many of the features of Lisp. This 
means you should look for programs that use techniques that can't 
trivially be copied in OCaml or your other languages.
I don't know how much object oriented programming is supported in ML. 
Does it have a Meta Object Protocol?
How easy can you apply design patterns in ML or OCaml? Is there the need 
for the visitor pattern when you just want full method dispatch?
If it only follows the "send a message paradigm", how easy is it to 
extend ML/OCaml so that it supports multimethods?
How many lines of code do you need to teach ML macros with the power of 
Lisp? Is it easy to implement unwind-protect in ML?
Does OCaml offer something similar like Lisps condition system? How well 
do your languages scale for bigger projects? When I did OCaml I had so 
many problems with type inference that it was not possible to do bigger 
programs, while short hacks were very nice.


Andr�
-- 
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <43133f7d$0$17464$ed2e19e4@ptn-nntp-reader04.plus.net>
Andr� Thieme wrote:
> Jon Harrop schrieb:
>> Yes. I'd be very interested to see useful Lisp programs that are
>> difficult to write in the other languages that I know. Bignums would not
>> be a good example but macros and restarts might be.
> 
> OCaml is a nice language, it offers many of the features of Lisp. This
> means you should look for programs that use techniques that can't
> trivially be copied in OCaml or your other languages.
> I don't know how much object oriented programming is supported in ML.
> Does it have a Meta Object Protocol?

OCaml has some support for OO but I have made very little use of it.

> How easy can you apply design patterns in ML or OCaml?

You can but you wouldn't (AFAIK) because there are better alternatives in
OCaml (and probably Lisp too).

> How many lines of code do you need to teach ML macros with the power of
> Lisp?

I think that is a theoretical impossibility. What you can do is implement a
Lisp interpreter/compiler in OCaml. That may be interesting (and we've
discussed embedding Lisp in OCaml and OCaml in Lisp) but it does not make
for an unbiased comparison.

> Is it easy to implement unwind-protect in ML?

I do not believe so. Can you give an example of a useful program that uses
this Lisp facility?

> Does OCaml offer something similar like Lisps condition system?

Is that like guarded pattern matching without the patterns?

> How well 
> do your languages scale for bigger projects? When I did OCaml I had so
> many problems with type inference that it was not possible to do bigger
> programs, while short hacks were very nice.

We're finding it easy and we've developed projects up to ~25kLOC. It is
certainly much easier than with C++ but I have no idea how OCaml compares
with Lisp.

-- 
Dr Jon D. Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com
From: Jens Axel Søgaard
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <431343c6$0$25985$edfadb0f@dread12.news.tele.dk>
Jon Harrop wrote:

>>Is it easy to implement unwind-protect in ML?

> I do not believe so. Can you give an example of a useful program that uses
> this Lisp facility?

If the ML implementation in question has callCC it ought to be 
*possible* - although calling it *easy* might be a stretch.

   Daniel P. Friedman and Christopher T. Haynes. "Constraining Control".
   Proceedings of the Twelfth Annual Symposium on Principles of
   Programming Languages. January 1985.

See also the short (cough) thread "UNWIND-PROTECT in Scheme" from 2003
in this news group.

-- 
Jens Axel S�gaard
From: Neelakantan Krishnaswami
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <slrndh6v30.acc.neelk@gs3106.sp.cs.cmu.edu>
In article <·························@ptn-nntp-reader04.plus.net>, Jon Harrop
wrote:
>> Is it easy to implement unwind-protect in ML?
> 
> I do not believe so. Can you give an example of a useful program
> that uses this Lisp facility?

Actually, it's a very simple hof, and rather handy.

let unwind_protect body cleanup =
  try body() with e -> (cleanup(); raise e)

-- 
Neel Krishnaswami
·····@cs.cmu.edu
From: O-MY-GLIFE
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1125400323.647497.320510@o13g2000cwo.googlegroups.com>
Neelakantan Krishnaswami wrote:
> In article <·························@ptn-nntp-reader04.plus.net>, Jon Harrop
> wrote:
> >> Is it easy to implement unwind-protect in ML?
> >
> > I do not believe so. Can you give an example of a useful program
> > that uses this Lisp facility?
>
> Actually, it's a very simple hof, and rather handy.
>
> let unwind_protect body cleanup =
>   try body() with e -> (cleanup(); raise e)

Shouldn't the (Ocaml??) unwind-protect be rather:

 let unwind_protect body cleanup =
   try 
     body();
     cleanup()
   with e -> cleanup()

???
From: ·········@gmail.com
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1125404811.257219.23180@g14g2000cwa.googlegroups.com>
O-MY-GLIFE wrote:
> Shouldn't the (Ocaml??) unwind-protect be rather:
>
>  let unwind_protect body cleanup =
>    try
>      body();
>      cleanup()
>    with e -> cleanup()
>
> ???

And what if cleanup() throws an exception? You will then run parts of
cleanup() twice.

Regards, Tommy
From: M Jared Finder
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <TO6dnQ-ekqCjHoneRVn-sQ@speakeasy.net>
·········@gmail.com wrote:
> O-MY-GLIFE wrote:
> 
>>Shouldn't the (Ocaml??) unwind-protect be rather:
>>
>> let unwind_protect body cleanup =
>>   try
>>     body();
>>     cleanup()
>>   with e -> cleanup()
>>
>>???
> 
> And what if cleanup() throws an exception? You will then run parts of
> cleanup() twice.

Is that really much worse than not running parts of cleanup()?  If 
cleaning up causes an error, all hope is already lost.

   -- MJF
From: ·········@gmail.com
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1125468006.775595.67990@g44g2000cwa.googlegroups.com>
The cleanup is run for its side-effects, and they will occur twice and
perhaps cause a different error the second time with the effect of
hiding the real error. It will be much harder to track down the real
cause watching the stacktrace of the second error.

Doesn't O'Caml have a finally clause?

Regards, Tommy
From: Kent M Pitman
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <u7je3efcz.fsf@nhplace.com>
··········@gmail.com" <·········@gmail.com> writes:

> O-MY-GLIFE wrote:
> > Shouldn't the (Ocaml??) unwind-protect be rather:
> >
> >  let unwind_protect body cleanup =
> >    try
> >      body();
> >      cleanup()
> >    with e -> cleanup()
> >
> > ???
> 
> And what if cleanup() throws an exception? You will then run parts of
> cleanup() twice.

Is there no non-local exit primitive here? No block/return, no catch/throw,
no Scheme-style continuation?  If there is, which of these clauses handles
that?
From: O-MY-GLIFE
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <1125408931.289610.297650@z14g2000cwz.googlegroups.com>
Kent M Pitman wrote:
> ··········@gmail.com" <·········@gmail.com> writes:
>
> > O-MY-GLIFE wrote:
> > > Shouldn't the (Ocaml??) unwind-protect be rather:
> > >
> > >  let unwind_protect body cleanup =
> > >    try
> > >      body();
> > >      cleanup()
> > >    with e -> cleanup()
> > >
> > > ???
> >
> > And what if cleanup() throws an exception? You will then run parts of
> > cleanup() twice.
>
> Is there no non-local exit primitive here? No block/return, no catch/throw,
> no Scheme-style continuation?  If there is, which of these clauses handles
> that?

The analog of
  catch/throw
is
  try .. with/raise ..

My concern with the first variant was that if no exception is risen the
cleanup form will not be run. And I guess there no need to raise the
exception again. Except that exceptions are cheap in Ocaml and are
often used to indicate failure. EOF, for example.

As for "what if cleanup() throws an exception?", my first thought was
to write it like this

  exception Spurious;

  let unwind_protect body cleanup =
    try
      body();
      raise Spurious;
    with e -> cleanup()

but it looks rather contorted.

Now I'm leaving the field to Ocamlers.
From: Benedikt Rosenau
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <dqm9or$d9k$1@nessy.newsmonster.de>
O-MY-GLIFE <·······@seznam.cz> wrote:

[...]

> Now I'm leaving the field to Ocamlers.

Here is some code from Markus Mottl:

let catch_finally ~f x ~exc_handler ~finally =
  try
    let res = f x in
    let _ = finally x in
    res
  with exc1 ->
    let res =
      try exc_handler exc1
      with exc2 ->
        let _ = finally x in
        raise exc2 in
    let _ = finally x in
    res

val catch_finally :
  f:('a -> 'b) -> 'a -> exc_handler:(exn -> 'b) -> finally:('a -> 'c) -> 'b =
  <fun>


However, it assumes that finally will not throw an exception. Anyway, this
might be ontopic somewhere else.
   Benedikt
From: Neelakantan Krishnaswami
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <slrndh8snu.c9k.neelk@gs3106.sp.cs.cmu.edu>
In article <·············@nhplace.com>, Kent M Pitman wrote:
> 
> Is there no non-local exit primitive here? No block/return, no
> catch/throw, no Scheme-style continuation?  If there is, which of
> these clauses handles that?

No, there are no nonlocal exits at all except for exceptions. So
the only control effect you have to protect against is an exceptional
exit. 

The original respondent was correct, though; my code doesn't work
right because it doesn't call cleanup when the body ran without 
failure. To behave correctly, you'd actually need to do something
like:

let finally body cleanup = 
  let result = try body() with e -> (cleanup(); raise e) in
  (cleanup(); 
   result)

Someone asked what would happen if cleanup threw an exception. This
code would raise the cleanup exception. Does unwind-protect do 
otherwise? (That would seem very strange to me.)

-- 
Neel Krishnaswami
·····@cs.cmu.edu
From: André Thieme
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <df2uu6$14o$1@ulric.tng.de>
Jon Harrop schrieb:
> Andr� Thieme wrote:
> 
>>How easy can you apply design patterns in ML or OCaml?
> 
> 
> You can but you wouldn't (AFAIK) because there are better alternatives in
> OCaml (and probably Lisp too).

That is only to some part correct.
Regarding the well known design patterns from the GoF: yes, Lisp and 
OCaml offer both much better mechanisms to express most of these design 
patterns. However, every language has its own patterns. These might be 
different ones described in the original patterns book.
There is a good bunch of Lispers who don't know too much about design 
patterns and think they are not so important stuff.

In Lisp you can use multimethods to do full method dispatch. In most 
other languages one uses the visitor pattern to get full dispatch. 
However, the visitor pattern can do more than full method dispatch. And 
if you need that you will have to know about it to do it in Lisp.

Noone has taken so far some time to describe patterns in Lisp. Perhaps 
there are not many that we humans can find with our limited minds.


>>Is it easy to implement unwind-protect in ML?
> 
> I do not believe so. Can you give an example of a useful program that uses
> this Lisp facility?

Others have shown that it is very easy.
Nearly every serious application will use unwind-protect.


Andr�
-- 
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <4315357e$0$1312$ed2619ec@ptn-nntp-reader02.plus.net>
Andr� Thieme wrote:
> Noone has taken so far some time to describe patterns in Lisp. Perhaps
> there are not many that we humans can find with our limited minds.

Yes. I think that is true of most FPLs.

>>>Is it easy to implement unwind-protect in ML?
>> 
>> I do not believe so. Can you give an example of a useful program that
>> uses this Lisp facility?
> 
> Others have shown that it is very easy.
> Nearly every serious application will use unwind-protect.

Yes. I was thinking of something else (restarts?).

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Wade Humeniuk
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <ABmOe.193600$9A2.141747@edtnps89>
Jon Harrop wrote:
> Wade Humeniuk wrote:
> 
>>Here is an example
>>of a program in Lisp which is non-trivial (no macros, well not
>>quite true... capi:define-interface is one such builtin LispWorks
>>macro, oh ... and defclass and capi:with-geometry, etc etc.).
> 
> 
> I have implemented a completely different version of the same game in OCaml
> for comparison. It took me 2hrs 20mins to complete (without proper testing)
> and is 164LOC.
> 

See, that wasn't so hard, was it?  As for speed of development Gerry Quinn
asserted that the MSVC C++ version took two hours (but he only had one
size board and fixed number of picks).

> I used our in-house vector graphics library "Smoke" and Glut instead of
> Motif. I believe the program complexity is roughly the same as yours so it
> is still useful for comparison but Smoke allowed me to do some interesting
> things:
> 
> 1. Hardware accelerated rendering via OpenGL.
> 2. 2D vector graphics.
> 3. Embedded Computer Modern fonts.
> 4. OpenGL picking.
> 

I certainly agree that using a visually stimulating OpenGL interface
would be better.  Perhaps Kenny would code up a cells/opengl version (he
has created something that has functionality of your smoke).

Is it possible for you to deliver an executable that I can just run? If you
statically link in smoke could you deliver it?  Just tell me what
libraries I would need (I assume Glut)


Wade
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <430a1a74$0$97131$ed2619ec@ptn-nntp-reader03.plus.net>
Wade Humeniuk wrote:
> I certainly agree that using a visually stimulating OpenGL interface
> would be better.  Perhaps Kenny would code up a cells/opengl version (he
> has created something that has functionality of your smoke).

Sounds like a challenge. :-)

> Is it possible for you to deliver an executable that I can just run? If
> you
> statically link in smoke could you deliver it?  Just tell me what
> libraries I would need (I assume Glut)

Sure. You'll need OpenGL, GLU, glut and probably some other stuff that I
can't think of. :-)

Here's a tarball of the executable:

  http://www.ffconsultancy.com/free/concentration/code/concentration.tar.bz2

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: André Thieme
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <dee2p1$oiv$2@ulric.tng.de>
Jon Harrop schrieb:
> Wade Humeniuk wrote:
> 
>>I certainly agree that using a visually stimulating OpenGL interface
>>would be better.  Perhaps Kenny would code up a cells/opengl version (he
>>has created something that has functionality of your smoke).
> 
> 
> Sounds like a challenge. :-)
> 
> 
>>Is it possible for you to deliver an executable that I can just run? If
>>you
>>statically link in smoke could you deliver it?  Just tell me what
>>libraries I would need (I assume Glut)
> 
> 
> Sure. You'll need OpenGL, GLU, glut and probably some other stuff that I
> can't think of. :-)
> 
> Here's a tarball of the executable:
> 
>   http://www.ffconsultancy.com/free/concentration/code/concentration.tar.bz2

Do you also have an executable for windows? ;-)
I am getting a new computer tomorrow and have no Linux available atm.


Andr�
-- 
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <43133fae$0$17464$ed2e19e4@ptn-nntp-reader04.plus.net>
Andr� Thieme wrote:
> Do you also have an executable for windows? ;-)
> I am getting a new computer tomorrow and have no Linux available atm.

Sorry, no. I ought to get a Windows development environment up and
running...

-- 
Dr Jon D. Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com
From: Ivan Boldyrev
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <cejqt2-5s4.ln1@ibhome.cgitftp.uiggm.nsc.ru>
On 9210 day of my life Jon Harrop wrote:
>> Is it possible for you to deliver an executable that I can just
>> run? If you statically link in smoke could you deliver it?  Just
>> tell me what libraries I would need (I assume Glut)
>
> Sure. You'll need OpenGL, GLU, glut and probably some other stuff that I
> can't think of. :-)

Did you ever heard of ldd?

$ ldd /path-to/file
        linux-gate.so.1 =>  (0xffffe000)
        libcap.so.1 => /lib/libcap.so.1 (0xb7fce000)
        libz.so.1 => /lib/libz.so.1 (0xb7fbb000)
        libbz2.so.1 => /lib/libbz2.so.1 (0xb7fac000)
        libreadline.so.5 => /lib/libreadline.so.5 (0xb7f7f000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7f7b000)
        libcurl.so.3 => /usr/lib/libcurl.so.3 (0xb7f4a000)
        libidn.so.11 => /usr/lib/libidn.so.11 (0xb7f1a000)
        libssl.so.0.9.7 => /usr/lib/libssl.so.0.9.7 (0xb7ee8000)
        libcrypto.so.0.9.7 => /usr/lib/libcrypto.so.0.9.7 (0xb7de8000)
        libc.so.6 => /lib/libc.so.6 (0xb7ccd000)
        libncurses.so.5 => /lib/libncurses.so.5 (0xb7c8c000)
        /lib/ld-linux.so.2 (0xb7feb000)
        libgpm.so.1 => /lib/libgpm.so.1 (0xb7c86000)

-- 
Ivan Boldyrev

                  Sorry my terrible English, my native language is Lisp!
From: Wade Humeniuk
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <kzGOe.212064$tt5.83478@edtnps90>
Jon Harrop wrote:

> 
> Sure. You'll need OpenGL, GLU, glut and probably some other stuff that I
> can't think of. :-)
> 

I thought it would be easier to get those libraries loaded into my
Linux compatibility directories.  However my FreeBSD system is behind
in its releases and the bottom line is that it does not seem to be
simple to find the proper libraries anymore.  On top of there is the
unknown issues of running it headless (I use a Windows 2000 Cygwin
installation to run an X server).

Perhaps I will spring $65US for a used PC to run Linux, probably
should get one anyways.

Wade
From: Jon Harrop
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <430b59c5$0$1286$ed2619ec@ptn-nntp-reader02.plus.net>
Wade Humeniuk wrote:
> Perhaps I will spring $65US for a used PC to run Linux, probably
> should get one anyways.

If you just download and burn a Knoppix CD and reboot into Linux from the
CD, then you should be able to download and run my program from there. And
its free! :-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy
http://www.ffconsultancy.com
From: Wade Humeniuk
Subject: Re: Concentration in OCaml
Date: 
Message-ID: <Z7POe.235627$on1.102846@clgrps13>
Jon Harrop wrote:
> Wade Humeniuk wrote:
> 
>>Perhaps I will spring $65US for a used PC to run Linux, probably
>>should get one anyways.
> 
> 
> If you just download and burn a Knoppix CD and reboot into Linux from the
> CD, then you should be able to download and run my program from there. And
> its free! :-)
> 

Good idea, Just happened to have Ubuntu v5.04 LiveCD sitting on
my desk.  First thing about your app...  In needs some colour!

Wade