caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Newbie q. about Arg parsing
@ 2002-08-17  9:56 Gerald heinig
  2002-08-17 15:32 ` Christophe Delage
  2002-08-19 16:42 ` Florian Hars
  0 siblings, 2 replies; 3+ messages in thread
From: Gerald heinig @ 2002-08-17  9:56 UTC (permalink / raw)
  To: caml-list

Hi all,

I'm new to functional programming and Ocaml, but I'm very interested in
becoming proficient in the language. In particular, I'm very impressed
with the brevity of the programs, including my first one, with which I'm
unfortunately having some problems (hence the question).

A bit of background: although I need this program (the one I'm writing),
I'm also treating its creation as an academic exercise by attempting to
stick to a purely functional style. There's no point in learning Ocaml
if I just overwrite values left, right and centre. If I did that, I
might just as well use C.

I'm trying to parse the command line using the module Arg. This works
fine for one option, or the default argument, since I call the same
function from both. What I'd like to do, however, is to check whether
the "-s" option is given, and if it is, pass the result to the function
doing the work. In other words,

command <filename>

parses filename from line 0, and

command -s 200 <filename>

parses filename from line 200.

Here's my program. Before you mention that "while" has side-effects - I
know, but I have to start somewhere. I'll change that later, when I'm
not quite so clueless.
How do I tell fnamefun to start at line <whatever>? If I just define it
as

let fnamefun = fun x l -> ....

the compiler will complain about a type mismatch. I thought of maybe
defining a tuple of (filename,startline) and passing that to fnamefun,
but that's a no-go because Arg.String expects a string, not a tuple.
Can you use Arg to parse the command line in purely functional style? If
yes, how?

Thanks very much for your help

Gerald

ps. Flame all you like about the layout style, but please tell me how to
do it The Right Way (tm)



let fnamefun = fun x ->
   try
      let file = open_in x in
      let lexline = Lexing.from_channel file in
      while true do
         let result = Parser.main Lexer.token lexline in
            Printf.printf "%s\n" result; flush stdout
      done
   with
      Sys_error e -> Printf.printf "%s\n" e
      | Not_found -> exit 1
      | Lexer.Eof -> exit 0
      | Parsing.Parse_error -> Printf.printf "%s\n" "parse error"

(* intarg does not do anything interesting at the moment *)

let intarg = fun i -> Printf.printf "%d"

let main = Arg.parse [("-s",Arg.Int intarg, "linenumber");
                      ("-",Arg.Rest fnamefun, "filename")] fnamefun
"Usage:"

-------------------
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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] Newbie q. about Arg parsing
  2002-08-17  9:56 [Caml-list] Newbie q. about Arg parsing Gerald heinig
@ 2002-08-17 15:32 ` Christophe Delage
  2002-08-19 16:42 ` Florian Hars
  1 sibling, 0 replies; 3+ messages in thread
From: Christophe Delage @ 2002-08-17 15:32 UTC (permalink / raw)
  To: caml-list

On Sat, 17 Aug 2002, Gerald heinig wrote:

> Hi all,
Hi,

> Can you use Arg to parse the command line in purely functional style? If
> yes, how?

Well, Arg.parse expects functions of type string -> unit, int -> unit,
etc. and calls theses functions when it finds the corresponding argument.
This is a purely imperative behaviour, I am afraid that doing something
usefull with Arg.parse leads to some side effects.

The simplest idea I see is to keep a reference to the integer you
want to pass to fnamefun, and setting it when you see a "-s":

let main =
  let lineno = ref 0 in (* or any other default value *)
  let call_fname filename = (* call fnamefun with the right args *)
    fnamefun filename !lineno in

    Arg.parse
      [ "-s", (fun i -> intarg := i), "linenumber";
        "-", call_fname, "filename" ]
      call_fname
      "usage"

(assuming that fnamefun takes two arguments : the filename and the lineno)

Hope this helps,

Christophe

-------------------
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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Caml-list] Newbie q. about Arg parsing
  2002-08-17  9:56 [Caml-list] Newbie q. about Arg parsing Gerald heinig
  2002-08-17 15:32 ` Christophe Delage
@ 2002-08-19 16:42 ` Florian Hars
  1 sibling, 0 replies; 3+ messages in thread
From: Florian Hars @ 2002-08-19 16:42 UTC (permalink / raw)
  To: Gerald heinig; +Cc: caml-list

Gerald heinig wrote:
> let intarg = fun i -> Printf.printf "%d"

This function takes an arbitrary value "i", ignores it and then returns

   Printf.printf "%d"

which has type int -> unit, so your intarg has type

   'a -> int -> unit

which is probably not what you wanted (and not wat Arg.Int expects). Try

   let intarg = Printf.printf "%d"

or

   let intarg i = Printf.printf "%d" i

instead (the latter for should optimize better, but if you parse command line 
arguments in an inner loop you should refactor your program anyway).

Yours, Florian.

-------------------
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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2002-08-19 16:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-08-17  9:56 [Caml-list] Newbie q. about Arg parsing Gerald heinig
2002-08-17 15:32 ` Christophe Delage
2002-08-19 16:42 ` Florian Hars

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).