Slashdot Mirror


mod_caml Comes Of Age

Richard W.M. Jones writes "mod_caml is a set of bindings between Objective Caml and the full Apache API. mod_caml 0.6 has bindings for the Apache API and a full Perl-like CGI and templating library. There's only two things you need to know about Objective Caml: it's a modern, fully-featured and highly-optimised language, and it has a good tutorial so Perl/Java/C/C++ programmers can join in the fun."

43 comments

  1. Old caml page by notfancy · · Score: 2, Informative

    I've noticed that the home page is kind of slow. There's the original, old one at INRIA.

    HTH

  2. caml rules by Anonymous Coward · · Score: 0

    caml rules

  3. O'Caml for Scripting? by Anonymous Coward · · Score: 1, Interesting

    i have a question: ocaml is usually only used for "heavy" projects like compilers or proof assistants. however, it should also be a great scripting language. i wonder if other people have used it for this purposes and would like to relay their experiences -- good or bad?

    1. Re:O'Caml for Scripting? by wcbarksdale · · Score: 1
      What? You don't want strong typing in a scripting language -- for all the differences between Perl and Python, weak typing is one thing they share. (S)ML is my favorite language but I wouldn't use it for scripting.

      worst troll ever

    2. Re:O'Caml for Scripting? by notfancy · · Score: 5, Informative

      Actually, the procedural elements of OCaml are so strong than, other than syntax (which is more convenient for functional composition than for imperative sequencing), it is an absolute joy to program UN*X-type filters and transformers in it.

      OCaml has a very complete interface to UN*X (including sockets), supports native (POSIX) threading, lots of publicly available libraries exist from regexps to XML parsing, etcetera; so it can be (and is!) used for systems-level programming, much as you would use C or Java.

      The only thing that may put down programmers accustomed to the more forgiving, dynamic nature of scripting languages like Perl is that OCaml's type system is very strict, much more so than Java's. On the other hand, it has type inference, whereas you rarely if ever need to type-declare things (other than for documenting, that is).

      For the sake of example, this is how you would program wc in OCaml:

      type counts = {
      mutable lines: int;
      mutable words: int;
      mutable chars: int;
      }

      let wc fname =
      let inch = open_in fname
      and stat = { lines = 0; words = 0; chars = 0 }
      in begin
      try while true do
      begin
      match input_char inch with
      '\n' -> stat.lines <- stat.lines + 1;
      stat.words <- stat.words + 1
      | '\t'
      | ' ' -> stat.words <- stat.words + 1
      | _ -> ()
      end;
      stat.chars <- stat.chars + 1
      done with End_of_file -> ()
      end;
      close_in inch;
      stat

      Sorry for the ugly formatting, but Slash is unforgiving

    3. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 0

      a. you can use <CODE> for better formating
      b. your code is incorrect (how many words
      in a file that consists of 1000 spaces?
      1000 according to you)
      c. what will happen if input_char fails?
      the file will not be closed. use
      with_open_file (google fa.caml)

    4. Re:O'Caml for Scripting? by rmull · · Score: 1

      Weak != Dynamic.
      Python is strongly, dynamically typed. Perl's is just wierd, I wouldn't call it strong or weak.

      The killer feature of ML derivatives is type inference, which in theory gives you the benefits of declaritve static typing (like C or Java) without the hassle and those of dynamic typing without the uncertainty.

      --
      See you, space cowboy...
    5. Re:O'Caml for Scripting? by Tom7 · · Score: 1

      Actually, I disagree with you. One of the things nice about static typing is that it gives you error messages BEFORE you run your program. Have you ever written a "run-once" perl script that messes everything up because of a runtime error? I have (well, not perl, but elisp), and I think that my bugs would have been caught by SML's static typing.

      I think that perl and python's main offerings are a convenient syntax and easy access to library functions that do the right thing most of the time. SML doesn't have the latter, but it could be added easily. I don't really see the importance of dynamic typing in the way that people use scripting languages.

    6. Re:O'Caml for Scripting? by wcbarksdale · · Score: 2, Interesting
      Only in a very limited sense could Python be considered strong typing. It's stronger than C, but most anything is, and you can do things like
      obj.feild = 4
      and in general, functions tend to care about whether their arguments have certain properties (you can apply something to them) rather than what type they are.

      And yes, type inference is absolutely necessary to have a workable strong-typing system - otherwise you end up with something as verbose as Java.

    7. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 1, Informative

      Christ, that's "good for scripting"? Here's a Ruby version:

      lines = words = chars = 0

      while gets
      lines += 1
      words += $_.scan(/\S+/).length
      chars += $_.length
      end

      puts "#{lines} #{words} #{chars}"

      I'd call a language like that "good for scripting". Doesn't get in your way.

    8. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 0

      Perl is dynamic and strongly typed as well. You can't treat a scalar like an array for instance. The weird thing is that objects are scalars. There's no "object" or "instance" type, just a scalar that you can call methods on.

    9. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 1, Informative

      Same in OCaml :

      open Str

      let (+=) r i = r := !r + i

      let lines = ref 0 and words = ref 0 and chars = ref 0

      let _ = try while true do
      let s = read_line () in
      chars += String.length s;
      lines += 1;
      words += List.length (split (regexp "\\( \\)+") s)
      done
      with _ -> Printf.printf "%d %d %d\n" !lines !words !chars

    10. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 0
      Nice. (Nice Ruby too, to the other guy.) Here's a recursive one in OCaml:
      let rec wc (lines, words, chars) =
      try let s = read_line () in
      wc (lines + 1,
      words + List.length (Str.split (Str.regexp "[ \t]+") s),
      chars + String.length s)
      with End_of_file -> (lines, words, chars)
      ;;
      let lines, words, chars = wc (0, 0, 0) in
      Printf.printf "%d %d %d\n" lines words chars
    11. Re:O'Caml for Scripting? by Zucht · · Score: 1

      Using Ocaml as a scripting language as a purpose? Over the years I have come the believe that there is no real distinction in requirements for languages for, what you call "heavy" projects, and scripting. Scripting, according to consensus of opinion, requires an expressive language and generally an interpreter for quick write, run, debug cycles. "Heavy" projects benefit from an expressive language as well. It should be common knowledge by now that the number of bugs per lines of code is constant no matter what language is used. Hence a more expressive language that require less lines of code to get something done results in less buggy code. Ocaml is arguably more expressive than for instance "scripting" languages such as Perl and Python. Maybe I should have said functional languages are arguably more expressive than Perl and Python. Anyway, what makes Ocaml such a great language is that it is a full featured toolbox for the programmer. Does de problem you are trying to solve favor a functional approach, Ocaml can do it. Does it favor a more imperative style, Ocaml can do it. Does it favor a more OO style, Ocaml can do it. And best of all, it can do it all very elegantly and with excellent performance. Getting back to the scripting part. If you define scripting as suitable for writing web based/server side applications, than Ocaml can be your language of choice as well with this announcement of mod_ocaml. Generally speaking scripting as well as developing "heavy" projects tend to require similar features. It should provide the programmer the tools she needs to get the job done by not forcing a particular paradigm down her throat as Java does, provide a great deal of expressivess, and have good performace. Ocaml fit the bill as no other language.

    12. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 0

      Neat, but not tail-recursive - will overflow stack
      on larger files. You need to move the recursion
      out of try/with to make wc tail-recursive.

      To the Ruby guy: scripts are, by definition, small
      quick and dirty simple programs with lots
      of imperativeness and little emphasis on speed, correctness and clean interfaces.

      OCaml may be OK for scripting but it shines on complicated algorithms: theorem provers, etc.

    13. Re:O'Caml for Scripting? by Richard+W.M.+Jones · · Score: 4, Informative
      I've tried to make mod_caml "scripting"[1] as simple as possible. There's a few example scripts in the manual here:

      http://www.merjis.com/developers/mod_caml/docs.sht ml

      Where possible I've gone for reducing the amount of code that you have to write in the common cases, based on a large amount of experience writing CGI scripts in Perl.

      At the moment we're missing a fully integrated database layer, but that's coming soon (the code is already out there, I just need to pull it in and do the persistent database connection stuff).

      Unfortunately I only get to work on this at weekends, but hope to have a Savannah page up soon so others can more easily contribute.

      Rich.

      [1] It's not really "scripting" as such. OCaml programs are bytecode compiled and dynamically linked into the bytecode interpreter which runs inside Apache. We also hope to get natively compiled loading working at some point.

    14. Re:O'Caml for Scripting? by kivaapina · · Score: 1

      LOL, you make ML syntax look even more weird than it is!

    15. Re:O'Caml for Scripting? by jorleif · · Score: 1

      It's not really "scripting" as such. OCaml programs are bytecode compiled and dynamically linked into the bytecode interpreter which runs inside Apache.


      Does this mean that each request does not spawn an own process (as CGI usually does) but that the "script" is linked into apache? I mean is this not the way PHP for example works? Do you have an assessment on how much this speeds up the processing compared to CGI?
    16. Re:O'Caml for Scripting? by Richard+W.M.+Jones · · Score: 1
      Does this mean that each request does not spawn an own process (as CGI usually does) but that the "script" is linked into apache?

      Yes, that's right. This avoids a fork and the overhead of starting up the bytecode interpreter each time.

      I don't have figures on how much of a speed increase this is, although it undoubtedly has some benefit. However the main reason for doing it is so you can have persistent cached data, and persistent database handles, and that's a much greater win than just avoiding a fork.

      Rich.

    17. Re:O'Caml for Scripting? by jorleif · · Score: 1

      Persistent cached data? So ocaml values can be instantiated once and then shared for the whole application like with a Java appserver? This is great stuff, I really have to try it out. How far along is it? Does it have any kind of session support or is that up to the application programmer?

    18. Re:O'Caml for Scripting? by Richard+W.M.+Jones · · Score: 2, Informative
      Persistent cached data? So ocaml values can be instantiated once and then shared for the whole application like with a Java appserver?

      Yes. There's two ways to do this - either just create the value at the top level of the script. Top level functions in a script get called once when the script is first loaded. The run function (which you have to register) gets called on each invocation.

      Thus:

      (* foo is evaluated just once: *)

      let foo = expensive_function ()

      let run r = ... (* generate the page each time - see examples in manual*)

      let () = Registry.register_script run

      How far along is it? Does it have any kind of session support or is that up to the application programmer?

      It's still in beta, but please play with it! Without people playing with it it will be perpetually beta software.

      Rich.

      PS. You might want to continue this conversation by email because Slashcode sucks for posting code snippets ....

    19. Re:O'Caml for Scripting? by Richard+W.M.+Jones · · Score: 2, Interesting
      Erm, and the other way to do it is by loading a shared module. In httpd.conf:

      CamlLoad /path/to/my/module.cmo

      Then all scripts can access functions/values in Module.

      Rich.

    20. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 2, Informative

      One can really do better in OCaml for scripting purposes than in the initial version:

      let lines, words, chars = ref 0, ref 0, ref 0 in
      Pcre.foreach_line (fun line ->
      incr lines;
      words := !words + List.length (Pcre.split line);
      chars := !chars + String.length line + 1);
      Printf.printf "%d %d %d\n" !lines !words !chars

      Pcre for OCaml is a very high-level and efficient string processing library that can do just about anything that Perl offers for string manipulation - only much faster :)

    21. Re:O'Caml for Scripting? by smallpaul · · Score: 4, Informative

      Only in a very limited sense could Python be considered strong typing. It's stronger than C, but most anything is

      There are a variety of languages that allow you to cast raw memory addresses to whatever you like: C, C++, Forth, Assembly language, many basics, etc. Those are weakly typed languages as the term was originally applied. Python is a strongly, dynamically typed language. And object has exactly one type and you cannot convince it to behave as another type merely by asserting it is that other type. When you try to get a Python object to do something disallowed by its type, you get an exception whereas in the languages described earlier the results are undefined.

    22. Re:O'Caml for Scripting? by notfancy · · Score: 1

      You're right on all three counts, atlhough I'd rather use HTML. I've corrected the program; for anyone interested, it is in here.

      Compiled with ocamlopt -o ocwc ocwc.ml, I got these results:

      [puma:~/Desktop] mgiovann% time ./ocwc hosts
      117233 234466 3752117 hosts
      0.570u 0.060s 0:00.84 75.0% 0+0k 0+0io 0pf+0w
      [puma:~/Desktop] mgiovann% time wc hosts
      117233 234466 3752116 hosts
      0.150u 0.070s 0:00.33 66.6% 0+0k 0+0io 0pf+0w

      I think it's pretty decent.

    23. Re:O'Caml for Scripting? by Anonymous Coward · · Score: 0

      It's references that are scalars. You can bless anything you have a reference to (scalar, array, hash, code, or typeglob) and use it by ref as an "object" (albeit without encapsulation).

    24. Re:O'Caml for Scripting? by HFXPro · · Score: 1

      First tail recursion is defined as calling of the function in any given branch of execution in a call. Provided that a function does not have to rely on the return of the call to get its value it can have tail call removal (thus letting you reuse the same space in the stack). By any given branch this means that if I have an if... then... else.... I can make a recursive call from either then or else. As long as the final result of that then clause does not rely on the recursive call in then it can have the recursive call removed. The same goes for try... catch since those are really just another if....then type structure. Not all languages require or provide tail recusion removal. C, C++, Java, and Common Lisp would fit here. Scheme (I know this one does), Caml, and Haskell I'm pretty sure require it.

      --
      Reserved Word.
    25. Re:O'Caml for Scripting? by penguin7of9 · · Score: 1
      You're confusing "strongly typed" with "statically typed". Strong vs. weak typing is whether the language allows you to perform type-unsafe operations accidentally. Static vs. dynamic typing is whether the language performs its type checks at compile time or at runtime. All four combinations are possible.

      Python is a strongly typed, dynamically typed language. That means that you can do:
      x = 3; x = "q"
      but something like
      "q" / 3
      gives you a type error.

      Old-style Perl and K&R C are weakly typed because they fail to detect many kinds of type errors.
  4. Mod parent down! by Anonymous Coward · · Score: 0

    It's obviously a troll! caml sucks!

  5. Improved linkage by fm6 · · Score: 4, Informative
    The link to Bagley.org gets diverted because Doug Bagley is a Slashdot-hater. You can read his summary of CAML by cutting and pasting
    http://www.bagley.org/~doug/shootout/
    into your address bar.

    Since CAML is a functional language, it's probably more productive to compare it with other functional languages than with more familiar procedural languages. Good stuff here and here. In this context, it makes sense to have a particular look at Guile, which is like mod_caml in that it implements a functional language as a means of writing application extensions.

    1. Re:Improved linkage by Anonymous Coward · · Score: 1, Interesting

      does it really make sense to say that O'Caml is a functional language? clearly it has references and hence is not a pure functional language. it is a mixed paradigm language, like java or c++. in fact, syntactic differences aside, java is a sublanguage of o'caml! hard to believe that o'caml is nevertheless faster than java, but it is ... good work xavier et al!

    2. Re:Improved linkage by Anonymous Coward · · Score: 1, Funny
      Just because Java's slow doesn't make it a mixed paradigm language. While a true mix of functional, list, procedural, logical, and object orientated in a single language, with dynamic interpretation, would indeed be as slow as Java (well, almost as slow), Java manages to be slow without needing to implement so many levels of paradigminity. Using a dynamic object orientation methodology, Java is able to crawl simply by utilizing an ideologically bananas virtual machine architecture.

      I don't know why you'd think its chronic slowness would be for any other reason.

    3. Re:Improved linkage by zangdesign · · Score: 2, Interesting

      I can see his point about hating /. - I read his reasons and they're all reasonable opinions. I pray god I never post anything that is even remotely interesting to /. as a whole.

      So far, no worries on that point.

      --
      To celebrate the occasion of my 1000th post, I will post no more forever on Slashdot. Goodbye.
    4. Re:Improved linkage by wcbarksdale · · Score: 1

      "Functional languages" generally means languages that allow for a functional style (having functions as arguments and/or return values of other functions) without much trouble. There are not may pure functional languages like Haskell in widespread use, mainly because you can't do some things as well (e.g. hashing).

    5. Re:Improved linkage by scrytch · · Score: 2, Insightful

      > Since CAML is a functional language, it's probably more productive to compare it with other functional languages than with more familiar procedural languages.

      Actually no, it's worth comparing against imperative languages, because caml has those features as well, like fully mutable variables (believe it or not, it's not something you take for granted in the FP world -- erlang's variables are set-once, and haskell has only bindings aside from monad 'do' blocks).

      Ocaml does have several annoying features though:

      * No machine types. You cannot express an unsigned 32 bit int in ocaml. This would make writing an IP4 stack in ocaml somewhat onerous. Similarly, there's no "raw" struct types you can finely pack.

      * No overloading at all. To implement the actual nuts and bolts of polymorphism, where the types diverge, you either have to use separate classes or pass along type information explicitly, something like a C++ traits object. Somewhat more palatable with closures, but the monomorphism restriction will then bite you in the ass. Modules are suggested as another mechanism, but I've yet to see actual code that makes them look anything like ad hoc polymorphism.

      * Supremely stupid compiler feedback. My favorite is "the expression is of type foo but is used here with type foo". Perhaps a warning about redefined types would have been handy?

      * Syntax gets uuuuuuugly when using polymorphic types and labels. Objective Labl has been in ocaml for years, but still feels bolted on.

      Personally, I want haskell and ocaml to get together and have a baby, but that's probably asking too much...

      --
      I've finally had it: until slashdot gets article moderation, I am not coming back.
    6. Re:Improved linkage by Haeleth · · Score: 1

      "You cannot express an unsigned 32 bit int in ocaml."

      module UInt32 =
      struct
      type t = Int64.t
      let zero = 0_L
      let one = 1_L
      let minus_one = 0xffffffff_L
      let neg (n : t) = Int64.sub 0x100000000_L n
      let add (n : t) (m : t) = Int64.logand (Int64.add n m) 0xffffffff_L
      let sub (n : t) (m : t) = Int64.logand (Int64.sub n m) 0xffffffff_L
      (* Etc. *)
      end

      Okay, maybe that comes into the category of "somewhat onerous"...

  6. Re:Mod gradparent up! by Anonymous Coward · · Score: 1, Informative

    Yes, mod parent down; but mod gradparent up.
    Caml is the best language ever: Take a look
    at the annual programming language results
    for Ocaml:

    ICFP'02 (1st prize)
    ICFP'01 (3rd prize)
    ICFP'00 (1st prize)
    ICFP'00 (2nd prize)
    ICFP'99 (1st prize)
    ICFP'98 (2nd prize)

    C++ and Java never won anything, even
    though there are always many more C++ and
    Java contestants than OCaml ones.

  7. Re:Mod gradparent up! by PylonHead · · Score: 1

    Now.. to be fair, this is the Functional Programming Contest, and the tasks are designed to favor deep thought and subtle algorithms over raw speed.

    That being said, OCaml is a great language, and I've been hacking in it for the last 5 days straight. It's gotten so that I hate programming in Java (too verbose, and inflexable) and Perl (Datastructures designed to inspire disgust.. I find myself writing $#{$categories} in my code and I want to cry)

    Go OCAML. w00t!

    --
    # (/.);;
    - : float -> float -> float =
  8. Not tail-recursive by r6144 · · Score: 3, Funny
    Here is a tail-recursive version:
    let process_line () =
    try let s = read_line () in
    (true, 1,
    List.length (Str.split (Str.regexp "[ \t]+") s),
    (String.length s) + 1)
    with End_of_file -> (false, 0, 0, 0)
    ;;

    let rec wc (lines, words, chars) =
    match process_line () with
    (true, l, w, c) -> wc (lines + l, words + w, chars + c)
    | (false, _, _, _) -> (lines, words, chars)
    ;;
    let lines, words, chars = wc (0, 0, 0) in
    Printf.printf "%d %d %d\n" lines words chars
    ;;
    1. Re:Not tail-recursive by Anonymous Coward · · Score: 0
      This is a bit simpler I think (still tail-recursive, but not as simple as the imperative OCaml one):
      let rec wc (lines, words, chars) =
      let read () = try (read_line (), false)
      with End_of_file -> ("", true) in
      let s, eof = read () in
      if not eof then
      wc (lines + 1,
      words + List.length (Str.split (Str.regexp "[ \t]+") s),
      chars + String.length s)
      else (lines, words, chars)
      ;;
      let lines, words, chars = wc (0, 0, 0) in
      Printf.printf "%d %d %d\n" lines words chars
      The OCaml samples aren't as simple as the Ruby one, but still, they'd all compile to small, stand-alone executables (170kB in this case), which you couldn't do in Ruby (or Perl or Python). And OCaml code should usually be considerably faster (though not necessarily in this case). Interestingly, OCaml and Ruby have very similar scores for lines-of-code in Bagley's language shootout.
  9. Interested in seeing what ocaml can do? by Anonymous Coward · · Score: 0

    Check out mldonkey .

    It supports a large number of P2P networks and is entirely open source (GPLv2). It's designed to be cross-platform, it has a GTK GUI, a web interface, and a telnet interface. :)

  10. It's really interesting! Good by alexeymas · · Score: 1

    It's simpe and it is great. We write some like this and called it Rejump. www.rejump.com/datafile Now it's exist only in free version (with some limitation) We have file based database in this one. Does any give some links for similar amusing products? Your are welcome!

    --
    Alexey Mas
    www.webnews.tv