caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Unix-Filekind => codexample with questions
@ 2002-04-21 20:50 Oliver Bandel
  2002-04-21 21:04 ` Remi VANICAT
  2002-04-21 21:17 ` John Prevost
  0 siblings, 2 replies; 5+ messages in thread
From: Oliver Bandel @ 2002-04-21 20:50 UTC (permalink / raw)
  To: caml-list

Hello,

I need a function, which tells me if a file is
a regular file or not.

Please look at my code-example:

let is_regularfile name =
      let filekind name = let tmp = Unix.stat name in tmp.Unix.st_kind
      in
      let fk = try (filekind name ) with
                  | Unix.Unix_error (Unix.ENOENT,_,_) -> Unix.S_DIR
                  | _ -> Unix.S_DIR

       in
       match fk with
       | Unix.S_REG -> true
       | _          -> false;;



This example works: It tells me, if a file is of kind/type
regular file with true. If it is not a regular file
or an error occured, it tells me this by passing
me the result false.

I thought about printing an error-message when an error
occurs. I can do this by inserting a printing-command
into the try-construct, if I return a Unix.st_kind-value
(so that Ocaml get's right types back). I tried this,
and it works - so I know how to handle the Unix.ENOENT
(and that makes my lucky :)). But I nevertheless have
more questions.





IMHO it looks a littlebid dirty, to return Unix.S_DIR
on an error-case, even if it is only internal to the
function is_regularfile.

Yes, I know, here is it an advantage of FPLs to give back
only the result and have the inner dirty tricks encapsulated
by the scoping here (at least that it is possible to
programn in this way, even if not mandatory).

But If I would split up the function into
three functions (one returning the filetype, one
doing the error-/exception-handling (giving back non-Unix.S_REG
e.g by using Unix.S_DIR) and one function, using these two functions,
returning a boolean value) the advantage of an FPL
is gone, because using unclean programming (which then
nevertheless is possible).
(Or is the problem here, that pattern-matching and
 exception-handling is not purely functional?)

Is there a type like "None of the defined Unix.st_kind-results",
such as NULL in C is definitely a non-valid address?

Does advantage of FPLs in respect to clean programming
belongs in "encapsulation by scoping" with nested
let-statements, which are hiding usage of unclean values
(like above)?

Or is it completely ok to write such functions like above?
(Philosophically question...?!)

BTW: What about the indentation-style of my function?
How would you rewrite that function, when using
Ocaml-like indentation?

TIA,
   Oliver

-------------------
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] 5+ messages in thread

* Re: [Caml-list] Unix-Filekind => codexample with questions
  2002-04-21 20:50 [Caml-list] Unix-Filekind => codexample with questions Oliver Bandel
@ 2002-04-21 21:04 ` Remi VANICAT
  2002-04-21 21:17 ` John Prevost
  1 sibling, 0 replies; 5+ messages in thread
From: Remi VANICAT @ 2002-04-21 21:04 UTC (permalink / raw)
  To: caml-list

Oliver Bandel <oliver@first.in-berlin.de> writes:

> Hello,
> 
> I need a function, which tells me if a file is
> a regular file or not.
> 
> Please look at my code-example:
> 
> let is_regularfile name =
>       let filekind name = let tmp = Unix.stat name in tmp.Unix.st_kind
>       in
>       let fk = try (filekind name ) with
>                   | Unix.Unix_error (Unix.ENOENT,_,_) -> Unix.S_DIR
>                   | _ -> Unix.S_DIR
> 
>        in
>        match fk with
>        | Unix.S_REG -> true
>        | _          -> false;;
> 
> 
> 

[...]


> 
> IMHO it looks a littlebid dirty, to return Unix.S_DIR
> on an error-case, even if it is only internal to the
> function is_regularfile.


it is, i would use :

let is_regularfile name =
  let filekind name = let tmp = Unix.stat name in tmp.Unix.st_kind in
  try 
    match filekind name with
    | Unix.S_REG -> true
    | _          -> false;;
  with
    | Unix.Unix_error (Unix.ENOENT,_,_) -> false
    | _ -> false



-- 
Rémi Vanicat
vanicat@labri.u-bordeaux.fr
http://dept-info.labri.u-bordeaux.fr/~vanicat
-------------------
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] 5+ messages in thread

* Re: [Caml-list] Unix-Filekind => codexample with questions
  2002-04-21 20:50 [Caml-list] Unix-Filekind => codexample with questions Oliver Bandel
  2002-04-21 21:04 ` Remi VANICAT
@ 2002-04-21 21:17 ` John Prevost
  2002-04-21 21:56   ` Markus Mottl
  2002-04-23 14:45   ` Oliver Bandel
  1 sibling, 2 replies; 5+ messages in thread
From: John Prevost @ 2002-04-21 21:17 UTC (permalink / raw)
  To: Oliver Bandel; +Cc: caml-list

>>>>> "ob" == Oliver Bandel <oliver@first.in-berlin.de> writes:

    ob> Hello, I need a function, which tells me if a file is a
    ob> regular file or not.

    ob> Please look at my code-example:

        let is_regularfile name =
              let filekind name = let tmp = Unix.stat name in tmp.Unix.st_kind
              in
              let fk = try (filekind name ) with
                          | Unix.Unix_error (Unix.ENOENT,_,_) -> Unix.S_DIR
                          | _ -> Unix.S_DIR

               in
               match fk with
               | Unix.S_REG -> true
               | _          -> false;;


    ob> This example works: It tells me, if a file is of kind/type
    ob> regular file with true. If it is not a regular file or an
    ob> error occured, it tells me this by passing me the result
    ob> false.

How about:

let is_regularfile name =
  try (match Unix.stat name with
         | {Unix.st_kind = Unix.S_REG} -> true
         | _ -> false)
  with
    _ -> false

I'm not sure why you're using so many intermediate values here--it
just seems to make the code harder to figure out.  Better to just wrap
a try around the whole check, and use a small simple match on the stat
result.

John.
-------------------
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] 5+ messages in thread

* Re: [Caml-list] Unix-Filekind => codexample with questions
  2002-04-21 21:17 ` John Prevost
@ 2002-04-21 21:56   ` Markus Mottl
  2002-04-23 14:45   ` Oliver Bandel
  1 sibling, 0 replies; 5+ messages in thread
From: Markus Mottl @ 2002-04-21 21:56 UTC (permalink / raw)
  To: John Prevost; +Cc: Oliver Bandel, caml-list

On Sun, 21 Apr 2002, John Prevost wrote:
> How about:
> 
> let is_regularfile name =
>   try (match Unix.stat name with
>          | {Unix.st_kind = Unix.S_REG} -> true
>          | _ -> false)
>   with
>     _ -> false

Or even shorter:

  let is_regularfile name = 
    try (Unix.stat name).Unix.st_kind = Unix.S_REG with _ -> false

Some people would prefer opening the Unix-module first for brevity:

  open Unix
  let is_regularfile name = try (stat name).st_kind = S_REG with _ -> false

Regards,
Markus Mottl

-- 
Markus Mottl                                             markus@oefai.at
Austrian Research Institute
for Artificial Intelligence                  http://www.oefai.at/~markus
-------------------
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] 5+ messages in thread

* Re: [Caml-list] Unix-Filekind => codexample with questions
  2002-04-21 21:17 ` John Prevost
  2002-04-21 21:56   ` Markus Mottl
@ 2002-04-23 14:45   ` Oliver Bandel
  1 sibling, 0 replies; 5+ messages in thread
From: Oliver Bandel @ 2002-04-23 14:45 UTC (permalink / raw)
  To: John Prevost; +Cc: caml-list



On 21 Apr 2002, John Prevost wrote:

> >>>>> "ob" == Oliver Bandel <oliver@first.in-berlin.de> writes:
> 
>     ob> Hello, I need a function, which tells me if a file is a
>     ob> regular file or not.
> 
>     ob> Please look at my code-example:
> 
>         let is_regularfile name =
>               let filekind name = let tmp = Unix.stat name in tmp.Unix.st_kind
>               in
>               let fk = try (filekind name ) with
>                           | Unix.Unix_error (Unix.ENOENT,_,_) -> Unix.S_DIR
>                           | _ -> Unix.S_DIR
> 
>                in
>                match fk with
>                | Unix.S_REG -> true
>                | _          -> false;;
> 
> 
>     ob> This example works: It tells me, if a file is of kind/type
>     ob> regular file with true. If it is not a regular file or an
>     ob> error occured, it tells me this by passing me the result
>     ob> false.
> 
> How about:
> 
> let is_regularfile name =
>   try (match Unix.stat name with
>          | {Unix.st_kind = Unix.S_REG} -> true
>          | _ -> false)
>   with
>     _ -> false
> 
> I'm not sure why you're using so many intermediate values here--it
> just seems to make the code harder to figure out.  Better to just wrap
> a try around the whole check, and use a small simple match on the stat
> result.


I really started with more than one functions and then
only put them together into one function, to have a
cleaner function (not giving the Unix.S_DIR (as an indicator
of not-Unix.S_REG)i as returnvalue to the outside).

I thought about pattern-matching the records, and to
use the ".member"-notation of records directly to the
application of the stat-function (as in Markus' example),
but I didn't know if OCaml's syntax provides the latter one.

So I used my first working "one-function-only"-version
and asked you all for comments.



For example the part with

>               let fk = try (filekind name ) with
>                           | Unix..Unix_error (Unix.ENOENT,_,_) -> Unix.S_DIR
>                           | _ -> Unix.S_DIR

may be too verbose and does not make any sense, because both
cases return the same value and the "_"-match matches on
all cases.

But I'm relativley new to Ocaml and therefore I can see the details
in matching the error-value better, when written explicitly (the
first case) and it's easier to expand the matching, when using
copy&paste&change of that line (changing Unix.ENOENT to the
needed value after duplicating the line). So, some maybe
unnecessary looking constructs
in the code were helpers for understanding, what I'm doing.

With more experience in OCaml-programming I maybe do not need
such verbose code (and I really like brevity - that's one of
the main-reasons to choose OCaml as my favourite programming
language for future projects).

But nevertheless, it's always worth to think about
verbose coding of programs, if that clarifies the
intention. At least in C-programming, writing more
code than less may help in understanding, what's going on.
[1]

Maybe it's different in OCaml, because it's code
does contain enough sense per command-word/line of code.
In C there is too much bloat; and more verbose coding
can (may) help in understanding.

So the verbose coding of my example was a result of
too-many-years-C-programming and too less experience
in Ocaml-programming.


All answers had helped a lot.

Ciao,
   Oliver


[1]: I like the literate programming idea; e.g. haskell provides
 two programming styles: code with inserted comments,
 or text with inserted code; so programming and documenting
 the code means, to edit *one* document, but to get
 the program and the documentation as a result. And in this
 way it's much easier and more motivating to write documentation
 of code-snippets (and the real advantage comes in big projects).
 All other (non-literate-programming) attempts
 in programming (programming here means: design+coding+documenting)
 I have seen, doesn't worked well.


-------------------
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] 5+ messages in thread

end of thread, other threads:[~2002-04-23 15:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-04-21 20:50 [Caml-list] Unix-Filekind => codexample with questions Oliver Bandel
2002-04-21 21:04 ` Remi VANICAT
2002-04-21 21:17 ` John Prevost
2002-04-21 21:56   ` Markus Mottl
2002-04-23 14:45   ` Oliver Bandel

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