ocaml-sf / learn-ocaml

A Web Application for Learning OCaml
https://ocaml-sf.org/learn-ocaml/
MIT License
304 stars 66 forks source link

Question: what is the 1.0 alternative to private grader helper modules a la depend.txt? #588

Open dm0n3y opened 8 months ago

dm0n3y commented 8 months ago

Related user(s):

@AltGr

Related issue(s) or PR(s):

https://github.com/ocaml-sf/learn-ocaml/pull/481

Related project scope(s):

grading, test_lib

Question?

Tried upgrading to LearnOCaml 1.0 (after over a year), found that my existing grader code for some exercises could no longer be broken up into separate files using depend.txt. It looks like this was removed in favor of test_libs.txt in https://github.com/ocaml-sf/learn-ocaml/pull/481, which requires that I make my grader code available as a library via findlib. I'm not familiar with this process, but from what I skimmed online, it seems a more public-facing option than seems warranted in my case -- I just want to keep many lines of messy datatype samplers and buggy solutions out of my way. Am I misunderstanding the test_libs.txt solution? If not, is there another alternative closer to depend.txt?

What has already been tested:

No response

learn-ocaml --version

1.0.0

git describe --long --always --abbrev=40 --tags

No response

What OS do you use?

GNU/Linux, MacOS

What browser(s) do you use with learn-ocaml?

Chromium

Additional context:

No response

AltGr commented 8 months ago

Indeed, sharing code between graders now requires the definition of a library; but that's much simpler than it seems, and it doesn't need to be user-facing. We'll improve the documentation regarding that.

The easiest way is to use dune: have your mytestlib.ml put in a directory besides the following dune file

(library
 (name mytestlib)
 (public_name mytestlib)
 (wrapped false)
 (modes byte)
 (libraries learn-ocaml.test_lib)
 (flags (:standard -open Test_lib.Open_me))
 (preprocess (action (run %{libexec:learn-ocaml.test_lib:grader-ppx} %{input-file}))))

Then run dune install from that directory, and just write mytestlib into test_libs.txt.

The major benefit of this approach is that your helper module is compiled just once and re-used by every exercise, instead of being recompiled for each one of them.

Thanks a lot for reporting, I will be waiting for your feedback on the above info to update the docs.

erikmd commented 8 months ago

FWIW, there is a comprehensive example here: https://github.com/lsylvestre/easy-check/blob/master/easy-check/src/dune

@AltGr this dune file doesn't have (preprocess (action (run %{libexec:learn-ocaml.test_lib:grader-ppx} %{input-file}))) → is it a bug?

dm0n3y commented 7 months ago

@AltGr @erikmd Thanks for your responses. I made some progress with the suggested approach, but don't have things working yet because of the many helper modules I need to port. Do you recommend that I create a separate dune project for each helper module? Feels very heavy, but not sure it's possible otherwise.

dm0n3y commented 7 months ago

Also, I guess this means I need to repeat this dune installation across different machines if I want to keep my modules private, correct? I usually develop LearnOCaml exercises locally but we run our LearnOCaml server on a dedicated machine on campus.

AltGr commented 7 months ago

this dune file doesn't have [...]

I guess that for this example they don't use the preprocessor, because they only provide helper functions that don't need it ?

Do you recommend that I create a separate dune project for each helper module?

You should be fine with one dune project providing a single OCaml library that bundles all your modules

I need to repeat this dune installation across different machines

If you want to run learn-ocaml build on your server, yes, you'll need it ; If you run that locally and rsync to the server on which you only run learn-ocaml serve it won't be necessary.