I've several suggestions, on how to improve your code.
First of all is the beauty, it matters for those who read the code (not for the compiler). Please, consider using spaces between lexemes. It will be much easier to read your code.
Next, there is no need to put this ;;
And then I'd like to suggest a more cleaner implementation of the printing function
open Printf
type listIS =
| Vide
| I of int * listIS
| S of string * listIS
let rec fprintIS out l = match l with
| Vide -> fprintf out "\n"
| I (i,l) -> fprintf out "%d %a" i fprintIS l
| S (s,l) -> fprintf out "%s %a" s fprintIS l
let l=I(5,I(3,S("3",I(0,S("",Vide)))))
let printIS = fprintIS stdout
let () = printIS l
I hope that you're familiar with printf function. If not, then I can try to find out some other solution, that will be easier for you to understand.
In this solution (I've prettified the code, as you may noticed) I use "%a" format specifier. It requires two arguments: first is the function that prints a value of an arbitrary type and the second is the value of that type. Using specifier you can build combine your printers.