Stream/1.t vs Stream/2.t

Good morning, everybody.

I’m using Yojson.Safe.stream_from_string to, obviously, create a stream from a string.

Then I’m using the following function to convert a stream to Yojson.Safe.t list:

    let rec read_stream l (s : Yojson.Safe.t Stream.t) =
      try
        let j = Stream.next s in
        read_stream (j::l) s
      with
      | Yojson.Json_error _ -> read_stream l s
      | Stream.Failure -> l
    in
    let jsons = List.rev @@ read_stream [] stream in (* ... *)

This code worked for many years but after the latest opam upgrade I’m getting the following error:

Error: This expression has type json Stream/2.t
       but an expression was expected of type json Stream/1.t
       File "_none_", line 1:
         Definition of module Stream/1
make: *** [build] Error 1

I did try to rebuild the project from scratch and to remove and rebuild whole .opam repo with zero success.

Currently, I’m using ocaml 4.12.

What do I miss?

I just tried out your sample code in utop and it worked fine:

# #require "yojson";;
# let rec read_stream l (s : Yojson.Safe.t Stream.t) =
      try
        let j = Stream.next s in
        read_stream (j::l) s
      with
      | Yojson.Json_error _ -> read_stream l s
      | Stream.Failure -> l;;
val read_stream :
  Yojson.Safe.t list -> Yojson.Safe.t Stream.t -> Yojson.Safe.t list = <fun>
# let jsons stream = List.rev @@ read_stream [] stream;;
val jsons : Yojson.Safe.t Stream.t -> Yojson.Safe.t list = <fun>

The error you’re getting looks like a build issue to me. Perhaps different versions of the same library are accidentally getting linked in to the same compilation. If you’re not using dune, I’d highly recommend migrating to get rid of build system errors like these.

Also you didn’t mention your yojson library version; mine is 1.7.0.

1 Like

My hunch: some weird interaction between (implicit_transitive_deps false) and the new compatibility package camlp-streams.

1 Like

Guys,

Thanks for your answers. Problem was solved by explicit use of Stdlib.Stream.next and Stdlib.Stream.Failure. Looks like some module I open in the beginning provide their own Stream now.

Btw, what is the best way to find this “provider”?

Depends on your build tool. I would check the build’s library dependencies. Particularly looking for what Antonio mentioned.

1 Like

For some good news, Yojson 2.0.0 does not use Stream anymore, since it was deprecated for OCaml 5 but instead uses Seq, that particular issue goes away.

1 Like

FYI This issue is being fixed in Only install modules for 4.14+ by dra27 · Pull Request #5 · ocaml/camlp-streams · GitHub.

Cheers,
Nicolas

Thanks everyone, I appreciate your answers :+1:t2: