refactor(Complex): Now a template type!

This means that the real and imaginary parts of a Complex must now be
  the same type. This seems like a real benefit: a Complex with a number real
  part and a bigint imaginary part does not seem sensible.

  Note that this is now straining typed-function in (at least) the following
  ways:
  (1) In this change, it was necessary to remove the logic that the square root
      of a negative number calls complex square root, which then calls back
      to the number square root in its algorithm. (This was creating a circular
      reference in the typed-function which the old implementation of Complex
      was somehow sidestepping.)
  (2) typed-function could not follow conversions that would be allowed by
      uninstantiated templates (e.g. number => Complex<number> if the latter
      template has not been instantiated) and so the facility for
      instantiating a template was surfaced (and for example is called explicitly
      in the demo loader `extendToComplex`. Similarly, this necessitated
      making the unary signature of the `complex` conversion function explicit,
      rather than just via implicit conversion to Complex.
  (3) I find the order of implementations is mattering more in typed-function
      definitions, implying that typed-function's sorting algorithm is having
      trouble distinguishing alternatives.

  But otherwise, the conversion went quite smoothly and I think is a good demo
  of the power of this approach. And I expect that it will work even more
  smoothly if some of the underlying facilities (subtypes, template types) are
  integrated into typed-function.
This commit is contained in:
Glen Whitney 2022-08-06 08:27:44 -07:00
parent 845a2354c9
commit 1444b9828f
25 changed files with 240 additions and 157 deletions

View file

@ -1,5 +1,8 @@
export * from './Types/Complex.mjs'
export const abs = {
Complex: ({sqrt, 'absquare(Complex)': absq}) => z => sqrt(absq(z))
'Complex<T>': ({
'sqrt(T)': sqt,
'absquare(Complex<T>)': absq
}) => z => sqt(absq(z))
}