Greg Nisbet
Greg Nisbet

Reputation: 6994

OCaml open only certain values/types from module

Does OCaml have an equivalent (possibly involving a camlp4 directive) of

from module import value1, value2 in Python or

use Module qw[value1 value2]; in Perl ?

I'd like to be able to write something like

open Ctypes (@->), string;; or open Ctypes ((@->), string);;

instead of

let (@->) = Ctypes.(@->);;
let string = Ctypes.string;;

Upvotes: 6

Views: 634

Answers (3)

Greg Nisbet
Greg Nisbet

Reputation: 6994

cppo and the C preprocessor since C99 both have the ability to process variadic macros.

This means that you can hide mookid's tuple assignment behind a macro to avoid repeating yourself.

#define USE_FROM(MODULE, ...) \
  let ( __VA_ARGS__ ) = (MODULE . ( __VA_ARGS__ )) ;;

USE_FROM(Printf, printf, sprintf, eprintf);;

let main = begin
  Printf.printf "%s\n" "a"
end

It's also possible to use a non-variadic macro by providing the arguments as a comma-delimited list surrounded by parentheses.

#define USE_FROM(MODULE, STUFF) \
  let ( STUFF ) = (MODULE . ( STUFF )) ;;

USE_FROM(Printf, (printf, sprintf, eprintf));;

let main = begin
  Printf.printf "%s\n" "a"
end

Upvotes: 0

mookid
mookid

Reputation: 1172

The closest is:

let value1, value2 = Module.(value1, value2) 

For this very reason, open statements are most of the time evil (especially at the top level).

Upvotes: 7

Trung Ta
Trung Ta

Reputation: 1732

I'm afraid there is no such partial module opening like what you described.

  • If your modules have no naming conflict, then it's simple enough to just use open Ctypes

  • Otherwise, you can shorten the module name by

    module CT = Ctypes
    
    (* and then just call CT.some_function instead of Ctypes.some_function *)
    
  • Your solutions is quite a neat one, but be careful that the name string may override the primitive type string of OCaml.

    let (@->) = Ctypes.(@->);;
    let string = Ctypes.string;;  (* override the type string *)
    

Upvotes: 2

Related Questions