Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic Feature #65

Open
seminumber opened this issue Aug 1, 2019 · 2 comments
Open

Generic Feature #65

seminumber opened this issue Aug 1, 2019 · 2 comments
Assignees
Labels
breaking-change Issue or PR that represents a breaking API or functional change over a release. enhancement

Comments

@seminumber
Copy link

seminumber commented Aug 1, 2019

Sorry for bringing back the closed issue #48

The type safety is pretty important feature for careless coders like me, and I believe some people will benefit from the change. In your samples, I see Genes contains indices and index calculus to solve certain problems. Obviously you can assign custom classes to Gene's object whatever you like, but this makes me feel unsafe when I recast it back to original class type.

Making it generic is truly possible, but will be very tedious; but once done right, we may benefit from compile time check for type casting, and a slight performance gain by avoiding boxing and unboxing
(but yes, gene populations will not be that much and as long as you use reference types or small structs, it will not be the performance bottleneck)

Describe the solution you'd like
I actually did it for my personal use and you can see how it works in my fork https://github.com/seminumber/GeneticSharp/tree/feature/generic and the sample https://github.com/seminumber/GeneticSharp/tree/feature/generic/src/TspWpf
This is a proof-of-concept only. It's not polished and tested and doesn't meant to be pulled into your project. It can only show how it would look like when generics are implemented. The code runs exactly in the same way as your Blazor sample.
(I'm a windows users and I can work well with Wpf, so my sample was Wpf only. sorry if you're not using Windows, but you'll see the code and how it goes)

Describe alternatives you've considered
I first thought changing Gene to Gene<T> is the way to go, but later changed mind as Gene<T> took place for every location, so I changed Gene altogether with T. You can rename it TGene of course, or assign some interfaces for that, but T seems good enough for me.
Obviously, in more generic setup making <T, U> : U is IGene<T>, and <T> as a synonym for <T, Gene<T>> is another solution with genericity, but it would be too complicated to change so I took a simple path. But you may consider this is the better solution.

Additional context

In case you're interested, here's the procedure I took:

  1. Copy the entire Domain folder to Domain.Generic Folder
  2. In VS, rename (F2-refactor) IChromosome to IChromosome_ (so that it does not interfere with other names)
  3. Search and Replace within the whole project and change IChromosome_ to IChromosome<T>
  4. For every error in the intellisense, change the class containing errors to (mindlessly) adding type parameter <T>
    by repeating procedure 2 and 3 (meaning MyClass to MyClass_ and then MyClass<T>
  5. Search and Replace all namespaces .Domain.* into .Domain.*.Generic
  6. Repeat 2 to 5 until no errors are left
  7. Fix codes using the following rules..
    - Gene is now all T
    - Gene[] is now all IList<T>
    - Gene Equality (== or != or Equals) is checked by EqualityComparer<T>.Default.Compare
    - static classes will give type argument <T> for their methods
    - search all constructors and remove <T> for them (this is the consequence of mindless search-and-replace)

If you think this feature is valid, here's a few more things to consider (which I didn't implement - it was a test code after all)

  • making all generics implement nongeneric interfaces when possible (like, collections implements both IEnumerable<T> and IEnumerable)
  • making IChromosome<T> covariant so that IChromosome<Apple> is IChromosome<Fruit> whenever Apple is Fruit.
  • remove unnecessary generic counterparts (ITermination doesn't really needs to be Generic all the way, but I just mindlessly
    change all the way to avoid compile errors. In production, a good design will be necessary)
  • if Gene is a must for the design, create IGene<T> and restrcit IChromosome<TType, TGene> where TGene: IGene<TType>
  • provide static factory methods to benefit from type inferencing
    (like, Tuple<T1, T2, T3> can benefit from static Tuple<T1,T2,T3> Create<T1,T2,T3>(T1, T2, T3), so that
    compiler deduces the correct method when we use var tuple = Tuple.Create(3, "three", new Foo()) )

There can be some other changes I made which I'm not sure that was intended
-- like integer chromosome which I believe will be broken if you upcast IntegerChromosome
to BinaryChromosomeBase or ChromosomeBase.. well that's separate issue and I'll not go deep into this.

@giacomelli giacomelli self-assigned this Aug 1, 2019
@giacomelli giacomelli added enhancement breaking-change Issue or PR that represents a breaking API or functional change over a release. labels Aug 1, 2019
@giacomelli
Copy link
Owner

I liked your approach and I really need to take some time to analyze the changes and how this will impact and variety of places that library is used.

Anyway, this issue is a breaking change and need to be postpone to a version 3 of GeneticSharp, now its 2.6.0. I just created I tag and a project for version 3 to track this kind of issues.

Now, I don't have a deadline to when this V3 will happen.

Thank you!

@electro-logic
Copy link

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Issue or PR that represents a breaking API or functional change over a release. enhancement
Projects
None yet
Development

No branches or pull requests

3 participants