Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
[Caml-list] Dynamically evaluating OCaml code
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2004-04-16 (18:10)
From: skaller <skaller@u...>
Subject: Re: [Caml-list] build tools - good vs. fast, both cheap
On Sat, 2004-04-17 at 02:06, Kenneth Knowles wrote:

> These are the approaches I can see out there:
> (1) Monolithic automagical GNU Makefile
> (2) O'Caml script outputing make-agnostic Makefile
> (3) Command-line build-every-at-once ocaml tool
> (4) Roll your own Makefile, have the user edit it - often separated into a
>     Makefile.config.
> (5) Use autoconf (why, oh why?  it doesn't offer any O'Caml support)
> (6) Interscript? I don't really understand what it does and what the developer
>     must do.

I'm against make. It just isn't necessary. Make is for C developers,
not Ocaml package installation. To build a package it suffices
to run a sequence of commands in a fixed order.

To understand interscript .. what does it do?
The answer is the same as tar -zxvf, except that
'extracting' a file can execute arbitrary code.
Its that simple. Here's an example:

@head(1,"My program")
Its only a demo.

let f x = x + x
@for i in [1..10]:
  tangle("print_endline (f "+i+");")

This demo prints 2,4, .. 20. The Python script
means: @head -- document heading level 1.
The @select(tangler("")) .. means 
"write the following stuff to"

The @ starts an arbitrary Python command.
The select, tangler, and head functions
are just interscript library functions,
nothing special. The tangle() functions
write a string to output.

The for loop prints out 

print_endline(f 1);
print_endline(f 2);
etc up to 10. It is just a standard Python construction,
nothing special. If you want to compile
the above program instantly, here is how to do it:

@os.system("ocamlc -c")

Duh. It just calls Python's system function,
which is C's system function. It is more usual
to do this though:

@tangle("\tocamlc -c")

and then after you run interscript you have
a makefile, and you can compile using 
the ordinary 'make' command. 

The point of all this is: you can do anything
you want. Its just Python script, with a little
control loop that copies lines to the weaver
for typesetting, the tangler to write a source
file, or executes them (if they start with @).

Oh yes, there is much more than that,
but this is the basic idea...

EXECISE: What does this do:

@os.system("ocaml > sample.out")
@f = open("sample.out")
@for i in [1..10]:

If you want to see a more advanced use
of the executable facilities, examine
section 6.4 of the interscript implementation
listing at

What you will see there is the full
Unicode data, and code tables for something like
30 other standard character sets -- there
are hundreds of pages of character tables,
and the whole of it is generated by about
a page of code which downloads and reads
the data files.

Here is a real example from Felix compiler.
Have you ever got annoyed at copying
things in both mli and ml files??

@head(1,'Compile time exceptions')
exceptions = """
open Flx_ast
open Flx_types
exception SyntaxError of string
exception ParseError of string
exception LexError of string
exception TokenError of string
exception ClientError of range_srcref * string
exception ClientError2 of range_srcref * range_srcref * string
exception SystemError of range_srcref * string
exception Exit of int
exception Bad_recursion
exception Expr_recursion of expr_t
exception Free_fixpoint of btypecode_t 
exception Unresolved_return of range_srcref * string
@h = tangler('src/')
let clierr2 sr sr2 s = raise (ClientError2 (sr,sr2,s))
let clierr sr s = raise (ClientError (sr,s))
let syserr sr s = raise (SystemError (sr,s))
let catch s f = try f() with _ -> failwith s

@h = tangler('src/flx_exceptions.mli')
val clierr: range_srcref -> string -> 'a
val clierr2: range_srcref -> range_srcref -> string -> 'a
val syserr: range_srcref -> string -> 'a
val catch: string -> (unit -> 'a) -> 'a

John Skaller,
voice: 061-2-9660-0850, 
snail: PO BOX 401 Glebe NSW 2037 Australia
Checkout the Felix programming language

To unsubscribe, mail Archives:
Bug reports: FAQ:
Beginner's list: