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

Add concatenation #15

Merged
merged 18 commits into from
May 13, 2019
Merged

Add concatenation #15

merged 18 commits into from
May 13, 2019

Conversation

Abbondanzo
Copy link
Contributor

Adds concat operator which merges indexed iterables and joins keyed iterables.

src/__tests__/concat-test.js Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved
src/protocol.js Show resolved Hide resolved
src/__tests__/concat-test.js Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Copy link

@bobc7i bobc7i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM once @kj800x issues are addressed

@kj800x
Copy link
Member

kj800x commented May 7, 2019

@colbyr If you get a chance, I'd love to hear your thoughts on this. We'll be looking to merge this sometime next week.

Copy link
Contributor

@colbyr colbyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah cool this'll be useful. I left some comments inline about modifying the protocol definition.

Also I was wondering about the intended behavior. (I don't really have strong opinions I just want to make sure we're clear on what it does/doesnt do 😄)

Does concat only work with two similar types (e.g. Arrray+Array, Map+Map) or can you mix and match? e.g. concat(Map({ a: 'a' }), List.of('b')). If it's meant to work with mixed types it might be good to explore that in the tests+docs.

Also when you use it with two Maps or Objects is it basically the same as a merge? If so do you think it's worth having that same behavior in two different functions? If we wanted, we could limit concat to only work on indexed types like List, Array, Seq, etc.

* @param {TYPE<_, V>} subject
* @return {Seq.Indexed<V>}
*/
export const indexedSeq = protocol({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this new indexedSeq protocol for? It doesn't seem like it's used anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original implementation used to build sequences based on whether or not the subject was an indexed or a keyed iterable, and reconstruct the object using that new sequence. I figured since the work was already done, there's no reason to toss it out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of TransmuteCollection was to have a set of protocols that are used internally by the library, so if you have a custom type in client code you can implement the protocols and that type would work with transmute. I'd lean away from adding an indexedSeq protocol until it's used by something in the library.

src/internal/TransmuteCollection.js Show resolved Hide resolved
src/internal/_concat.js Outdated Show resolved Hide resolved
@Abbondanzo
Copy link
Contributor Author

@colbyr
The intention was to only use this on indexed types but I figured it couldn't hurt to support keyed types as well, although keyed concatenation should be identical to merge behavior. By dropping the Iterable and replacing with Iterable.Indexed, I think this addition would better serve its intended purpose.

However, I am unable to target Iterable.Indexed in the implementInherited method, limited to only target Iterable. Else, the protocol is unable to pick up on immutable objects like Seq and List.

Copy link
Contributor

@colbyr colbyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, I am unable to target Iterable.Indexed in the implementInherited method, limited to only target Iterable. Else, the protocol is unable to pick up on immutable objects like Seq and List.

Hmm could you target Collection.Indexed and Seq.Indexed instead? That seems to get us the dispatching you want:

Screen Shot 2019-05-09 at 2 12 25 PM

src/protocol.js Show resolved Hide resolved
* @param {TYPE<_, V>} subject
* @return {Seq.Indexed<V>}
*/
export const indexedSeq = protocol({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of TransmuteCollection was to have a set of protocols that are used internally by the library, so if you have a custom type in client code you can implement the protocols and that type would work with transmute. I'd lean away from adding an indexedSeq protocol until it's used by something in the library.

@Abbondanzo
Copy link
Contributor Author

Targeting Collection.Indexed and Seq.Indexed seemed to do the trick. Going to add one small test for ensuring that concat can't be called on keyed objects

@Abbondanzo
Copy link
Contributor Author

^ force pushed over the history to remove the @hubspot email

Copy link
Contributor

@colbyr colbyr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks awesome! 👍

src/__tests__/concat-test.js Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved

it('uses the subject Seq as the return value type', () => {
// https://github.com/facebook/jest/issues/5998
expect(concat(['test'], Seq('test')).toJS()).toEqual([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests don't validate the type since you're doing the toJS. I'd find another way to validate the return type or remove the test (but I think having a test for this would be useful).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I linked the jest issue in question but this is happening due to reasons out of our control. The best we can do is check that the contents match and that the returned object is an instance of Seq.

src/internal/TransmuteCollection.js Outdated Show resolved Hide resolved
Copy link
Member

@kj800x kj800x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tiniest of nits, but once they're taken care of, let's merge and release this.

src/__tests__/concat-test.js Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved
src/__tests__/concat-test.js Outdated Show resolved Hide resolved
Abbondanzo and others added 4 commits May 13, 2019 10:39
Co-Authored-By: Kevin Johnson <kevin@coolkev.com>
Co-Authored-By: Kevin Johnson <kevin@coolkev.com>
Co-Authored-By: Kevin Johnson <kevin@coolkev.com>
@Abbondanzo Abbondanzo merged commit a45828e into HubSpot:master May 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants