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 Semiring type class #1266

Merged
merged 22 commits into from
Feb 1, 2019

Conversation

juliankotrba
Copy link
Contributor

@juliankotrba juliankotrba commented Jan 25, 2019

  • Interface definition
  • Laws
  • Instances
  • Tests
  • Documentation

closes #1225

@juliankotrba
Copy link
Contributor Author

Hey @pakoito, here are some things I would like to know for this PR:

  • Should I create (internal?) classes for multiplicative monoid/semigroup and let Semiring extend them
  • Any better idea for naming the function product
  • Did I forget something else important to add?

Thank you for any help you can provide 🍻

@pakoito pakoito self-requested a review January 26, 2019 23:54
@pakoito
Copy link
Member

pakoito commented Jan 27, 2019

Awesomely done, thank you much for putting time on this.

Should I create (internal?) classes for multiplicative monoid/semigroup and let Semiring extend them

I haven't seen any docs, talks, or examples where each was useful individually. Maybe with KEEP-87 when we enforce unique instances? I wouldn't require them for this PR tho, this is enough!

Any better idea for naming the function product

I checked on other languages and they tend to use either times or an operator. Because we like verbose probably combineMultiplicate is the best choice here.

Did I forget something else important to add?

Nothing important, just some short KDocs atop of the typeclass and the functions would be nice. I'm bad at this myself so it isn't a requirement :)

@pakoito
Copy link
Member

pakoito commented Jan 27, 2019

The build failed on a flaky tests, so don't worry about it!

@raulraja
Copy link
Member

@juliankotrba great stuff, Take a look at the Functor type class sources for examples on how to document a type class.

@juliankotrba
Copy link
Contributor Author

Thank you both @pakoito @raulraja for your feedback! I think I did also something wrong with the number instance tests. I am currently calling equalUnderTheLaw in my Semiring laws. But equalUnderTheLaw is just returning true or false and not throwing an AssertionException, hence my tests will never fail if there is something wrong with the implementation.

For me it looks like that shouldBeEqual is designed for this use case but is currently just creating a io.kotlintest.Result. Shouldn't it be something like this:

if (eqv(b).not()) {
      throw AssertionError("Expected: $this but found: $b")
}

Please correct me if I am wrong or miss something.

@pakoito
Copy link
Member

pakoito commented Jan 27, 2019

equalUnderTheLaw is meant to be used with property-based tasting blocks forAll. If you just want to test a single case, useshouldBe for assertions.

@juliankotrba juliankotrba changed the title [WIP] Add Semiring type class Add Semiring type class Jan 28, 2019
/**
* Maybe multiplicatively combine two [A] values.
*/
fun A.maybeCombineMultiplicate(b: A?): A =
Copy link
Member

Choose a reason for hiding this comment

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

Could it be fun A?.maybeCombineMultiplicate(b: A?): A = instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, but I wanted to be consistent with Semigroup's maybeCombine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should I change it in this this PR for both functions, create a new PR or just leave it?

Copy link
Member

Choose a reason for hiding this comment

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

I'd fix both on this PR tbh :P

Copy link
Contributor Author

Choose a reason for hiding this comment

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

K 😁 But just to be sure, returning zero() if the receiver is null is the expected behavior, right?

Copy link
Member

Choose a reason for hiding this comment

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

zero for addition, one for multiplication

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mhh maybe the reason why maybeCombine's receiver is not nullable is because maybeCombine is defined in Semigroup, which doesn't have an empty element. To get around this I have added A?.maybeCombineAddition to Semiring

@pakoito
Copy link
Member

pakoito commented Jan 28, 2019

@juliankotrba Great work! tell us when it's ready to go!

@@ -0,0 +1,24 @@
---
Copy link
Member

Choose a reason for hiding this comment

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

Once you add the Kdocs you can remove this file and have the menu entry point to the generated apidocs. That already includes the type class hierarchy charts and will turn any kotln:ank:playground docs in runnable snippets in the arrow docs. The Kdocs are written directly in the class. See functor for an example. We no longer create files for each type class or data type and the ones we have are in the process of being converted to just point to the apidocs.

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 tried to update everything as you suggested, but I'm still doing something wrong. Ank is able to compile everything without errors but when running the Ank playground examples, it fails because of unresolved references to Int.semiring(). I guess it is basically the same problem as here in the playground example. If I change semiring with semigroup everything runs without problems. I also checked if the classpath of the docs module contains an up to date arrow-core-extensions.jar, because the Int.semiring() extension function is declared inside.
Any ideas?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@raulraja I just figured out that Ank has nothing to do with the actual playground snippet (:man_facepalming:), so I guess the problem is that the arrow playground server doesn't know about my changes yet. Sorry, my bad..

Copy link
Member

@pakoito pakoito left a comment

Choose a reason for hiding this comment

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

Stamping the PR to merge as soon as it's ready!

@raulraja
Copy link
Member

raulraja commented Feb 1, 2019

@juliankotrba Outstanding work and thank you so much for this contribution. 👏

@raulraja raulraja merged commit d6e064e into arrow-kt:master Feb 1, 2019
@juliankotrba
Copy link
Contributor Author

Thank you guys for the great support !!

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.

Add Semiring
4 participants