logo       
Google Custom Search
    AddThis Social Bookmark Button
-->

Re: Future of ExtLib: msg#00005

Subject: Re: Future of ExtLib
On Thu, Dec 16, 2004 at 10:22:05AM +0100, Nicolas Cannasse wrote:
> Hi list,
> 
> It's been long time without activity on this list, I have been quite busy
> lately but I keep on fixing bugs when reports are coming sometimes ;). Right
> now the ExtLib acheivements are pretty good : I am a happy ExtLib user and I
> don't feel anymore when I write Ocaml that I miss all theses functions from
> Stdlib. That's good, and I hope you feel same.
> 
> As for the future, I am not certain which path we should follow. I tend to
> appreciate the current shape of ExtLib and I'm not wishing to include a lot
> more modules, but other people might think different. What I would like to
> be included in ExtLib would be small Xml and Date modules, but I'm not sure
> we can reach agreement on what should be put inside theses ;). Any insights
> or wishes are welcome !

ExtLib works great for me.  The only thing I'd like to see is more of
the same.  Some ideas:

List.takewhile and List.dropwhile still seem to be missing (I posted a
patch for this on list some time ago).

Simple config file parsing.  YAML-compatibility would be awesome.  Or
take a look at ConfigParser in JG's MissingLib.

List.range:

    let rec range a b =
      if a <= b then
        a :: range (a+1) b
      else
        []

String.truncate:

    let truncate ?(with_dots = false) ?(dots = " ...") n str =
      if String.length str < n then
        str
      else (
        if not with_dots then
          String.sub str 0 n
        else (
          let n = n - String.length dots in
          let str = String.sub str 0 n in
          str ^ dots
        )
      )

Controversial, because they only work on ASCII-compatible string
encodings (ie. ASCII, UTF-8, ISO-8859-1, but not UCS-2), but extremely
useful:

    val isspace : char -> bool
    val isalpha : char -> bool
    val isdigit : char -> bool
    val isalnum : char -> bool
    val islower : char -> bool
    val isupper : char -> bool
    val isxdigit : char -> bool

From this you can have trimming functions:

    let triml ?(test = isspace) str =
      let i = ref 0 in
      let n = ref (String.length str) in
      while !n > 0 && test str.[!i]; do
        decr n;
        incr i
      done;
      if !i = 0 then str
      else String.sub str !i !n
    
    let trimr ?(test = isspace) str =
      let n = ref (String.length str) in
      while !n > 0 && test str.[!n-1]; do
        decr n
      done;
      if !n = String.length str then str
      else String.sub str 0 !n
    
    let trim ?test str =
      trimr ?test (triml ?test str)

And also String.for_all / String.exists functions:

    let string_for_all f str =
      let len = String.length str in
      let rec loop i =
        if i = len then true
        else (
          let c = str.[i] in
          if not (f c) then false
          else loop (i+1)
        )
      in
      loop 0
    
    let string_exists f str =
      let len = String.length str in
      let rec loop i =
        if i = len then false
        else (
          let c = str.[i] in
          if f c then true
          else loop (i+1)
        )
      in
      loop 0

    let string_is_whitespace = string_for_all isspace

List.uniq and List.sort_uniq:

    let rec uniq ?(cmp = Pervasives.compare) = function
        [] -> []
      | [x] -> [x]
      | x :: y :: xs when compare x y = 0 ->
          uniq (x :: xs)
      | x :: y :: xs ->
          x :: uniq (y :: xs)
    
    let sort_uniq ?cmp xs =
      let xs = List.sort ?cmp xs in
      let xs = uniq ?cmp xs in
      xs

List.group_by is useful when you're pulling stuff out of a database:

    let group_by ?(cmp = Pervasives.compare) ls =
      let ls' =
        List.fold_left
          (fun acc (day1, x1) ->
             match acc with
                 [] -> [day1, [x1]]
               | (day2, ls2) :: acctl ->
                   if cmp day1 day2 = 0
                   then (day1, x1 :: ls2) :: acctl
                   else (day1, [x1]) :: acc)
          []
          ls
      in
      let ls' = List.rev ls' in
      List.map (fun (x, xs) -> x, List.rev xs) ls'

Meta-functions, like in standard ML:

    let notf f =
      fun v -> not (f v)

That'll do for the moment, I think!

Rich.

-- 
Richard Jones.  http://www.annexia.org/  http://www.j-london.com/
>>>   http://www.team-notepad.com/ - collaboration tools for teams   <<<
Merjis Ltd. http://www.merjis.com/ - improving website return on investment
Write Apache modules in OCaml - http://www.merjis.com/developers/mod_caml

Attachment: signature.asc
Description: Digital signature

<Prev in Thread] Current Thread [Next in Thread>