JuliaMath / FixedPointNumbers.jl

fixed point types for julia

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Commonizing code between `Fixed` and `Normed`

kimikage opened this issue · comments

Fixed and Normed have evolved independently. Therefore, some functions are specialized even though they do not need specialization.

cf. ee5bd54...kimikage:commonize PR #151

I'm going to refactor the codes by taking the following 3 steps.

  1. Commonize the existing implementation code
  2. Add the functions which are implemented only in either (e.g. rounding functions for Fixed)
  3. Commonize the test codes

Although "test-first" is a good practice, the step 3. requires major renovations. Please give me your advice if you have any ideas.

It might be a good idea to add the step.

  1. Update comments and Add docstrings

For example, "32-bit fixed point" is a holdover from the Fixed32 age.

# 32-bit fixed point; parameter `f` is the number of fraction bits
struct Fixed{T <: Signed,f} <: FixedPoint{T, f}

If we modify the comments, I think it is better to write them in the docstring style, e.g:

"""
    FixedPoint{T <: Integer, f} <: Real

Supertype of the two fixed-point number types: `Fixed{T, f}` and `Normed{T, f}`.

The parameter `T` is the underlying machine representation and `f` is the number of fraction bits.
"""
abstract type FixedPoint{T <: Integer, f} <: Real end

The problem is that I am not good at English.

Edit:
Also, what about setting coding guidlines for the static parameters (parametric methods)?

I am concerned that I will unnecessarily be blamed by renaming all parameters at once (even though Github provides a good UI for "diff"). So, I think it is better to rename them at every opportunity rather than at once.

There are two type of inconsistency: the naming and the specialization level. The following is my draft.

Naming

  • F, F[0-9] X, X[0-9]
    • for <: FixedPoint, <: Fixed, <: Normed
  • F, F[0-9]
    • for <: Fixed
  • N, N[0-9]
    • for <: Normed
  • f, f[0-9]
    • for the number of fractional bits
  • T, T[0-9]
    • for the rawtype Integer
  • T[a-z]+
    • for general purpose, e.g.:
      • Ti <: Integer
      • Tf <: AbstractFloat
      • Tw <: widen(T)

Specialization level

  • Don't use unnecessary static parameters
    • especially when the method is not worth inlining, e.g.:
      • using IO
      • might throw an exception
    • exceptions:
      • the rawtype T with the nbitsfrac f
      • when using two or more typeof-like methods
      • needs for solving ambiguity

Steps 1 and 2 are almost complete. Step 0 (the coding guidelines) is partially unfinished. Step 3 has not been started yet. I will keep this issue open until we have a concrete work plan.

I thought the test code was difficult to commonize. However, as I'll add tests for arithmetic operations, I am not very satisfied with the current test code.

A practical problem is the long testing times. It's not fatal at the moment, but it should be an obstacle to supporting signed Normed in the future.
We spend the most part of the testing time compiling. Therefore, except the reduction of memory allocation, optimization techniques for "run-time" speed has almost no effect. So it's important to reduce the number of test cases, or target types.
Currently, 128-bit/64-bit types are tested, even though they are rarely used in practice. I believe that the reduction of the target type can be abstracted. For example, the following API can be considered:

julia> target(Normed, (:i8, :i16), :light)
(N7f1, N1f7, N0f8, N15f1, N9f7, N8f8, N7f9, N6f10, N5f11, N1f15, N0f16)

We can use include to do things like mix-in, but the unit of common reusable test sets are per file. That is incompatible with ”partially" commonizable test sets. @includetests of TestSetExtensions.jl also have the same problem.

I devised (ugly) small macros like this:
https://github.com/kimikage/CommonTests.jl

The pair of macros @common and @runcommon use the names of the test sets to map the caller to the callee. However, I think there is a more elegant way.

The support for checked basic four operations is almost complete. Now that I know that those 100% tests are common to Fixed and Normed, I would like to commonize their codes. However, I'm not going to introduce any tricky macros, but simply write functions.