0

if this question is stupid, please understand.

I'm starting to learn scala with basic grammar.

But I don't understand why one is error other is not. I tested this with scala worksheet

val range = 1 to 10 by 3 toList
println(s"$range") //error

but the below is the List(actually Seq)

val range = (1 to 10 by 3).toList
println(s"$range") //no problem

I am using intellij 2018.2 ultimate edit.

Edit: Image was changed. I attached capture that is included error message not warning. enter image description here

Edit: I thought it is intellij version problem, but still doesn't work

Hyun
  • 566
  • 1
  • 3
  • 13
  • 1
    That is actually not an error. Its just that IntelliJ is confused by the compiler warning about the usage of postfix syntax. I will strongly advise you to start with more explicit syntax like `val range = Range(1, 11, 3).toList` or `Range.inclusive(1, 10, 3)` instead of `(1 to 10 by 3).toList` which involves the `implicits` over `Int` and postfix syntax. Once you have gotten a good grasp of things then you can move to more fancier stuff like this. – sarveshseri Nov 22 '18 at 08:50
  • it'a warning telling you should enable postfixOps if you use them (as you do) `import scala.language.postfixOps` – Raf Nov 22 '18 at 08:56
  • you can go into scala-> general -> advance language feature (tick mark it) – Raman Mishra Nov 22 '18 at 08:57
  • It's worth noting that the `List` object has a `.range()` method: `List.range(1,10,3)` No `.toList` conversion needed. – jwvh Nov 22 '18 at 08:58
  • it works for me in 2.11... please check your Scala version – Balaji Reddy Nov 22 '18 at 09:00
  • @BalajiReddy used scala 2.12.7 but not work – Hyun Nov 22 '18 at 09:16
  • not sure why. its not a syntactical error. I also use intellij IDE – Balaji Reddy Nov 22 '18 at 09:18
  • 1
    @HackingJ you need to end the line with post-fix operator either with [`;` or new line or defining a `val`, `def` after the post-fix operator](https://stackoverflow.com/a/53427053/432903). – prayagupa Nov 22 '18 at 09:43

2 Answers2

1

Either should work. In scala you can omit . with space for method invocation, which is probably broken version of haskell way. I think space is not recommended in scala as per official doc - STYLE GUIDE - METHOD INVOCATION

Example:

scala> val data = "guitar"
data: String = guitar

scala> data.toUpperCase
res8: String = GUITAR

you can use space instead of .,

scala> data toUpperCase
<console>:13: warning: postfix operator toUpperCase should be enabled
by making the implicit value scala.language.postfixOps visible.
This can be achieved by adding the import clause 'import scala.language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scaladoc for value scala.language.postfixOps for a discussion
why the feature should be explicitly enabled.
       data toUpperCase
            ^
res9: String = GUITAR

Since .toUpperCase is used after the data-structure without . (it is called postfix Operator) and compiler is simply warning about that. It can be fixed as the warning says,

scala> import scala.language.postfixOps
import scala.language.postfixOps

scala> data toUpperCase
res10: String = GUITAR

Same thing applies to your example. From readability perspective dot makes more readable in your example.

scala> (1 to 10 by 3).toList
res9: List[Int] = List(1, 4, 7, 10)

ALSO, post-fix operators could lead into bugs. For example, 1 + "11" toInt apply the toInt at the end of the computation but maybe what I wanted was 1 + "11".toInt

ALSO, ALSO regarding your bug you need to yell at compiler to stop chaining on toList with ; or a new line after post-fix operator. Or you can use val, def after post-fix operator that way compiler knows it is different context now.

scala> :paste

    import scala.language.postfixOps
    val range = 1 to 10 by 3 toList

    println(s"$range")

// Exiting paste mode, now interpreting.

List(1, 4, 7, 10)
import scala.language.postfixOps
range: List[Int] = List(1, 4, 7, 10)

Also read: Let’s drop postfix operators

prayagupa
  • 30,204
  • 14
  • 155
  • 192
1

If you're getting this error ...

Error:(2, 13) recursive lazy value range needs type

... it's because you're using infix (dot-less) notation where you shouldn't.

Put a blank line before the println(), or a semicolon after the toList and it will work.

The reason for the error is that instance.method(argument) can be turned into ...

instance method argument

... but the compiler is often confused if you try to turn instance.method into ...

instance method

The compiler will look for the missing argument until it hits a semicolon or a blank line.

jwvh
  • 50,871
  • 7
  • 38
  • 64