Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Again on pattern matching and strings
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Alessandro Baretta <alex@b...>
Subject: [Caml-list] Again on pattern matching and strings
Gentlemen,

Let me discuss one further aspect of pattern matching, which 
relates to matching strings.

I am writing an Epson ESC/P printer driver from a text 
formatter I wrote. I have come across the need to scan 
buffers of printer commands to post process them before 
actually sending them to the printer. Since printer commands 
tend to get rather complex to write I have thought that a 
very natural way to make my program more readable would be 
to define identifiers to stand for such commands. Here's an 
example.

let printer_set_unit = "\027(U\001\000\005"

This commands sets the unit of measurement for subsequent 
commands to 5/3600 in.

I also have a scanning function which returns a string 
option, which either contains None, if no printer command is 
recognized, or Some(s) where an ESC/P command is recognized.

I want to use pattern matching on the result of my string 
scanning to determine what to do depending on the command 
identified by the scanner. Intuitively, I wrote the 
following, which is obviously wrong.

match <scanning function> with
| Some ( printer_set_unit ) -> ...
| Some ( printer_reset ) -> ...
| Some ( printer_formfeed )   -> ...
...
| Some (_) -> assert false
| None -> ()

Naturally, this does not work, because instead of evaluating 
  printer_set_unit, printer_set_pagesize and 
printer_formfeed and defining patterns based on these, the 
compilers redefines the identifiers based on the matched 
string in the local scope. But this leaves me no alternative 
to writing
match ... with
| Some ( "\027(U\001\000\005" ) -> ...
| Some ( "\027@" ) -> ...
| Some ( "\012" ) -> ...

And so on. This is completely unreadable. I think this 
problem requires a solution like C++ const variables: values 
which the compiler considers compile time constants and 
directly substitutes into the code in place of the 
identifier name. Now, "const" is rather meaningless in a 
functional language, so I suggest "alias" as a better 
alternative. For example

alias printer_set_unit = "\027(U\001\000\005"

whereby such an identifier cannot be hidden by a new let 
binding (compile-time error) and is considered a constant in 
patterns.

If the compiler allowed the aliasing of constant expressions 
with an identifier, the above pattern matching would make 
sense. Of course, such a technique also applies to other 
cases as well, besides programming Epson printer drivers. In 
general, any pattern matching where complex constant 
patterns are used would benefit from this feature, for the 
programmer would be able to write a better readable code.

I write this message because I would like to know what kind 
of complications would need to be added to the compiler to 
make the above trick work.

Alex

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners