lisitsyn / tapkee

A flexible and efficient С++ template library for dimension reduction
http://tapkee.lisitsyn.me
BSD 3-Clause "New" or "Revised" License
231 stars 58 forks source link

Simplify interface methods with Requires Expressions and later maybe Concepts #109

Closed iglesias closed 2 months ago

iglesias commented 3 months ago

Yesterday, we started with going from

  tapkee::initialize().withParameters((method=...,num_neighbors=...))

to

  tapkee::with((method=...,))

For the distance, kernel, and/or features there are

  tapkee::with(...).withKernel(kernel_callback)
                   .withDistance(distance_callback)
                   .withFeatures(features_callback)

which, yesterday afternoon, I thought could be nice to simplify since in e.g. 'withKernel(kernel_callback)' already from the kernel_callback's type it should be inferable that the 'with' is for a kernel.

From how to implement it, I got excited since I think requires/concepts are the good tool for this and I have never used them.

I think the result could look like

  tapkee::with((method=...,...).with(kernel_callback).with(distance_callback)

or perhaps

  tapkee::with((method=...,num_neighbors=...),
               kernel_callback,
               distance_callback)

(the latter may be quirky to have the kwargs betweeen parentheses and the others no, but I personally think it is not an issue and looks nice).

I am using Mateus Pusz library as a reference for the syntax, for example: https://github.com/mpusz/mp-units/blob/602a60999547ed13134232b54f041bfac6ccc35b/src/core/include/mp-units/math.h#L227

I started experimenting yesterday night for about an hour and got this far. I think the requires clauses are large enough to be worth their own concepts (e.g. DistanceCallback, KernelCallback, FeaturesCallback or maybe just even Distance, Kernel, and Features concepts and the *Callbacks would be the names for the template types complying to their respective concept). The library could be built and the unit tests run with PASS. I think there's still problem with rna example. But in any case, this I don't think is close to good yet, just the experimental kickoff.