mojo
mojo copied to clipboard
[Feature Request] Compare a type with other types
Request
Compare a type with another type
Motivation
A functionality that Python does not have without libraries like NumPy.
Description and Requirements
Could be useful, for example, to compare a single number with an array:
print(5 < [1,3,7])
# The output sholud be: [False, False, True]
Are you suggesting that we add elementwise comparators to our list type? Our list type isn't super-functional at the moment.
I personally prefer quite strict type safety. It feels like a feature like this added to the default list type would more often be used on accident than on purpose, which could lead to silent bugs. I definitely wouldn't mind having a more explicit type with this functionality though, such as 5 < ListPairwise(1, 3, 7)
or something.
You can also do this with SIMD today already. Not that SIMD is what you want to use in general for pairwise list operations.
from DType import DType
print(SIMD[DType.ui32, 4](1, 3, 7, 5) > 5)
@DayDun why if we extend the vector to 5 elements or we reduce it to 3 elements, we get errors?
from DType import DType
print(SIMD[DType.ui32, 5](1, 3, 7, 5, 8) > 5)
_error: Expression [15]:9:1: no viable expansions found fn lldb_expr(inout __mojo_repl_arg: mojo_repl_context): ^
Expression [15]:11:28: call expansion failed
mojo_repl_expr_impl(__mojo_repl_arg, __get_address_as_lvalue(__mojo_repl_arg.np
.load().address), __get_address_as_lvalue(__mojo_repl_arg.a
.load().address), __get_address_as_lvalue(__mojo_repl_arg.result
.load().address))
^
Expression [15]:15:1: no viable expansions found
def mojo_repl_expr_impl(inout __mojo_repl_arg: mojo_repl_context, inout np
: __mlir_type.!kgen.declref<@"$PythonObject"::@PythonObject>
, inout a
: __mlir_type.!kgen.declref<@"$PythonObject"::@PythonObject>
, inout result
: __mlir_type.!kgen.declref<@"$PythonObject"::@PythonObject>
) -> None:
^
Expression [15]:22:26: call expansion failed mojo_repl_expr_body() ^
Expression [15]:17:3: no viable expansions found def mojo_repl_expr_body() -> None: ^
Expression [15]:19:30: call expansion failed print(SIMD[DType.ui32, 5](1, 3, 7, 5, 8) > 5) ^
/.modular/Kernels/mojo/Stdlib/SIMD.mojo:19:1: no viable expansions found fn _simd_construction_checkssize: Int: ^
/.modular/Kernels/mojo/Stdlib/SIMD.mojo:28:75: constraint failed: simd width must be power of 2 assert_param_msgis_power_of_2(size), "simd width must be power of 2"_
However we can do the same using numpy:
from PythonInterface import Python
# This is equivalent to Python's `import numpy as np`
let np = Python.import_module("numpy")
# Now use numpy like Python
let a = np.array([1, 3, 7, 5])
# Compare the number to the array
result = a > 5
print(result)
Because as I said, SIMD is not what you want to use in general for pairwise list operations. SIMD is a low level CPU optimization, and only supports lengths that are a power of two.
julias dot syntax is cool for such stuff its quite handy especially in conjunction with pipe (|>). Its way cleaner imho. That being said im totally fine with having inline closures and higher order functions like map , than you can simply write
print(map( lambda x: x < 5, [1,3,7])
Another interesting way to consider this request is less about type comparison and more a request for first class rank polymorphism. There is precedent in numpy for this behavior.