Looking for an elegant coding idiom.

John Gerard Malecki (johnm@vlibs.com)
Wed, 2 Aug 95 16:37 PDT

Message-Id: <m0sdnMC-00026dC@owl.uucp>
Date: Wed, 2 Aug 95 16:37 PDT
From: johnm@vlibs.com (John Gerard Malecki)
To: caml-list@margaux.inria.fr
Subject: Looking for an elegant coding idiom.

Hi,

CAML is a very elegant language and I am curious to hear of any
elegant coding idioms. I am especially curious to hear of any elegant
solutions to deal with some nuisance code of mine. I once solved this
problem in C. This may be holding me back from an elegant CAML
solution. It may be that there is no "best" style or solution but any
suggestions you have are appreciated.

I am placing rectangular objects in the plane. There are 8 orthogonal
orientations and they are:

>type orient =
> R0
> | R90
> | R180
> | R270
> | MY (* mirrored about the y axis *)
> | MX
> | MXR90 (* mirrored about the x axis and then rotated *)
> | MYR90
> ;;

Given an orientation it is useful to be able to compose it with
another orientation. A transliteration from C looks something like

>let rorient = [|
> [| R0 ; R90 ; R180 ; R270 ; MY ; MX ; MXR90; MYR90 |];
> [| R90 ; R180 ; R270 ; R0 ; MXR90; MYR90; MX ; MY |];
> [| R180 ; R270 ; R0 ; R90 ; MX ; MY ; MYR90; MXR90 |];
> [| R270 ; R0 ; R90 ; R180 ; MYR90; MXR90; MY ; MX |];
> [| MY ; MYR90; MX ; MXR90; R0 ; R180 ; R270 ; R90 |];
> [| MX ; MXR90; MY ; MYR90; R180 ; R0 ; R90 ; R270 |];
> [| MXR90; MY ; MYR90; MX ; R90 ; R270 ; R0 ; R180 |];
> [| MYR90; MX ; MXR90; MY ; R270 ; R90 ; R180 ; R0 |]
> |];;

Since I used a vector I now need to map from a orient to an int.
Writing this code is a nuisance. Reading this code is difficult. For
example,

>let int_from_orient = function
> R0 -> 0
>| R90 -> 1
>| R180 -> 2
>| R270 -> 3
>| MY -> 4
>| MX -> 5
>| MXR90 -> 6
>| MYR90 -> 7
>;;

>let reorient current new =
> rorient.(int_from_orient current).(int_from_orient new)
> ;;

This int_from_orient stuff is a minor mess but it works. How about

>let rorient = function
> R0 -> function R0 -> R0 | R90 -> R90 | ...
> | R90 -> function R0 -> ...
> ;;

Now we have a real coding mess. If we look in cl/examples/docteur we
see something like

>let rorient = [
> (R0, [ (R0,R0); (R90,R90); ...
> (R90, [ (R0,R90); ...
>
and hence

>let reorient current new = assq new (assq current rorient)
>;;

This looks okay but i'm not sure how efficient it is compared to a
vector based solution. What other techniques are reasonable? Is it
possible to access a record with a non-constant label? For example

?let rorient = {R0 = {R0=R0; R90=R90;...
? R90 = {R0=R90; R90=R180;...
?...
?let reorient current new = rorient.current.new
?;;

Besides orientations, I have other data types like which edges (north,
south, east, west), directions (positive, negative), axes (x, y) etc.
I really would like to use user-defined types to take advantage of
CAML's strong type-checking facilities.

Can anyone share their experience and coding idioms to solving these
kind of combinatoric problems? Consistent coding style is more
readable. If anyone has any examples of good coding idioms I'd be
happy to hear about them too.

-- 
John Gerard Malecki;  johnm@vlibs.com;  voice 408.450.5302;  fax 408.970.9920
VLSI Libraries Incorporated;  3135 Kifer Road;   Santa Clara, CA;  95051; USA