lcompilers / lpython

Python compiler
https://lpython.org/
Other
1.37k stars 157 forks source link

Improve comparison of dissimilar types #2591

Closed kmr-srbh closed 3 months ago

kmr-srbh commented 4 months ago

Fixes #2593

Comparison on dissimilar types can be handled the way CPython does - return True when comparing for inequality and False when comparing for equality. Throw a semantic error when using >, >=, < and <=.

On main branch

Checking equality

integer: i32 = 1
integer_list: list[i32] = [1, 2, 3, 4, 5]
print(integer == integer_list)
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
semantic error: Type mismatch in comparison operator, the types must be compatible
 --> ./examples/example.py:5:7
  |
5 | print(integer == integer_list)
  |       ^^^^^^^    ^^^^^^^^^^^^ type mismatch ('i32' and 'list[i32]')

Note: Please report unclear or confusing messages as bugs at
https://github.com/lcompilers/lpython/issues.

Similar error is thrown for other operators.

On local branch

Checking equality

integer: i32 = 1
integer_list: list[i32] = [1, 2, 3, 4, 5]
print(integer == integer_list)
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
False

Checking inequality

integer: i32 = 1
integer_list: list[i32] = [1, 2, 3, 4, 5]
print(integer != integer_list)
(base) saurabh-kumar@Awadh:~/Projects/System/lpython$ ./src/bin/lpython ./examples/example.py
True

Checking greater than or equal to (>=) [similar for other operators]

integer: i32 = 1
integer_list: list[i32] = [1, 2, 3, 4, 5]
print(integer >= integer_list)
semantic error: Comparison operator not supported between instances of 'i32' and 'list[i32]'
 --> ./examples/example.py:5:7
  |
5 | print(integer >= integer_list)
  |       ^^^^^^^^^^^^^^^^^^^^^^^ 

Note: Please report unclear or confusing messages as bugs at
https://github.com/lcompilers/lpython/issues.
kmr-srbh commented 4 months ago

The failing tests are those which checked for the semantic error before. I am pushing new tests.

kmr-srbh commented 4 months ago

@certik In CPython 1 == 1.0 returns True as the value is the same. Should we do something similar, or is it okay to throw an error?

Shaikh-Ubaid commented 4 months ago

@certik In CPython 1 == 1.0 returns True as the value is the same. Should we do something similar, or is it okay to throw an error?

We currently throw an error because LPython has strict type checking and does not do implicit casting. The design of LPython is such that everything has to be explicitly casted by the user.

Shaikh-Ubaid commented 4 months ago

I feel this PR is not needed at this moment in LPython. I am temporarily marking this as draft.

Shaikh-Ubaid commented 3 months ago

Let's close this PR for now. We can reopen later if needed.