Giter VIP home page Giter VIP logo

Comments (10)

imulab avatar imulab commented on July 22, 2024

I did notice you already have chaining tests in files like arraylist_test, but these only allow implementation level chaining, it kind of defeats the purpose of having interfaces though...

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

I agree with everything you said. I was not sure how to solve this problem and left it for some other time. I tried a few ways, but could not reach the desired effect.

How would you implement it? I am not sure I understood the ToContainer method? What does it do exactly?

Also if one returns EnumerableWithIndex (or EnumerableWithKey) then it's impossible to mix between those two, right?

I am just not sure, if I can make this work as in Ruby where you can mix maps, arrays, etc. without any type assertions, which are really ugly to that point that the library becomes useless.

Can you please make a proof of concept, either in gods or on golang playground just so I get the idea. Thanks

from gods.

imulab avatar imulab commented on July 22, 2024

Yep, I forked your repo to add and fix a few things for use of another project. The proposed enumeration changes are in there.

https://github.com/davidiamyou/go-companion/blob/master/containers/enumerable.go

You can then take a look at various data structure packages where there is the enumerable.go. Essentially, all lists now implement EnumerableWithIndex, all sets now implement Enumerable, all maps now implement EnumerableWithKey. The reason for this is that lists are by nature ordered, sets are by nature unordered (even though underlying implementation can have its elements ordered, API should not make this visible unless user does explicit type assertion himself) and maps are by nature key-valued.

The ToContainer method is really a type assertion disguised in API form. You can see in my implementations that it just returns the receiver as is. I just thought a redirection back to the Container types after chaining will be nice. It could be argued that we can change the ToContainer method to something more specific. i.e. For EnumerableWithIndex, use ToList() to allow direct access to more rich APIs than Container.

from gods.

imulab avatar imulab commented on July 22, 2024

I also returned interfaces only for New() constructors except for the trees. IMHO, users should only work with interface APIs and be shielded away from the implementation details. This is partially why, I guess, the above proposed type assertion is way easier, as it no longer have to deal with specific concrete types.

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

Thanks for finding time to explain your idea.

I found this in your commit. It looks like type assertion is still necessary or is there another actual chaining example? That's basically what I also get if I uncomment the code, but without the ToContainer() call.

I'll try to create a simpler example on golang playground and see if we can figure something out here without the ugliness of type assertions (at least not on the container types).

This is (probably unreachable) beauty of Ruby:

{a: 1, b: 2, c: 3}
  .select { |k,v| v > 2 } # {b: 2, c: 3}
  .map { |k,v| k }        # [b, c]
  .any? { |v| v == :a }   # false

I was hoping gods would be able to do something like this without a ton of type assertions.

from gods.

imulab avatar imulab commented on July 22, 2024

Right, this is what I am talking about removing the ToContainer() method from the three Enumerable interfaces and replace with more specific methods like ToList(), ToSet() and ToMap(). If I do that, type assertion in most cases would be unnecessary.

Actually, thinking about it, I think I am gonna change my interfaces to that tomorrow. The only downside is that by doing this, I am effectively binding each of the three Enumerable interfaces to a specific kind of data structure. It would be hard later on for me to try to enumerate a map (with map entry instead of key value tuple, effectively treating it as a set), but I think it is a something I am okay with without massively changing your interface hierarchy.

I totally agree with you on the beauty of the ruby syntax. Unfortunately, I suppose the core idea of Golang is to produce maintainable and simple code by preventing people to do too much smart things.

I will post my commit here tomorrow after I have changed my interfaces and fix the test cases.

from gods.

imulab avatar imulab commented on July 22, 2024

You can find the changes to the interface in this commit

If we want things to be more flexible (for instance, capability to enumerate map as a set of entries and in the end convert that into actually a set), we would probably need to haul out something like Java's Stream API.

But for most day-to-day use cases, I would say this is sufficient.

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

but I think it is a something I am okay with without massively changing your interface hierarchy

I don't have too much of a problem with that, even though it's a huge task. If it would make the library more useful, I am up for it. However, I tried a few ways and could not make it work any close to Ruby.

You can find the changes to the interface in this commit

IMHO somehow these To...() calls still resemble type assertions (in essence they are exactly that). Saying ToSet() or type asserting .(*HashSet) is not that different and chaining would again be on the container super-type (lists or sets) level.

I'll have to rethink this whole thing and perhaps try uncommenting the mentioned lines to return perhaps and Iterables? Perhaps that's the part that I missed trying to return the Container. Let me play with this for a while and see if there is any way to accomplish this, I probably need to look at it from another angle. I am even at the point to be forgiving in terms of having to type assert containers during chaining, if there is no other way.

from gods.

imulab avatar imulab commented on July 22, 2024

You are right, it is still a type assertion in the end. Because enumerables have their own interfaces, I just cannot get away with type assertion without having to merge enumerable interfaces with data structure interfaces.

Please let me know if you have come up with anything, I would love to incorporate it into my project later.

At the meantime, I will take a look at the possibility of mimicing Java's Stream API.

from gods.

emirpasic avatar emirpasic commented on July 22, 2024

i still don't have an idea how to solve this, closing after two years...

from gods.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.