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

Make Free/FreeApplicative constructors private #613

Merged
merged 2 commits into from
Nov 9, 2015

Conversation

ceedubs
Copy link
Contributor

@ceedubs ceedubs commented Nov 8, 2015

There are a couple of reasons this might be a good idea.

Currently it's possible to observe a difference when calling
.map(identity) on a Free instance:

scala> import cats.free._; import cats.implicits._
import cats.free._
import cats.implicits._

scala> def f(x: Free[Option, Int]) = x match {
     |   case Free.Pure(i) => i
     |   case _ => 0
     | }
f: (x: cats.free.Free[Option,Int])Int

scala> val x: Free[Option, Int] = Free.pure(3)
x: cats.free.Free[Option,Int] = Pure(3)

scala> f(x)
res0: Int = 3

scala> f(x.map(identity))
res1: Int = 0

Making these private also frees us up to change the internal
representation in the future without breaking user code.

There are a couple of reasons this might be a good idea.

Currently it's possible to observe a difference when calling
`.map(identity)` on a `Free` instance:

```scala
scala> import cats.free._; import cats.implicits._
import cats.free._
import cats.implicits._

scala> def f(x: Free[Option, Int]) = x match {
     |   case Free.Pure(i) => i
     |   case _ => 0
     | }
f: (x: cats.free.Free[Option,Int])Int

scala> val x: Free[Option, Int] = Free.pure(3)
x: cats.free.Free[Option,Int] = Pure(3)

scala> f(x)
res0: Int = 3

scala> f(x.map(identity))
res1: Int = 0
```

Making these private also frees us up to change the internal
representation in the future without breaking user code.
@adelbertc
Copy link
Contributor

If I remember correctly I made this change before but reverted it - on one hand hiding the constructors ensures lawful-ness.. on the other hand hiding constructors prevents users from writing their own tail-recursive implementation, though perhaps we can say the methods we provide on Free(Applicative) are tail recursive and people should just use those instead? I think @non was the one who convinced me?

@non
Copy link
Contributor

non commented Nov 8, 2015

The place where I definite care about this is Streaming, where it's totally plausible that a user might want to write their own tail-recursive methods. I don't have as much sense whether that is an issue here.

@non
Copy link
Contributor

non commented Nov 8, 2015

(There's also a legitimate Travis build failure.)

Also make TrampolineFunctions package-private, since it's just a
workaround for a scalac bug and isn't really intended to be used
directly.
@codecov-io
Copy link

Current coverage is 75.99%

Merging #613 into master will decrease coverage by -0.45% as of ec7de90

@@            master    #613   diff @@
======================================
  Files          161     159     -2
  Stmts         2208    2066   -142
  Branches        70      70       
  Methods          0       0       
======================================
- Hit           1688    1570   -118
  Partial          0       0       
+ Missed         520     496    -24

Review entire Coverage Diff as of ec7de90

Powered by Codecov. Updated on successful CI builds.

@ceedubs
Copy link
Contributor Author

ceedubs commented Nov 9, 2015

Thanks for the input @adelbertc and @non. I'm inclined to make these private for the reasons stated in my original comment. It's always easier to open them up in the future if people need access to them for custom tail-recursive methods than it is to remove them once they are part of a public API. I would guess that people are more likely to want to write custom tail-recursive methods for Streaming, and we may just have to bite the bullet there. What do you think?

I've also fixed the build error (thanks Travis).

@non
Copy link
Contributor

non commented Nov 9, 2015

I'm fine with making these private (and opening them up later if necessary).

I just wanted to make the argument for why some types (e.g. Streaming) should remain public.

@non
Copy link
Contributor

non commented Nov 9, 2015

👍

@aryairani
Copy link
Contributor

Squash? :)

@ceedubs
Copy link
Contributor Author

ceedubs commented Nov 9, 2015

@refried I can squash if people want me to, but I think per Cats contributor guidelines that would mean closing this PR and opening a new one from a different branch which seems like it might be overkill for just having one extra commit. Happy to do whatever people want, though.

@aryairani
Copy link
Contributor

@ceedubs Oops, I hadn’t read them!

I wasn’t trying to reduce the number of commits in the PR, but reduce the number of non-compiling commits. Maybe it’s not a big deal though?

@adelbertc
Copy link
Contributor

👍

adelbertc added a commit that referenced this pull request Nov 9, 2015
Make Free/FreeApplicative constructors private
@adelbertc adelbertc merged commit a38fdb2 into typelevel:master Nov 9, 2015
@ceedubs ceedubs deleted the hide-free-constructors branch November 15, 2015 23:38
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.

6 participants