abreis edited a comment on pull request #9454: URL: https://github.com/apache/arrow/pull/9454#issuecomment-778208765
> @abreis , I am not convinced that that is sufficient, unfortunately, because it excludes all types that are not Numeric (i.e. all dates and times for primitives, as well as all other logical types). > > We could of course offer a `DatumTemporal` and a `DatumList` and so one and so forth, but IMO that is introducing more complexity, as we now start having `struct`s for all kinds of logical types. I agree. I just realized that `ArrowPrimitiveType` exists though, so Datum can be generic over that instead. Here is a more fleshed-out mock of a Datum type. The signature of `math_divide` enforces a consistent `T` over array/array and array/scalar combinations, and the method's output. Base type: ```rust #[derive(Debug)] pub enum Datum<'a, T> where T: ArrowPrimitiveType, { Array(&'a PrimitiveArray<T>), Scalar(Option<T::Native>), } ``` `From` impls for both arrays and nullable scalars: ```rust impl<'a, T> From<&'a PrimitiveArray<T>> for Datum<'a, T> where T: ArrowPrimitiveType, { fn from(array: &'a PrimitiveArray<T>) -> Self { Datum::Array(array) } } impl<'a, T> From<Option<T::Native>> for Datum<'a, T> where T: ArrowPrimitiveType, { fn from(scalar: Option<T::Native>) -> Self { Datum::Scalar(scalar) } } ``` A (user-facing) method for math division: ```rust pub fn math_divide<'a1, 'a2, T, DL, DR>( left: DL, right: DR, ) -> Result<PrimitiveArray<T>> where T: ArrowNumericType, T::Native: Div<Output = T::Native> + Zero, DL: Into<Datum<'a1, T>>, // left and right may have different lifetimes DR: Into<Datum<'a2, T>>, // but `T` must be the same { use Datum::*; match (left.into(), right.into()) { (Array(left), Array(right)) => todo!(), // array/array (Array(array), Scalar(divisor)) => todo!(), // array/scalar _ => todo!(), } } ``` Test code: ```rust fn test_datum_divide() { let array1 = Int32Array::from(vec![15, 15, 8, 1, 9]); let array2 = Int32Array::from(vec![5, 6, 8, 9, 1]); let scalar = Some(8i32); let a_over_a = math_divide(&array1, &array2).unwrap(); // works let a_over_s = math_divide(&array1, scalar).unwrap(); // also works } ``` @jorgecarleitao I'm aware this doesn't address the second half of your comment. I'm just exploring this idea for the current version of arrow. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org