mojo icon indicating copy to clipboard operation
mojo copied to clipboard

[Feature Request] Compare a type with other types

Open survuvi opened this issue 1 year ago • 6 comments

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]

survuvi avatar May 23 '23 15:05 survuvi

Are you suggesting that we add elementwise comparators to our list type? Our list type isn't super-functional at the moment.

Mogball avatar May 23 '23 15:05 Mogball

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 avatar May 23 '23 17:05 DayDun

@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)

survuvi avatar May 23 '23 18:05 survuvi

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.

DayDun avatar May 23 '23 18:05 DayDun

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])

ekinimo avatar May 23 '23 18:05 ekinimo

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.

lsh avatar May 24 '23 05:05 lsh