tweag / nickel

Better configuration for less
https://nickel-lang.org/
MIT License
2.43k stars 93 forks source link

Example from the tutorial fails in Playground #2046

Closed vi closed 1 month ago

vi commented 2 months ago

Describe the bug

Cannot export contracts from files (or rather nickel eval files that export contracts), even though it is one of the first features demonstrated in the beginning of the documentation.

To Reproduce

  1. Go to tutorial: https://nickel-lang.org/user-manual/tutorial
  2. Go to "Step 3: Write a contract"
  3. Copy the code snippet (starting with { UserSchema = {)
  4. Go to Playground: https://nickel-lang.org/playground/
  5. Paste the code there, press Run button.

It displays error error: missing definition for 'name'.

Expected behavior

No error, maybe it displays the scheme back to you.

If I do the tutorial steps locally, nickel eval users.ncl succeeds. nickel typecheck users-schema.ncl also succeeds, but it is confusing that nickel eval users-schema.ncl fails - how can import of a module that fails evaluation succeed?

It would be understandable if nickel export fail to export something incomplete, but nickel eval should probably just evaluate the code and print also the incomplete result.

The error here looks just like the error when source code is invalid.


I think Playground should also have typecheck button and should also show version of Nickel.

suimong commented 2 months ago

@yannham (sorry for pinging) may give you a more complete picture, but essentially nickel export = nickel eval + serialization. As for why typecheck succeeds but eval fails, I'd like to make a rather crude analogy to Python: you have a correctly type annotated python script user-schema.py, which takes an required argument name. In this scenario, mypy user-schema.py will succeed (aka "typecheck"), whereas python user-schema.py will fail because you do not provide the name argument.

yannham commented 2 months ago

I think UserSchema should be seen as an interface of some sort. Or a class definition in a OO programing language, or a header in C/C++, etc - it's not because you can import it that it makes sense to evaluate or to use as a normal value.

Nickel being lazy, eval could actually only shallowly evaluate a value - which it used to in very old Nickel. However, we thought that it's not a very useful feature for the user, to evaluate a file very shallowly - if you're interested in the values, you don't get them (it stops at the first data structure like a record or an array and doesn't evaluate the content), and if you're interested in knowing if the source file doesn't contain runtime errors, it's also not very useful because most of the actual content won't be evaluated. So we decided to make nickel eval perform deep evaluation, similarly to nickel export.

I think my question would be: what would you expect to get when evaluating something like a schema? Is that a useful operation to do?

yannham commented 1 month ago

I'll close for now, as there issue isn't very clear and there's no actionable fix. Feel free to re-open later if needed.