From 1908ff41c3cc332fb2355444ef6011496e2dd675 Mon Sep 17 00:00:00 2001 From: Kevin Gillette Date: Fri, 15 Apr 2022 00:04:38 -0600 Subject: [PATCH] rem, sqrt, log are unchecked but have checked variants mod exists but is not implemented due to lack of hardware support (emulation, possibly in terms of rem, is needed). --- compiler/builtins/docs/Num.roc | 9 ++- compiler/builtins/roc/Num.roc | 23 +++--- compiler/builtins/src/std.rs | 45 ++++++++---- compiler/can/src/builtins.rs | 107 +++++++++++++++++++++++++++- compiler/gen_llvm/src/llvm/build.rs | 12 ++-- compiler/gen_wasm/src/low_level.rs | 5 ++ compiler/module/src/low_level.rs | 12 +++- compiler/module/src/symbol.rs | 4 +- compiler/mono/src/borrow.rs | 7 +- compiler/mono/src/low_level.rs | 1 + compiler/test_gen/src/gen_list.rs | 4 +- compiler/test_gen/src/gen_num.rs | 37 +++++----- examples/benchmarks/Deriv.roc | 2 +- examples/benchmarks/RBTreeCk.roc | 13 +--- repl_test/src/tests.rs | 2 +- 15 files changed, 208 insertions(+), 75 deletions(-) diff --git a/compiler/builtins/docs/Num.roc b/compiler/builtins/docs/Num.roc index 2f45e22600..e33a7eda94 100644 --- a/compiler/builtins/docs/Num.roc +++ b/compiler/builtins/docs/Num.roc @@ -61,6 +61,7 @@ interface Num isPositive, isZero, log, + logChecked, maxFloat, maxI8, maxU8, @@ -81,8 +82,8 @@ interface Num minI64, minU64, minI128, - modInt, - modFloat, + mod, + modChecked, mul, mulChecked, mulWrap, @@ -90,6 +91,7 @@ interface Num pow, powInt, rem, + remChecked, round, shiftLeftBy, shiftRightBy, @@ -99,6 +101,7 @@ interface Num subChecked, subWrap, sqrt, + sqrtChecked, tan, toI8, toI8Checked, @@ -1316,7 +1319,7 @@ isInfinite : Float * -> Bool ## ## >>> Num.isNaN 12.3 ## -## >>> Num.isNaN (Num.sqrt -2) +## >>> Num.isNaN (Num.pow -1 0.5) ## ## *NaN* is unusual from other numberic values in that: ## * *NaN* is not equal to any other number, even itself. [Bool.isEq] always returns `False` if either argument is *NaN*. diff --git a/compiler/builtins/roc/Num.roc b/compiler/builtins/roc/Num.roc index 3038842caa..3a56f282f1 100644 --- a/compiler/builtins/roc/Num.roc +++ b/compiler/builtins/roc/Num.roc @@ -68,12 +68,15 @@ interface Num isPositive, isNegative, rem, + remChecked, div, divChecked, - modInt, - modFloat, + mod, + modChecked, sqrt, + sqrtChecked, log, + logChecked, round, ceiling, floor, @@ -230,19 +233,23 @@ asin : Float a -> Float a acos : Float a -> Float a atan : Float a -> Float a -sqrt : Float a -> Result (Float a) [ SqrtOfNegative ]* -log : Float a -> Result (Float a) [ LogNeedsPositive ]* +sqrt : Float a -> Float a +sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]* +log : Float a -> Float a +logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]* + div : Float a, Float a -> Float a divChecked : Float a, Float a -> Result (Float a) [ DivByZero ]* - divCeil : Int a, Int a -> Int a divCeilChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* divFloor : Int a, Int a -> Int a divFloorChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* -# mod : Float a, Float a -> Result (Float a) [ DivByZero ]* -rem : Int a, Int a -> Result (Int a) [ DivByZero ]* -# mod : Int a, Int a -> Result (Int a) [ DivByZero ]* +rem : Int a, Int a -> Int a +remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* +mod : Int a, Int a -> Int a +modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* + isMultipleOf : Int a, Int a -> Bool bitwiseAnd : Int a, Int a -> Int a diff --git a/compiler/builtins/src/std.rs b/compiler/builtins/src/std.rs index cc0fd16ef0..111523e170 100644 --- a/compiler/builtins/src/std.rs +++ b/compiler/builtins/src/std.rs @@ -393,16 +393,30 @@ pub fn types() -> MutMap { Box::new(int_type(flex(TVAR2))) ); - // rem : Int a, Int a -> Result (Int a) [ DivByZero ]* + // rem : Int a, Int a -> Int a add_top_level_function_type!( Symbol::NUM_REM, vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), + ); + + // remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* + add_top_level_function_type!( + Symbol::NUM_REM_CHECKED, + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), ); - // mod : Int a, Int a -> Result (Int a) [ DivByZero ]* + // mod : Int a, Int a -> Int a add_top_level_function_type!( - Symbol::NUM_MOD_INT, + Symbol::NUM_MOD, + vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], + Box::new(int_type(flex(TVAR1))), + ); + + // modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* + add_top_level_function_type!( + Symbol::NUM_MOD_CHECKED, vec![int_type(flex(TVAR1)), int_type(flex(TVAR1))], Box::new(result_type(int_type(flex(TVAR1)), div_by_zero.clone())), ); @@ -680,36 +694,43 @@ pub fn types() -> MutMap { add_top_level_function_type!( Symbol::NUM_DIV_FLOAT_CHECKED, vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], - Box::new(result_type(float_type(flex(TVAR1)), div_by_zero.clone())), - ); - - // mod : Float a, Float a -> Result (Float a) [ DivByZero ]* - add_top_level_function_type!( - Symbol::NUM_MOD_FLOAT, - vec![float_type(flex(TVAR1)), float_type(flex(TVAR1))], Box::new(result_type(float_type(flex(TVAR1)), div_by_zero)), ); // sqrt : Float a -> Float a + add_top_level_function_type!( + Symbol::NUM_SQRT, + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), + ); + + // sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]* let sqrt_of_negative = SolvedType::TagUnion( vec![(TagName::Global("SqrtOfNegative".into()), vec![])], Box::new(SolvedType::Wildcard), ); add_top_level_function_type!( - Symbol::NUM_SQRT, + Symbol::NUM_SQRT_CHECKED, vec![float_type(flex(TVAR1))], Box::new(result_type(float_type(flex(TVAR1)), sqrt_of_negative)), ); // log : Float a -> Float a + add_top_level_function_type!( + Symbol::NUM_LOG, + vec![float_type(flex(TVAR1))], + Box::new(float_type(flex(TVAR1))), + ); + + // logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]* let log_needs_positive = SolvedType::TagUnion( vec![(TagName::Global("LogNeedsPositive".into()), vec![])], Box::new(SolvedType::Wildcard), ); add_top_level_function_type!( - Symbol::NUM_LOG, + Symbol::NUM_LOG_CHECKED, vec![float_type(flex(TVAR1))], Box::new(result_type(float_type(flex(TVAR1)), log_needs_positive)), ); diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index d194966b8b..b715d983e1 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -203,9 +203,14 @@ pub fn builtin_defs_map(symbol: Symbol, var_store: &mut VarStore) -> Option NUM_ABS => num_abs, NUM_NEG => num_neg, NUM_REM => num_rem, + NUM_REM_CHECKED => num_rem_checked, + NUM_MOD => num_mod, + NUM_MOD_CHECKED => num_mod_checked, NUM_IS_MULTIPLE_OF => num_is_multiple_of, NUM_SQRT => num_sqrt, + NUM_SQRT_CHECKED => num_sqrt_checked, NUM_LOG => num_log, + NUM_LOG_CHECKED => num_log_checked, NUM_ROUND => num_round, NUM_IS_ODD => num_is_odd, NUM_IS_EVEN => num_is_even, @@ -730,6 +735,23 @@ fn bool_and(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } +fn num_unaryop(symbol: Symbol, var_store: &mut VarStore, op: LowLevel) -> Def { + let num_var = var_store.fresh(); + let body = RunLowLevel { + op, + args: vec![(num_var, Var(Symbol::ARG_1))], + ret_var: num_var, + }; + + defn( + symbol, + vec![(num_var, Symbol::ARG_1)], + var_store, + body, + num_var, + ) +} + /// Num a, Num a -> Num a fn num_binop(symbol: Symbol, var_store: &mut VarStore, op: LowLevel) -> Def { let num_var = var_store.fresh(); @@ -1169,8 +1191,13 @@ fn num_to_float(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.sqrt : Float -> Result Float [ SqrtOfNegative ]* +/// Num.sqrt : Float a -> Float a fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def { + num_unaryop(symbol, var_store, LowLevel::NumSqrtUnchecked) +} + +/// Num.sqrtChecked : Float a -> Result (Float a) [ SqrtOfNegative ]* +fn num_sqrt_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { let bool_var = var_store.fresh(); let float_var = var_store.fresh(); let unbound_zero_var = var_store.fresh(); @@ -1218,8 +1245,13 @@ fn num_sqrt(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.log : Float -> Result Float [ LogNeedsPositive ]* +/// Num.log : Float a -> Float a fn num_log(symbol: Symbol, var_store: &mut VarStore) -> Def { + num_unaryop(symbol, var_store, LowLevel::NumLogUnchecked) +} + +/// Num.logChecked : Float a -> Result (Float a) [ LogNeedsPositive ]* +fn num_log_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { let bool_var = var_store.fresh(); let float_var = var_store.fresh(); let unbound_zero_var = var_store.fresh(); @@ -4196,8 +4228,13 @@ fn set_walk(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } -/// Num.rem : Int a, Int a -> Result (Int a) [ DivByZero ]* +/// Num.rem : Int a, Int a -> Int a fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def { + num_binop(symbol, var_store, LowLevel::NumRemUnchecked) +} + +/// Num.remChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* +fn num_rem_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { let num_var = var_store.fresh(); let unbound_zero_var = var_store.fresh(); let bool_var = var_store.fresh(); @@ -4255,6 +4292,70 @@ fn num_rem(symbol: Symbol, var_store: &mut VarStore) -> Def { ) } +/// Num.mod : Int a, Int a -> Int a +fn num_mod(symbol: Symbol, var_store: &mut VarStore) -> Def { + num_binop(symbol, var_store, LowLevel::NumModUnchecked) +} + +/// Num.modChecked : Int a, Int a -> Result (Int a) [ DivByZero ]* +fn num_mod_checked(symbol: Symbol, var_store: &mut VarStore) -> Def { + let num_var = var_store.fresh(); + let unbound_zero_var = var_store.fresh(); + let bool_var = var_store.fresh(); + let ret_var = var_store.fresh(); + + let body = If { + branch_var: ret_var, + cond_var: bool_var, + branches: vec![( + // if condition + no_region( + // Num.isNeq arg2 0 + RunLowLevel { + op: LowLevel::NotEq, + args: vec![ + (num_var, Var(Symbol::ARG_2)), + (num_var, num(unbound_zero_var, 0, num_no_bound())), + ], + ret_var: bool_var, + }, + ), + // arg1 was not zero + no_region( + // Ok (Int.#modUnsafe arg1 arg2) + tag( + "Ok", + vec![ + // Num.#modUnsafe arg1 arg2 + RunLowLevel { + op: LowLevel::NumModUnchecked, + args: vec![ + (num_var, Var(Symbol::ARG_1)), + (num_var, Var(Symbol::ARG_2)), + ], + ret_var: num_var, + }, + ], + var_store, + ), + ), + )], + final_else: Box::new(no_region(tag( + "Err", + vec![tag("DivByZero", Vec::new(), var_store)], + var_store, + ))), + }; + + defn( + symbol, + vec![(num_var, Symbol::ARG_1), (num_var, Symbol::ARG_2)], + var_store, + body, + ret_var, + ) +} + /// Num.isMultipleOf : Int a, Int a -> Bool fn num_is_multiple_of(symbol: Symbol, var_store: &mut VarStore) -> Def { lowlevel_2(symbol, LowLevel::NumIsMultipleOf, var_store) diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index d80b48dfea..d147da254b 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -5814,9 +5814,9 @@ fn run_low_level<'a, 'ctx, 'env>( } NumAdd | NumSub | NumMul | NumLt | NumLte | NumGt | NumGte | NumRemUnchecked - | NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated | NumDivUnchecked - | NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap | NumSubChecked - | NumSubSaturated | NumMulWrap | NumMulChecked => { + | NumModUnchecked | NumIsMultipleOf | NumAddWrap | NumAddChecked | NumAddSaturated + | NumDivUnchecked | NumDivCeilUnchecked | NumPow | NumPowInt | NumSubWrap + | NumSubChecked | NumSubSaturated | NumMulWrap | NumMulChecked => { debug_assert_eq!(args.len(), 2); let (lhs_arg, lhs_layout) = load_symbol_and_layout(scope, &args[0]); @@ -6578,6 +6578,11 @@ fn build_int_binop<'a, 'ctx, 'env>( bd.build_int_unsigned_rem(lhs, rhs, "rem_uint").into() } } + NumModUnchecked => { + // there generally is not hardware support for flooring mod; + // it could probably be implemented in pure Roc in terms of Num.rem. + todo!("mod is not implemented") + } NumIsMultipleOf => { // this builds the following construct // @@ -6908,7 +6913,6 @@ fn build_float_binop<'a, 'ctx, 'env>( NumGte => bd.build_float_compare(OGE, lhs, rhs, "float_gte").into(), NumLt => bd.build_float_compare(OLT, lhs, rhs, "float_lt").into(), NumLte => bd.build_float_compare(OLE, lhs, rhs, "float_lte").into(), - NumRemUnchecked => bd.build_float_rem(lhs, rhs, "rem_float").into(), NumDivUnchecked => bd.build_float_div(lhs, rhs, "div_float").into(), NumPow => env.call_intrinsic(&LLVM_POW[float_width], &[lhs.into(), rhs.into()]), _ => { diff --git a/compiler/gen_wasm/src/low_level.rs b/compiler/gen_wasm/src/low_level.rs index b376f613b5..f3b3b2b180 100644 --- a/compiler/gen_wasm/src/low_level.rs +++ b/compiler/gen_wasm/src/low_level.rs @@ -434,6 +434,11 @@ impl<'a> LowLevelCall<'a> { _ => todo!("{:?} for {:?}", self.lowlevel, self.ret_layout), } } + NumModUnchecked => { + // wasm does not provide a flooring modulo instruction, + // so it would need to be emulated. + todo!("{:?}", self.lowlevel) + } NumIsMultipleOf => todo!("{:?}", self.lowlevel), NumAbs => { self.load_args(backend); diff --git a/compiler/module/src/low_level.rs b/compiler/module/src/low_level.rs index ef888bc878..12fc990851 100644 --- a/compiler/module/src/low_level.rs +++ b/compiler/module/src/low_level.rs @@ -85,6 +85,7 @@ pub enum LowLevel { NumDivUnchecked, NumDivCeilUnchecked, NumRemUnchecked, + NumModUnchecked, NumIsMultipleOf, NumAbs, NumNeg, @@ -293,14 +294,19 @@ impl LowLevelWrapperType { Symbol::NUM_DIV_FLOAT_CHECKED => WrapperIsRequired, Symbol::NUM_DIV_CEIL => CanBeReplacedBy(NumDivCeilUnchecked), Symbol::NUM_DIV_CEIL_CHECKED => WrapperIsRequired, - Symbol::NUM_REM => WrapperIsRequired, + Symbol::NUM_REM => CanBeReplacedBy(NumRemUnchecked), + Symbol::NUM_REM_CHECKED => WrapperIsRequired, + Symbol::NUM_MOD => CanBeReplacedBy(NumModUnchecked), + Symbol::NUM_MOD_CHECKED => WrapperIsRequired, Symbol::NUM_IS_MULTIPLE_OF => CanBeReplacedBy(NumIsMultipleOf), Symbol::NUM_ABS => CanBeReplacedBy(NumAbs), Symbol::NUM_NEG => CanBeReplacedBy(NumNeg), Symbol::NUM_SIN => CanBeReplacedBy(NumSin), Symbol::NUM_COS => CanBeReplacedBy(NumCos), - Symbol::NUM_SQRT => WrapperIsRequired, - Symbol::NUM_LOG => WrapperIsRequired, + Symbol::NUM_SQRT => CanBeReplacedBy(NumSqrtUnchecked), + Symbol::NUM_SQRT_CHECKED => WrapperIsRequired, + Symbol::NUM_LOG => CanBeReplacedBy(NumLogUnchecked), + Symbol::NUM_LOG_CHECKED => WrapperIsRequired, Symbol::NUM_ROUND => CanBeReplacedBy(NumRound), Symbol::NUM_TO_FLOAT => CanBeReplacedBy(NumToFloat), Symbol::NUM_POW => CanBeReplacedBy(NumPow), diff --git a/compiler/module/src/symbol.rs b/compiler/module/src/symbol.rs index 5be160e1d8..067e4b01a0 100644 --- a/compiler/module/src/symbol.rs +++ b/compiler/module/src/symbol.rs @@ -950,8 +950,8 @@ define_builtins! { 41 NUM_DIV_FLOAT_CHECKED: "divChecked" 42 NUM_DIV_FLOOR: "divFloor" 43 NUM_DIV_FLOOR_CHECKED: "divFloorChecked" - 44 NUM_MOD_INT: "modInt" - 45 NUM_MOD_INT_CHECKED: "modIntChecked" + 44 NUM_MOD: "mod" + 45 NUM_MOD_CHECKED: "modChecked" 46 NUM_MOD_FLOAT: "modFloat" 47 NUM_MOD_FLOAT_CHECKED: "modFloatChecked" 48 NUM_SQRT: "sqrt" diff --git a/compiler/mono/src/borrow.rs b/compiler/mono/src/borrow.rs index 7fd09d0bfc..8174ca8918 100644 --- a/compiler/mono/src/borrow.rs +++ b/compiler/mono/src/borrow.rs @@ -994,10 +994,9 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] { And | Or | NumAdd | NumAddWrap | NumAddChecked | NumAddSaturated | NumSub | NumSubWrap | NumSubChecked | NumSubSaturated | NumMul | NumMulWrap | NumMulChecked | NumGt | NumGte | NumLt | NumLte | NumCompare | NumDivUnchecked | NumDivCeilUnchecked - | NumRemUnchecked | NumIsMultipleOf | NumPow | NumPowInt | NumBitwiseAnd - | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy | NumShiftRightZfBy => { - arena.alloc_slice_copy(&[irrelevant, irrelevant]) - } + | NumRemUnchecked | NumModUnchecked | NumIsMultipleOf | NumPow | NumPowInt + | NumBitwiseAnd | NumBitwiseXor | NumBitwiseOr | NumShiftLeftBy | NumShiftRightBy + | NumShiftRightZfBy => arena.alloc_slice_copy(&[irrelevant, irrelevant]), NumToStr | NumAbs | NumNeg | NumSin | NumCos | NumSqrtUnchecked | NumLogUnchecked | NumRound | NumCeiling | NumFloor | NumToFloat | Not | NumIsFinite | NumAtan | NumAcos diff --git a/compiler/mono/src/low_level.rs b/compiler/mono/src/low_level.rs index 03092a25cb..5dc37091df 100644 --- a/compiler/mono/src/low_level.rs +++ b/compiler/mono/src/low_level.rs @@ -144,6 +144,7 @@ enum FirstOrder { NumCompare, NumDivUnchecked, NumRemUnchecked, + NumModUnchecked, NumIsMultipleOf, NumAbs, NumNeg, diff --git a/compiler/test_gen/src/gen_list.rs b/compiler/test_gen/src/gen_list.rs index cb46f2de49..517e3d9c58 100644 --- a/compiler/test_gen/src/gen_list.rs +++ b/compiler/test_gen/src/gen_list.rs @@ -2534,7 +2534,7 @@ fn list_keep_oks() { RocList ); assert_evals_to!( - "List.keepOks [1,2] (\\x -> x % 2)", + "List.keepOks [1,2] (\\x -> Num.remChecked x 2)", RocList::from_slice(&[1, 0]), RocList ); @@ -2561,7 +2561,7 @@ fn list_keep_errs() { assert_evals_to!( indoc!( r#" - List.keepErrs [0,1,2] (\x -> x % 0 |> Result.mapErr (\_ -> 32)) + List.keepErrs [0,1,2] (\x -> Num.remChecked x 0 |> Result.mapErr (\_ -> 32)) "# ), RocList::from_slice(&[32, 32, 32]), diff --git a/compiler/test_gen/src/gen_num.rs b/compiler/test_gen/src/gen_num.rs index 88480c6310..ac089cdc9d 100644 --- a/compiler/test_gen/src/gen_num.rs +++ b/compiler/test_gen/src/gen_num.rs @@ -473,7 +473,7 @@ fn f64_sqrt() { assert_evals_to!( indoc!( r#" - when Num.sqrt 100 is + when Num.sqrtChecked 100 is Ok val -> val Err _ -> -1 "# @@ -489,9 +489,7 @@ fn f64_log() { assert_evals_to!( indoc!( r#" - when Num.log 7.38905609893 is - Ok val -> val - Err _ -> -1 + Num.log 7.38905609893 "# ), 1.999999999999912, @@ -501,11 +499,11 @@ fn f64_log() { #[test] #[cfg(any(feature = "gen-llvm"))] -fn f64_log_one() { +fn f64_log_checked_one() { assert_evals_to!( indoc!( r#" - when Num.log 1 is + when Num.logChecked 1 is Ok val -> val Err _ -> -1 "# @@ -521,7 +519,7 @@ fn f64_sqrt_zero() { assert_evals_to!( indoc!( r#" - when Num.sqrt 0 is + when Num.sqrtChecked 0 is Ok val -> val Err _ -> -1 "# @@ -533,11 +531,11 @@ fn f64_sqrt_zero() { #[test] #[cfg(any(feature = "gen-llvm"))] -fn f64_sqrt_negative() { +fn f64_sqrt_checked_negative() { assert_evals_to!( indoc!( r#" - when Num.sqrt -1 is + when Num.sqrtChecked -1 is Err _ -> 42 Ok val -> val "# @@ -549,11 +547,11 @@ fn f64_sqrt_negative() { #[test] #[cfg(any(feature = "gen-llvm"))] -fn f64_log_zero() { +fn f64_log_checked_zero() { assert_evals_to!( indoc!( r#" - when Num.log 0 is + when Num.logChecked 0 is Err _ -> 42 Ok val -> val "# @@ -569,13 +567,12 @@ fn f64_log_negative() { assert_evals_to!( indoc!( r#" - when Num.log -1 is - Err _ -> 42 - Ok val -> val + Num.log -1 "# ), - 42.0, - f64 + true, + f64, + |f: f64| f.is_nan() ); } @@ -1082,9 +1079,7 @@ fn gen_rem_i64() { assert_evals_to!( indoc!( r#" - when Num.rem 8 3 is - Ok val -> val - Err _ -> -1 + Num.rem 8 3 "# ), 2, @@ -1094,11 +1089,11 @@ fn gen_rem_i64() { #[test] #[cfg(any(feature = "gen-llvm"))] -fn gen_rem_div_by_zero_i64() { +fn gen_rem_checked_div_by_zero_i64() { assert_evals_to!( indoc!( r#" - when Num.rem 8 0 is + when Num.remChecked 8 0 is Err DivByZero -> 4 Ok _ -> -23 "# diff --git a/examples/benchmarks/Deriv.roc b/examples/benchmarks/Deriv.roc index caf08906a6..90e641cb0f 100644 --- a/examples/benchmarks/Deriv.roc +++ b/examples/benchmarks/Deriv.roc @@ -41,7 +41,7 @@ Expr : [ Val I64, Var Str, Add Expr Expr, Mul Expr Expr, Pow Expr Expr, Ln Expr divmod : I64, I64 -> Result { div : I64, mod : I64 } [ DivByZero ]* divmod = \l, r -> - when Pair (l // r) (l % r) is + when Pair (Num.divFloorChecked l r) (Num.remChecked l r) is Pair div (Ok mod) -> Ok { div, mod } diff --git a/examples/benchmarks/RBTreeCk.roc b/examples/benchmarks/RBTreeCk.roc index 225df33161..90c6fb3d4f 100644 --- a/examples/benchmarks/RBTreeCk.roc +++ b/examples/benchmarks/RBTreeCk.roc @@ -23,12 +23,12 @@ makeMapHelp = \freq, n, m, acc -> _ -> powerOf10 = - (n % 10 |> resultWithDefault 0) == 0 + n % 10 == 0 m1 = insert m n powerOf10 isFrequency = - (n % freq |> resultWithDefault 0) == 0 + n % freq == 0 x = (if isFrequency then Cons m1 acc else acc) @@ -43,15 +43,6 @@ fold = \f, tree, b -> Node _ l k v r -> fold f r (f k v (fold f l b)) -resultWithDefault : Result a e, a -> a -resultWithDefault = \res, default -> - when res is - Ok v -> - v - - Err _ -> - default - main : Task.Task {} [] main = Task.after diff --git a/repl_test/src/tests.rs b/repl_test/src/tests.rs index 9f46137f38..9480cbce91 100644 --- a/repl_test/src/tests.rs +++ b/repl_test/src/tests.rs @@ -56,7 +56,7 @@ fn float_addition() { #[cfg(not(feature = "wasm"))] #[test] fn num_rem() { - expect_success("299 % 10", "Ok 9 : Result (Int *) [ DivByZero ]*"); + expect_success("299 % 10", "9 : Int *"); } #[cfg(not(feature = "wasm"))]