aeternity / aesophia

Stand alone compiler for the Sophia smart contract language
https://docs.aeternity.com/aesophia
ISC License
52 stars 19 forks source link

Unclear error if a cycle dependency between namespaces #444

Open davidyuk opened 1 year ago

davidyuk commented 1 year ago

Reproduction

├── Includes.aes
└── lib
    ├── Library.aes
    └── Sublibrary.aes

Includes.aes

include "./lib/Library.aes"

contract Includes =
    entrypoint test(x: int): int = Library.sum(x, 4)

Library.aes

include "./lib/Sublibrary.aes"

namespace Library =
  type number = int
  function sum(x: int, y: int): int = Sublibrary.sum(x, y)

Sublibrary.aes

include "./lib/Library.aes"

namespace Sublibrary =
  function sum(x: int, y: int): int = x + y
  function return42(): Library.number = 42

CLI prints an unclear error

$ aesophia_cli ./Includes.aes
Type error in 'lib/Sublibrary.aes' at line 5, col 24:
Unbound type Library.number.

Type error in 'lib/Sublibrary.aes' at line 5, col 41:
Cannot unify `int` and `Library.number`
when checking the type of the expression `42 : int` against the expected type `Library.number`
$ aesophia_cli --version     
Sophia compiler version 7.0.1

it works if I include number from another namespace (without cycle deps). Sophia should disallow cycle dependencies explicitly or the above reproduction should work.

ghallak commented 1 year ago

First, this has nothing to do with includes. You can put the namespaces in the same file and it will still not work.

The error is produced because a namespace can only recognize what was written before it, so if you want to have a base namespace and a dependent namespace, you should have them in order.

namespace Base =
    ...

namespace Dependent =
    ...

Is there a specific situation where you need 2 namespaces to depend on each other, and you're not better off refactoring the code?

I would say that it's better to keep it this way in order to prevent messy designs, and the error messages are clear enough once you know that a namespace can only recognize what's written before it.

@radrow Do you have any opinion on this?

radrow commented 1 year ago

I think it would be much more user friendly if we explicitly point out that dependency cycles are not supported. For example functions within one namespace do support mutual recursion, so I can imagine this being confusing.