Skip to content

Conversation

@gus-massa
Copy link
Contributor

And a few related changes ...


Add exact and inexact to cptypes

This is the main part, it has a few subparts inside the same commit:

  • Add inexact to cptypes: The old implementation of real->flonum calls inexact and this goes in the "wrong" direction of detail level, and it cause a problem when I add inexact to cptypes (or perhaps when I add inexact to cpprim). So I added a new function $real->flonum to 5_3.ss

  • Add exact to cptypes: The problem is that exact is not total, and the domain is unusual, so it can't be converted to the unsafe version automatically, so I added a special case. An alternative is to add a new type complex-rational to primvars.ms and then change the signature to (exact? [sig [(complex-rational) -> (boolean)]] ...). (Side note: Also, the handle has a special case to collaborate with zero? that is where I notice the problem of moving stuff from the tail position to non-tail.)

  • Replace $value with fl+: This is an experimental idea. I'd like to add in the future a few fl+ here and there so later np-unbox-fp-vars! can unbox more flonums. I'm not sure when it's a good idea to add new fl+, but replacing some $value with fl+ looks like a win.


Reverse arguments of $real->flonum

Rename in library real-flonum to $real-flonum because it has two arguments like the primitive with the same name.

Also, in all (most?) of the other cases, who is the first argument. I'm not sure if it's necessary to keep backward compatibility at with the system functions.

Both changes are just cosmetic, but they make the code more consistent.


Add exact and inexact to cpprim

I'm not very happy with this third part. There is too little work to do and it may increase the executable file size without increasing speed. Perhaps inexact is interesting but exact has too few possible improvements unless I add a lot of code to cpprim.

(The boot files have probably only a stub for the increase of items in the library, without the implementation.)

Copy link
Contributor

@mflatt mflatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first two commits look good as far as I can tell. I have some suggestions for the third commit.

s/cpprim.ss Outdated
(%typed-object-check mask-inexactnum type-inexactnum ,e-x))
,e-x
,(build-libcall #t src sexpr inexact e-x)))))])
(define-inline 2 exact->inexact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like too much code duplication. Add a build-exact->inexact parameterized over the library entry to call?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The (small) problem is that build-libcall is a macro that expect an not-quoted version of the name of the library call. So build-exact->inexact must be a macro too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or pass in a function like(lambda (e-x) (build-libcall #t src sexpr inexact e-x)). I'd say the goal isn't to avoid every bit of duplication, but to get most of it.

s/cpprim.ss Outdated
,e-x
,(build-libcall #t src sexpr exact->inexact e-x)))))])
)
(define-inline 2 exact
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I share your reluctance about these. Maybe if they included conversion from integer flonums that are small enough to fit into a fixnum? Otherwise, I'd be inclined to leave them out until motivated by a use.

Copy link
Contributor Author

@gus-massa gus-massa Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like (copiying from #2%flonum->fixnum)

,(build-and
                            (build-fl< e-x `(quote ,(constant too-positive-flonum-for-fixnum)))
                            (build-fl< `(quote ,(constant too-negative-flonum-for-fixnum)) e-x))

I'll try tomorrow, because I prefer to see the code to think about it, but I'm still not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code should check that it's an integer flonum. flonum->fixnum just truncates the value. To check that one possibility is to look if the exponent is big enough, but that will detect only very big flonums, bigger than ~2^54 that are not very interesting (and I'm missing 0.0 and inf.0). It looks too hard to do something interesting with fast code.

I'll try to add the most interesting cases to cptypes instead.

@gus-massa
Copy link
Contributor Author

By the way, in primdata.ss there is a primitive

($flonum->fixnum [flags single-valued])

that is unused.

@burgerrg burgerrg changed the title Add exact and imexact to cptypes Add exact and inexact to cptypes Nov 14, 2025
Also, try to change $value to fl+ to allow flonum unboxing later
@gus-massa
Copy link
Contributor Author

I made a lot of changes, so I squashed the old commits and the new part. I have still the unesquashed version if helpful https://github.com/gus-massa/ChezScheme/tree/25-8-Imexact-2

This has an update of the bootfiles of some of the commits that are already merged. Otherwise I get an error in my machine. I'm not sure what is happening.


New parts:

exact:

My old idea was to split fixnum from the other types in cpprim. Now I dropped that attempt and I'm splitting flonum but only when the argument is known to be real:

(lambda (x) (when (real? x) (exact x)))
=>
(lambda (x) (when (real? x) (if (flonum? x) (exact x) x)))

I expect this to be more useful in usual programs and in many cases the type check can be removed by the optimization.

It's still possible to split fixnum but I don't expect this to be very useful

(lambda (x) (when (maybe-fixnum? x) (exact x)))
=>  not implemented =>
(lambda (x) (when (maybe-fixnum? x) (if (fixnum? x) x (exact x))))

inexact:

It mostly call real->fonum that does most of the job

real->flonum

Now in cprim, the implementation of real->flonum and $real->flonum are very similar. The only difference is that real->flonum has first a run time check for fixnum so my idea was to move that check here and transform

(lambda (x) (real->fixnum x))
=>
(lambda (x) (if (fixnum? x) (fixnum->flonum x) ($real->fixnum 'real->fixnum x)))

If I understand correctly this does not change the assembler that is generated, so in the worse case it does not change the runtime so it's "free". In the best case, the type check can be removed during the optimization and increase the final speed a tiny bit.

One problem is that the to reuse $real->fixnum the code needs to use too many arguments and it returns 5 results but I only need the first one. So the code does not look nice. My idea is to add some kind of wrapper that hides the other 4 return values and perhaps some of the arguments, but I prefer to do this code improvement in the future when there are a few more cases and I understand how is the best level of hiding.

Next both have a check for flonums. One idea was to move it to cptypes too, and perhaps removed. But I'd need a very system primitive $$real->flonum, so I didn't implement it.

$real->flonum

No changes

real-exp->flonum-exp[/-]
It now reuse real->flonum to handle the subcases. (It again shows the problem with the 5 return values)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants