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

Modernize scala syntax #87

Merged
merged 9 commits into from
Jan 29, 2024
Merged

Modernize scala syntax #87

merged 9 commits into from
Jan 29, 2024

Conversation

iilyak
Copy link
Contributor

@iilyak iilyak commented Jan 16, 2024

This PR removes deprecated forms of Scala syntax as well as

  • try to use Option type whenever possible
  • validates the types of inner elements in nested structures
  • add test cases for parsing

The main goal of the PR is to prepare the codebase for Scala version upgrade.

@iilyak iilyak marked this pull request as draft January 16, 2024 20:33
facets.addFields(doc, List(new CategoryPath(name, value)).asJava)
private def addFields(doc: Document, field0: Any): Unit = {
field0 match {
case (name: String, value: String, options: List[_]) =>
Copy link
Contributor

Choose a reason for hiding this comment

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

Should not we keep the parameter to the List[A] type here?

Copy link
Contributor Author

@iilyak iilyak Jan 17, 2024

Choose a reason for hiding this comment

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

If we would have List[A] then newer compiler would be producing warnings like this

warning: non-variable type argument (String, Any) in type pattern List[(String, Any)] (the underlying of List[(String, Any)]) is unchecked since it is eliminated by erasure
    case (name: String, value: String, options: List[(String, Any)]) =>
                                                     ^

New versions of scala do not have ability to match on inner type of containers. It cannot distinguish the following two cases

   case strings: List[Strings] => ...
   case integers: List[Int] => ...

As a result Scala designers decided to introduce the warning. The List[_] signals to compiler that user is not trying to match on the type so it is fine use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This also applies to generics. For example I cannot do

def asListOf[T](input: List[Any]): List[T] = {
    input match {
        case list: List[T] => list.asInstanceOf[List[T]]
        case _ => throw new Exception("")
    } 
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Personally I would prefer to keep the type and find a way to disable the warning. Because in this case I know what I am doing. But I couldn't find the way to control the warning. I'll try again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

BTW the following also not going to work.

input match {
    case list if (list.isInstanceOf[List[String]]) => ...

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've found a way

      case (name: String, value: String, options: List[(String, Any) @unchecked]) => ...

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'll add the types back and use @unchecked trick.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thank you @iilyak for both the explanation and the fix.

src/main/scala/com/cloudant/clouseau/IndexService.scala Outdated Show resolved Hide resolved
* and throw an exception if it encounters a non-string element.
*/

def elementWise[Inner](pf: PartialFunction[Any, Inner], orElse: PartialFunction[(List[Any], Any), List[Inner]]): PartialFunction[Any, List[Inner]] = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice abstraction!

@pgj
Copy link
Contributor

pgj commented Jan 18, 2024

Are you planning to update the CI as well? Apparently it tries to build the code with old Java (and Scala) and it fails.

@iilyak
Copy link
Contributor Author

iilyak commented Jan 18, 2024

Are you planning to update the CI as well? Apparently it tries to build the code with old Java (and Scala) and it fails.

This work doesn't make it possible to build full project with new Java/Scala. I just renovated syntax of *.scala files without addressing the dependencies.

Therefore updating CI is not needed.

@iilyak iilyak marked this pull request as ready for review January 22, 2024 18:39
Copy link
Contributor

@pgj pgj left a comment

Choose a reason for hiding this comment

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

Well done @iilyak! Looks good to me now.

The `ValueSource` requires overriding `equals` and `hashCode()`. These two are
automatically derived for case classes.
The previous implementation `case e => ...` produces following warning on
modern scala

```
warning: This catches all Throwables. If this is really intended, use
         `case e : Throwable` to clear this warning.
    case e =>
         ^
```
@iilyak iilyak force-pushed the modernize-scala-syntax branch from a12e954 to 22d7615 Compare January 29, 2024 19:55
Copy link
Contributor

@rnewson rnewson left a comment

Choose a reason for hiding this comment

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

lots of nice work here. a little puzzled at the commit that removes the procedural syntax that gets followed up by adding back in the : Unit = return type, but if it's a style thing or a future deprecation, fine.

@@ -107,7 +107,7 @@ class ClouseauQueryParser(version: Version,
fpRegex.matcher(str).matches()
}

private def setLowercaseExpandedTerms(field: String) {
private def setLowercaseExpandedTerms(field: String) = {
Copy link
Contributor

Choose a reason for hiding this comment

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

why avoid "procedural syntax" for all these functions where Unit is the appropriate result? Is it being removed in Scala 3?

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 procedural syntax has been removed in scala/scala#3076. I am not sure in which version of scala this landed though. I can find out the version.

Copy link
Contributor

Choose a reason for hiding this comment

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

no need. that's a perfectly good reason for the change.

lat: String,
multiplier: Double,
from: Point)
case class DistanceValueSource(ctx: SpatialContext,
Copy link
Contributor

Choose a reason for hiding this comment

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

neat.

@iilyak iilyak merged commit 1d84432 into master Jan 29, 2024
1 check passed
@iilyak iilyak deleted the modernize-scala-syntax branch January 29, 2024 21:13
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.

3 participants