flauwekeul / honeycomb

Create hex grids easily, in node or the browser.
https://abbekeultjes.nl/honeycomb
MIT License
630 stars 57 forks source link

4.0.0 release #82

Closed AnthonyCrowcroft closed 1 year ago

AnthonyCrowcroft commented 2 years ago

Hey @flauwekeul when is the full release in typescript expected and is there anything required to finish it?

flauwekeul commented 2 years ago

Hi! Thanks for taking an interest. The reason it's not finished yet is that I'm unhappy with the API and after the last beta release I was tired of it. Also, I've had less time to spend on it since.

Anyway, are there any things you like or dislike about the beta? I could also just release it and make a better version 5 😆

AnthonyCrowcroft commented 2 years ago

I was thinking of using it for a personal project soon and instead of just using the beta I thought I'd see if I could help get the next full version out and use that. What sort of things were you unhappy with?

flauwekeul commented 2 years ago

I have to dive into it again to remember the details, but I don't like how state management happens. Because all Grid methods return a new grid, each time you want to do anything with a grid (mapping/filtering over hexes, or updating it), you need to overwrite some "global" variable to keep the new grid.

I'm considering to either make it possible to mutate a grid instance in-place (similarly to how MomentJS works, but there's good reason it's not in active development anymore). Or move to a more functional programming style of API (similar to RxJS maybe). Using an FP-style API has several (big) advantages (disclaimer: I'm a big fan of FP), but it's less familiar for a lot of people. However, FP is getting more traction since React introduced "hooks" (and Vue later their similar composition API). So, at the moment I'm quite sure I'll head in that direction.

You could help me most by using the beta version and tell me things you like and dislike 👍

AnthonyCrowcroft commented 2 years ago

I'm also very fond of the functional paradigms so that would be ideal. I'll start playing wit hit soon

flauwekeul commented 2 years ago

Just an update: I continued working on the next version (in the transducers branch, I'll merge it into next soon). I'm planning on doing some more dogfooding and if I keep liking the current API I'll update the docs and release the next alpha or beta.

etodanik commented 2 years ago

Would love to either contribute financially to move this along quicker , or to contribute my time and help you finish it up.

Right now a big blocker for contribution is that the tests on next aren't passing at all, there isn't a clear backlog/roadmap for this refactor, so it's rather hard to understand where to take the code next.

flauwekeul commented 2 years ago

Hi. For some reason neither my phone, nor my laptop notified me I had new email 😕, so sorry for the delayed response.

I am in fact in the middle of a very big refactor and the roadmap is in my head only. Also, it changes every hour as I gain new insights and change my mind about things...So unfortunately you can't help it move forward. I appreciate your willingness though.

The refactor is moving along nicely, I'm still dogfooding the API and things are still changing, although not as much as in the beginning. Once I feel the API is done enough I'll start adding/fixing tests and updating the documentation. This will probably take at least some weeks...

etodanik commented 2 years ago

I'm a little bit ambiguous on the lib "forcing" the use of transducers. I know how they're great for performance and all, but IMHO this should be an encouraged patter v.s a hard dependency on transducist, given how it's a mostly obscure and little used library.

I feel that any library should try to be as thin as possible, and encourage good patterns while leaving the final call with the user.

This is just my 0.2 cents, but having this hard dependency on transducist makes everything a little "fatter" than I'd love to see. If I was deciding, I'd design it to work great with transducist but in a more decoupled way (rather than a hard dependency). This would also leave the possibility that if transducist dies (it's already a nearly non-maintained repo) - users could switch to something else, or apply a completely different approach altogether.

Does it make any sense?

flauwekeul commented 2 years ago

I'm planning on using transducist internally and only exposing relevant functionality through Honeycomb (e.g. dedupe() isn't relevant). That way it's Honeycomb's "problem" that it depends on an obscure ill-maintained repo (which still supports tree-shaking btw). Honeycomb relies on the programming pattern of transducers, and it happens to use transducist for it.

However, it would be better if Honeycomb wouldn't rely on transducist, but I would very much like to use transducers internally, because it's simply more performant. I see 3 options:

  1. use a library (transducist seems the only transducer lib with good typescript support)
  2. make my own transducer functionality
  3. don't use transducers and find another way to transform hexes (in a grid) in a composable and performant way with proper typescript support

I've experimented with option 3 in a separate branch, but I either didn't like the resulting API or it just wasn't performant.

If you see more than these 3 options or any other remarks, please let me know.

etodanik commented 2 years ago

Hmm, yes I understand... I guess you did choose the lesser of evils. I guess it's just a shame that transducers didn't catch on as much in the JS world as a concept :(

Anyways, if I have a sudden epiphany I'll write, but it seems that you have chosen a good compromise so far.

flauwekeul commented 2 years ago

So...I had a new insight yesterday evening: the added value of transducers is negligible 😅.

In terms of performance, they only help when transforming part of an iterable (e.g. a grid). For example, if you want to iterate over hexes in a grid (using a traverser for example), but only the first n hexes or until the traverser "leaves the grid", then transducers keep you from running the entire iteration. But still, the performance gain is small compared to using good ol' Array methods (about 17% faster in my specific benchmark test).

That leaves a nice composable API as the only reason to keep using transducers, but like you said: that should be an opt-in for users.

So, I'm almost certainly going to change the API again (probably only removing the update() method from Grid).

etodanik commented 2 years ago

That actually sounds amazing and makes me happy to hear it 😀

On 29 Jul 2022 Fri at 17:41 Abbe Keultjes @.***> wrote:

So...I had a new insight yesterday evening: the added value of transducers is negligible 😅.

In terms of performance, they only help when transforming part of an iterable (e.g. a grid). For example, if you want to iterate over hexes in a grid (using a traverser for example), but only the first n hexes or until the traverser "leaves the grid", then transducers keep you from running the entire iteration. But still, the performance gain is small compared to using good ol' Array methods (about 17% faster in my specific benchmark test).

That leaves a nice composable API as the only reason to keep using transducers, but like you said: that should be an opt-in for users.

So, I'm almost certainly going to change the API again (probably only removing the update() method from Grid).

— Reply to this email directly, view it on GitHub https://github.com/flauwekeul/honeycomb/issues/82#issuecomment-1199424430, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAPBB6GC2SHO4YSQ46AQZDTVWPUQFANCNFSM5Z74B2TQ . You are receiving this because you commented.Message ID: @.***>

flauwekeul commented 1 year ago

Closing this, because v4.0.1 was just released.