On Sun, May 21, 2017 at 05:14:02PM +0200, lemonboy wrote: > Hi Peter, > I expect the `fxX?` procedures as 1:1 replacements of the standard > `fxN` ones with the > only exception being the way the overflow is handled. > The point where the two diverge is the handling of the input > parameters: while the latter > follow the garbage-in garbage-out philosophy the former takes a > "stricter" approach and > rejects the non-fixnum arguments by returning `#f`. > I think that's the by-product of a lax check on the input parameters > rather than a design > decision and even though this check works just fine in practice there > are some drawbacks: > - We can't give to their arguments the type `(or fixnum false)`, this > means we can't possibly > warn the user if they pass the wrong argument (the standard > procedures allow this);
I don't really care that much about this, so unless others have similar concerns I think we can apply this change. However, they shouldn't be #:enforce; they don't raise an error when their types are fixnum or false, which is what enforce means: if the code goes beyond this expression, you may assume the input types are correct. I believe these procedures can be marked #:pure, though, since they don't have *any* side effects (except for fx/?, since it will raise an exception when dividing by zero). Speaking of which: can't all the other fixnum-specific procedures be pure as well? Except for fx/, of course. > - There's no way to distinguish the result of `(fx+? 'foo 3)` from the > result of an > overflowing calculation, couple it with the lack of any warning and > you're in for a nice bug > hunt. Speaking of strange bugs, I'm wondering whether these fixnum procedures should be foldable at all (that also goes for the procedures that are already in types.db). Consider the case where you're compiling on a 64-bit machine. The compiler folds the fixnum operations at compile-time, resulting in a fixnum. However, if the fixnum is not representable as a fixnum on the target computer, it will be represented as a bignum (or on CHICKEN 4, as a flonum). This not only produces a different answer than when the same code would be compiled on the 32-bit machine and in the interpreter, but it also may trigger other unexpected behaviour resulting from a mismatch of the expectation that you're dealing with fixnums only. For example, a specialised unsafe version of a generic procedure might end up being specialised for fixnums, but on a 32-bit platform it might still receive a bignum (or a flonum on master). Hm, I wonder if this stuff causes other problems as well... Anyway, attached is a signed-off version of your patch without the #:enforce and with the #:pure annotations, and a second patch which removes #:foldable from the other fixnum operations too. Cheers, Peter
From 2af71bd754ee57249e3f445e9d199de152f5147e Mon Sep 17 00:00:00 2001 From: LemonBoy <thatle...@gmail.com> Date: Fri, 19 May 2017 22:45:28 +0200 Subject: [PATCH 1/2] Add entries in the types.db for the fxX? ops Signed-off-by: Peter Bex <pe...@more-magic.net> --- types.db | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/types.db b/types.db index 7e30466..ad8a462 100644 --- a/types.db +++ b/types.db @@ -1191,6 +1191,15 @@ (chicken.fixnum#fxxor (#(procedure #:clean #:foldable) chicken.fixnum#fxxor (fixnum fixnum) fixnum)) (chicken.fixnum#fxlen (#(procedure #:clean #:foldable) chicken.fixnum#fxlen (fixnum) fixnum)) +(chicken.fixnum#fx+? (#(procedure #:pure) + chicken.fixnum#fx+? ((or fixnum false) (or fixnum false)) (or fixnum false))) +(chicken.fixnum#fx-? (#(procedure #:pure) + chicken.fixnum#fx-? ((or fixnum false) (or fixnum false)) (or fixnum false))) +(chicken.fixnum#fx*? (#(procedure #:pure) + chicken.fixnum#fx*? ((or fixnum false) (or fixnum false)) (or fixnum false))) +(chicken.fixnum#fx/? (#(procedure #:clean) + chicken.fixnum#fx/? ((or fixnum false) (or fixnum false)) (or fixnum false))) + (gensym (#(procedure #:clean) gensym (#!optional (or string symbol)) symbol)) (get (#(procedure #:clean #:enforce) get (symbol symbol #!optional *) *) -- 2.1.4
From b554163c44d4168128707784fafa40f8096ccef4 Mon Sep 17 00:00:00 2001 From: Peter Bex <pe...@more-magic.net> Date: Sun, 21 May 2017 18:23:12 +0200 Subject: [PATCH 2/2] Remove #:foldable for fixnum-specific ops What's a fixnum on a 64-bit platform may not be a fixnum on a 32-bit platform, which might cause problems with unsafe specialisation. --- types.db | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/types.db b/types.db index ad8a462..cc7f9a2 100644 --- a/types.db +++ b/types.db @@ -1165,31 +1165,31 @@ (chicken.fixnum#fixnum-bits fixnum) (chicken.fixnum#fixnum-precision fixnum) -;;XXX should these be enforcing? -(chicken.fixnum#fx- (#(procedure #:clean #:foldable) chicken.fixnum#fx- (fixnum fixnum) fixnum)) -(chicken.fixnum#fx* (#(procedure #:clean #:foldable) chicken.fixnum#fx* (fixnum fixnum) fixnum)) -(chicken.fixnum#fx/ (#(procedure #:clean #:foldable) chicken.fixnum#fx/ (fixnum fixnum) fixnum)) -(chicken.fixnum#fxgcd (#(procedure #:clean #:foldable) chicken.fixnum#fxgcd (fixnum fixnum) fixnum)) -(chicken.fixnum#fx+ (#(procedure #:clean #:foldable) chicken.fixnum#fx+ (fixnum fixnum) fixnum)) -(chicken.fixnum#fx< (#(procedure #:clean #:foldable) chicken.fixnum#fx< (fixnum fixnum) boolean)) -(chicken.fixnum#fx<= (#(procedure #:clean #:foldable) chicken.fixnum#fx<= (fixnum fixnum) boolean)) -(chicken.fixnum#fx= (#(procedure #:clean #:foldable) chicken.fixnum#fx= (fixnum fixnum) boolean)) -(chicken.fixnum#fx> (#(procedure #:clean #:foldable) chicken.fixnum#fx> (fixnum fixnum) boolean)) -(chicken.fixnum#fx>= (#(procedure #:clean #:foldable) chicken.fixnum#fx>= (fixnum fixnum) boolean)) -(chicken.fixnum#fxand (#(procedure #:clean #:foldable) chicken.fixnum#fxand (fixnum fixnum) fixnum)) -(chicken.fixnum#fxeven? (#(procedure #:clean #:foldable) chicken.fixnum#fxeven? (fixnum) boolean)) -(chicken.fixnum#fxior (#(procedure #:clean #:foldable) chicken.fixnum#fxior (fixnum fixnum) fixnum)) -(chicken.fixnum#fxmax (#(procedure #:clean #:foldable) chicken.fixnum#fxmax (fixnum fixnum) fixnum)) -(chicken.fixnum#fxmin (#(procedure #:clean #:foldable) chicken.fixnum#fxmin (fixnum fixnum) fixnum)) -(chicken.fixnum#fxmod (#(procedure #:clean #:foldable) chicken.fixnum#fxmod (fixnum fixnum) fixnum)) -(chicken.fixnum#fxrem (#(procedure #:clean #:foldable) chicken.fixnum#fxrem (fixnum fixnum) fixnum)) -(chicken.fixnum#fxneg (#(procedure #:clean #:foldable) chicken.fixnum#fxneg (fixnum) fixnum)) -(chicken.fixnum#fxnot (#(procedure #:clean #:foldable) chicken.fixnum#fxnot (fixnum) fixnum)) -(chicken.fixnum#fxodd? (#(procedure #:clean #:foldable) chicken.fixnum#fxodd? (fixnum) boolean)) -(chicken.fixnum#fxshl (#(procedure #:clean #:foldable) chicken.fixnum#fxshl (fixnum fixnum) fixnum)) -(chicken.fixnum#fxshr (#(procedure #:clean #:foldable) chicken.fixnum#fxshr (fixnum fixnum) fixnum)) -(chicken.fixnum#fxxor (#(procedure #:clean #:foldable) chicken.fixnum#fxxor (fixnum fixnum) fixnum)) -(chicken.fixnum#fxlen (#(procedure #:clean #:foldable) chicken.fixnum#fxlen (fixnum) fixnum)) +;;XXX These aren't enforcing, and aren't foldable due to 32/64-bit issues +(chicken.fixnum#fx- (#(procedure #:clean) chicken.fixnum#fx- (fixnum fixnum) fixnum)) +(chicken.fixnum#fx* (#(procedure #:clean) chicken.fixnum#fx* (fixnum fixnum) fixnum)) +(chicken.fixnum#fx/ (#(procedure #:clean) chicken.fixnum#fx/ (fixnum fixnum) fixnum)) +(chicken.fixnum#fxgcd (#(procedure #:clean) chicken.fixnum#fxgcd (fixnum fixnum) fixnum)) +(chicken.fixnum#fx+ (#(procedure #:clean) chicken.fixnum#fx+ (fixnum fixnum) fixnum)) +(chicken.fixnum#fx< (#(procedure #:clean) chicken.fixnum#fx< (fixnum fixnum) boolean)) +(chicken.fixnum#fx<= (#(procedure #:clean) chicken.fixnum#fx<= (fixnum fixnum) boolean)) +(chicken.fixnum#fx= (#(procedure #:clean) chicken.fixnum#fx= (fixnum fixnum) boolean)) +(chicken.fixnum#fx> (#(procedure #:clean) chicken.fixnum#fx> (fixnum fixnum) boolean)) +(chicken.fixnum#fx>= (#(procedure #:clean) chicken.fixnum#fx>= (fixnum fixnum) boolean)) +(chicken.fixnum#fxand (#(procedure #:clean) chicken.fixnum#fxand (fixnum fixnum) fixnum)) +(chicken.fixnum#fxeven? (#(procedure #:clean) chicken.fixnum#fxeven? (fixnum) boolean)) +(chicken.fixnum#fxior (#(procedure #:clean) chicken.fixnum#fxior (fixnum fixnum) fixnum)) +(chicken.fixnum#fxmax (#(procedure #:clean) chicken.fixnum#fxmax (fixnum fixnum) fixnum)) +(chicken.fixnum#fxmin (#(procedure #:clean) chicken.fixnum#fxmin (fixnum fixnum) fixnum)) +(chicken.fixnum#fxmod (#(procedure #:clean) chicken.fixnum#fxmod (fixnum fixnum) fixnum)) +(chicken.fixnum#fxrem (#(procedure #:clean) chicken.fixnum#fxrem (fixnum fixnum) fixnum)) +(chicken.fixnum#fxneg (#(procedure #:clean) chicken.fixnum#fxneg (fixnum) fixnum)) +(chicken.fixnum#fxnot (#(procedure #:clean) chicken.fixnum#fxnot (fixnum) fixnum)) +(chicken.fixnum#fxodd? (#(procedure #:clean) chicken.fixnum#fxodd? (fixnum) boolean)) +(chicken.fixnum#fxshl (#(procedure #:clean) chicken.fixnum#fxshl (fixnum fixnum) fixnum)) +(chicken.fixnum#fxshr (#(procedure #:clean) chicken.fixnum#fxshr (fixnum fixnum) fixnum)) +(chicken.fixnum#fxxor (#(procedure #:clean) chicken.fixnum#fxxor (fixnum fixnum) fixnum)) +(chicken.fixnum#fxlen (#(procedure #:clean) chicken.fixnum#fxlen (fixnum) fixnum)) (chicken.fixnum#fx+? (#(procedure #:pure) chicken.fixnum#fx+? ((or fixnum false) (or fixnum false)) (or fixnum false))) -- 2.1.4
signature.asc
Description: Digital signature
_______________________________________________ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers