learn-ocaml icon indicating copy to clipboard operation
learn-ocaml copied to clipboard

The optional file "depent.txt" is not working

Open git-amd opened this issue 4 years ago • 7 comments

Hi,

In the context of some learn-ocaml exercises, I need to preload some external code (".ml" and ".cma" files). I tried to use the optional file "depend.txt" as described in the manual (http://ocaml-sf.org/learn-ocaml/tutorials/step-8.html). However, this seems to fail to work. I cannot manage to make the external code available to the student's code.

Here is the description of one failed experiment. I'm trying to gain access to some module "Q" that exports the symbol "q".

- Definition of module Q

> cat my-learn-ocaml-repository/exercises/lib/q.ml
   let q = 123 ;;
   let w = 456 ;;
> cat my-learn-ocaml-repository/exercises/lib/q.mli
   val q: int

- Checking the module Q

> ocamlc -c q.mli q.ml
> ocaml q.cmo
        OCaml version 4.05.0
# Q.q;;
- : int = 123
# Q.w;;
Error: Unbound value Q.w

- The file "depend.txt"

> cat my-learn-ocaml-repository/exercises/demo/depend.txt
../lib/q.mli
../lib/q.ml

- Rebuilding the repository and launching the learn-ocaml server

> touch my-learn-ocaml-repository/exercises/demo/test.ml
> learn-ocaml build  --repo my-learn-ocaml-repository
Learnocaml v.0.12 running.
Updating app at ./www
demo                         [OK]
> learn-ocaml serve
Learnocaml server v.0.12 starting on port 8080
Found the following teacher tokens:
  - X-1JJ-OZA-V41-XXX

- Using the exercise "demo" in the web browser

   Q.q;;
Unbound module Q

Thank you,

- Artur Miguel Dias

git-amd avatar Nov 12 '20 06:11 git-amd

@lsylvestre Can you help us with this one?

yurug avatar Nov 12 '20 07:11 yurug

Hi,

thank you for your interest in this feature. As far as I know, it is not yet possible to preload external code and to make it available to the student's code.

The optional file depend.txt just allow to make external code available to test.ml, in the grading environment.

For instance, by replacing the content of my-learn-ocaml-repository/exercises/demo/test.ml with :

Test_lib.set_result @@ 
  [ Report.info ~message:("Q.q = " ^ string_of_int Q.q) ] ;;

the result in the web browser is :

q123

lsylvestre avatar Nov 12 '20 10:11 lsylvestre

You answer was very useful to me. I quickly understood that the exercises run in a restricted environment with access to a limited set of libraries and with no reach to the file system. This is a consequence of the translated OCaml code running on the browser, on the client side of the learn-ocaml application.

Probably, it should be possible to create a customized version of learn-ocaml with extra ocaml libraries available. Nevertheless, we tried to find a solution within the confines of the user manual.

Our code had a single dependence: the Yojson library. Our final, best solution was to get rid of this dependency and to write by hand a new small JSon parser, a neat piece of code with only 150 lines. After all, the json format is LL(1) parsable...

A different attempt that also worked, however with less flexibility, was to preprocess all the JSon examples beforehand, so that the json parser was not required at runtime.

One funny failed attempt that is worth mentioning was to try and expand inline the entire code of the Yojson library, which amounts to 14 thousand lines of OCaml code. Extra two thousand lines of code from the module Stream was also required. The final single file "depend.txt" ran perfectly on the regular OCaml interpreter, but the client side of learn-ocaml couldn't cope with it due to sheer size (we got the error "INTERNAL ERROR: error in prelude").

Thank you!

git-amd avatar Dec 30 '20 08:12 git-amd

Thank you for your feedback on your experiments. I was just testing another solution that you may find helpful:

You can customise the Learn-OCaml interpreter by declaring compiled files in : https://github.com/ocaml-sf/learn-ocaml/blob/master/src/grader/dune#L86

For instance, by declaring %{ocaml-config:standard_library}/stream.cmi, and then recompiling Learn-OCaml, Stream can be used in all the exercises.

On my opam installation, %{ocaml-config:standard_library} is ~/.opam/<switch-name>/lib/ocaml, and Yojson is in ~/.opam/<switch-name>/lib/Yojson.

Therefore, by declaring something like %{ocaml-config:standard_library}/../Yojson/yojson.cmi, I can use Yojson on the client side :

cutsom-learn-ocaml

Have a good day!

lsylvestre avatar Dec 30 '20 13:12 lsylvestre

This is great! Thank you for the very clear examples.

git-amd avatar Dec 31 '20 19:12 git-amd

I guess we can close this issue, right?

yurug avatar Jun 23 '21 08:06 yurug

Yes, I agree.

lsylvestre avatar Jun 23 '21 16:06 lsylvestre