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

#622 Make deprecations and feature flag more explicit in compile output and addressing some boring warnings #625

Merged
merged 2 commits into from Mar 23, 2018

Conversation

fmasion
Copy link
Contributor

@fmasion fmasion commented Mar 20, 2018

Thanks for your pull request. Please review the following guidelines.

  • Title includes issue id.
  • Description of the change added.
  • Commits are squashed.
  • Tests added.
  • Documentation added/updated.
  • Also please review CONTRIBUTING.md.

@anilgursel
Copy link
Collaborator

I am not sure if 30.secondsor 30 seconds (with import scala.language.postfixOps) preferable.

@fmasion
Copy link
Contributor Author

fmasion commented Mar 21, 2018

I agree 30 seconds is elegant but 30.seconds is less difficult for the compiler to figure out
Postfix operator notation is unsafe and should not be used.
see here Scala style recommendation

The new default is to emit warnings when used
The import is only a way to stop these warnings because postfix is massively used in DSLs

The same applies to :
functor map function
the prefered version is functor.map(function)

@sebady
Copy link
Contributor

sebady commented Mar 21, 2018

Since the scala style guide recommendation is clear here, I would vote we move away from Postfix. I think for test code though postfix improves readability in some cases and I would prefer to optionally continue to use it there.

@fmasion
Copy link
Contributor Author

fmasion commented Mar 21, 2018

@sebady tests, by nature, are DLSs :)
the magic of DSL is built upon implicits, postfix and magnet pattern

Don't conclude that postfix is evil
It's only a matter of balance between readability and safety

IMHO 30.seconds is still very readable and makes compiler faster ;)

@akara
Copy link
Contributor

akara commented Mar 22, 2018

Sorry for chiming in late. Agree with 30.seconds.

Copy link
Contributor

@akara akara left a comment

Choose a reason for hiding this comment

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

I'm good with pretty much all the changes. The use of higherKinds and implicitConversion is well placed. The only sticky one is the use of existentials. I'm still wondering whether that is well placed. Just need an explanation. Thanks so much for doing this work.

@@ -64,11 +64,13 @@ class ResolverRegistryExtension(system: ExtendedActorSystem) extends Extension w
*
* @param resolver The resolver implementation
*/
def register[T: ClassTag](resolver: Resolver[T]): Unit =
def register[T: ClassTag](resolver: Resolver[T]): Unit = {
import scala.language.existentials
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering about this liberal import scala.language.existentials. I'm not clear we're even using existential types in the code block below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly I'm not quite sure how to resolve this.
Here's the compiler output with -feature flag activated

[info] Compiling 1 Scala source to /Users/Hit/Dev/squbs/squbs-ext/target/scala-2.12/classes ...
[warn] /Users/Hit/Dev/squbs/squbs-ext/src/main/scala/org/squbs/resolver/Resolver.scala:70:32: inferred existential type (Class[_$1], org.squbs.resolver.Resolver[T]) forSome { type _$1 }, which cannot be expressed by wildcards,  should be enabled
[warn] by making the implicit value scala.language.existentials visible.
[warn] This can be achieved by adding the import clause 'import scala.language.existentials'
[warn] or by setting the compiler option -language:existentials.
[warn] See the Scaladoc for value scala.language.existentials for a discussion
[warn] why the feature should be explicitly enabled.
[warn]       case None => resolvers = (classTag[T].runtimeClass, resolver) :: resolvers
[warn]                                ^

I presume it's a warning because the code uses scala.reflect.classTag that makes the type only known at runtime ?
If you know how to fix this I'll do the change
I tried to reduce the "scope" of the import inside the function
this import is only a feature flag to tell the compiler "I know what I do don't warn me"

Copy link
Contributor

Choose a reason for hiding this comment

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

Seems like a pretty common issue with Class[_]. Lets take it as in your current PR then.

@@ -124,6 +124,7 @@ object ConfigUtil extends LazyLogging {


def getOptionalConfigList(path: String): Option[Seq[Config]] = {
import scala.language.existentials
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto on these.

Copy link
Contributor Author

@fmasion fmasion Mar 22, 2018

Choose a reason for hiding this comment

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

here the output for this one :

[warn] /Users/Hit/Dev/squbs/squbs-ext/src/main/scala/org/squbs/util/ConfigUtil.scala:129:9: inferred existential type Option[java.util.List[?0]] forSome { type ?0 <: com.typesafe.config.Config }, which cannot be expressed by wildcards,  should be enabled
[warn] by making the implicit value scala.language.existentials visible.
[warn] This can be achieved by adding the import clause 'import scala.language.existentials'
[warn] or by setting the compiler option -language:existentials.
[warn] See the Scaladoc for value scala.language.existentials for a discussion
[warn] why the feature should be explicitly enabled.
[warn]         try {
[warn]         ^
[warn] one warning found

the signature of underlying.getConfigList(path) is
List<? extends Config> getConfigList(String path); in java
that the scala compiler translates to :
java.util.List[?0]] forSome { type ?0 <: com.typesafe.config.Config}
subtypes of Config

We can remove the warning here by explicitly casting the java result like this :

    def getOptionalConfigList(path: String): Option[Seq[Config]] = {
      val list =
        try {
          Some(underlying.getConfigList(path).asScala.map(x=> x:Config)) //CAST HERE
        } catch {
          case e: ConfigException.Missing => None
        }
      list map (_.toSeq)
    }

Or by importing the

import scala.language.existentials

What do you prefer ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd be fine if it is a single cast with .asInstanceOf but not if we need to cast record by record. Please see whether that works. If not I'll accept it as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

even better :

    def getOptionalConfigList(path: String): Option[Seq[Config]] = try {
          Some(underlying.getConfigList(path).asScala)
        } catch {
          case e: ConfigException.Missing => None
        }

works without warning
javaConverters may do the job ?

…e output

plus addressing some "simple warnings" like postfix notation, implicitConversions and existentials
@fmasion
Copy link
Contributor Author

fmasion commented Mar 23, 2018

@akara updated and rebased

Copy link
Contributor

@akara akara left a comment

Choose a reason for hiding this comment

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

LGTM

@anilgursel anilgursel merged commit 7512afa into paypal:master Mar 23, 2018
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