Thursday, July 31, 2008

Dada generator

Disclaimer: this program is not useful in any way.

Ok, I wrote this one when I was listening to a lecture on databases and data warehouses - I was exploring functional programming at the time, and decided that if you really thought about it you could make a very nice and pleasant function that does almost absolutely nothing, apart from being aesthetically pleasing. After I wrote one on paper, I decided that it could be expanded a bit, but it was too much hassle to do by hand... so, a generator!

What this program does is actually generate a program, which, upon running will recursively pass all its parameters to itself, and when the recursion stops it will use the first of the parameters as a function, supplying it with the other parameters as parameters... is this clear? I suppose an example is in order...

Ok, so first, I run the program in the following way:

ocaml dada_gen.ml 5 f a b c > dada_ex.ml


...and got the following code as a result (in the file dada_ex.ml):

let f a b c =
   let f a b c =
      let f a b c =
         let f a b c =
            let f a b c =
               let f a b c =
                  a b c 
               in f a b c 
            in f a b c 
10         in f a b c 
11      in f a b c 
12   in f a b c 
13;;
14



Ok, then I run the Ocaml top-level like this:

ocaml


Inside the toplevel I loaded the file:

#use "dada_ex.ml";;


...and got the response:

val f : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = <fun>


...and then the function f funtion like this:

f (+) 2 2


...and got in return:

- : int = 4


...which just means that the result is 4. I could've achieved the same by going:

(+) 2 2;;


...or even

2 + 2


That's why its dada. It's not meant to be useful!

Yeah, I know, I'm weird.

Here's the script:
(**
 * Dada generator
 * Generates a completely useless but aesthetically pleasing dada program
 * 
 * Potential issues:
 *  None
 * Parameters:
 *  number of internal functions
 *  name of the dadaistic function
10 *  list of passed parameters
11 * Requires:
12 *  Ocaml (http://caml.inria.fr/)
13 *  Sense of humor
14 *)
15
16(**
17 * Function responsible for generating dadaistic programs basing on the 
18 * supplied parameters
19 * @param function_name the name of the main function
20 * @param parameter_list a list of strings which will be inserted as the 
21 *  body of the inner-most function
22 * @param nested_function_count the number of functions generated inside 
23 *  the main function
24 * @author Konrad Siek
25 *)
26let generate_dada function_name parameter_list nested_function_count =
27   let rec list_to_string list =
28      match list with 
29        | head::tail -> head ^ " " ^ (list_to_string tail)
30        | [] -> ""
31   in
32   let rec tabs count = 
33      if count = 0 then
34         ""
35      else
36         "   " ^ (tabs (count - 1))
37   in
38   let program = ref ("let " ^ function_name  ^ " " ^ 
39        (list_to_string parameter_list) ^ "=\n") in
40   let _ = for i = 1 to nested_function_count do
41     program := !program ^ (tabs i);
42     program := !program ^ "let " ^ function_name ^ " " ^ 
43        (list_to_string parameter_list) ^ "=\n"
44   done in
45   program := !program ^ (tabs (nested_function_count + 1)) ^ 
46        (list_to_string parameter_list) ^ "\n";
47   let _ = for i = nested_function_count downto 1 do
48     program := !program ^ (tabs i);
49     program := !program ^ "in " ^  function_name ^ " " ^ 
50        (list_to_string parameter_list) ^ "\n"
51   done in
52   program := !program ^ ";;\n";
53   !program
54;;
55
56(* Main method calling the generation function. *)
57if Array.length Sys.argv > 3 then 
58   let count = int_of_string Sys.argv.(1) in
59   let function_name = Sys.argv.(2) in
60   let parameters = Array.to_list 
61    (Array.sub Sys.argv 3 (Array.length Sys.argv - 3)) in
62   let program = generate_dada function_name parameters count in
63   print_endline program
64else
65   print_endline ("Usage:\n\t" ^ Sys.argv.(0) ^ " <function_count> " ^ 
66        "<main_function_name> <parameter> [ ... <parameter> ]")
67;;


The code is also available at GitHub as ocaml/dada_generator.ml.

No comments: