Why using "!" instead of "-" here for "reverse"?

scala> b
val res10: List[String] = List(a, b)

scala> c
val res11: List[String] = List(a, b, c, a, c)

scala> c.filter( -b.contains(_) )
                 ^
       error: value unary_- is not a member of Boolean
       did you mean unary_!?

scala> c.filter( ! b.contains(_) )
val res19: List[String] = List(c, c)

I think “-” means “reverse” such as the case of sortBy.
But here I must use the “!” instead.
please help explain it. thank you.

I’m not sure about sortBy, but filter() takes a function which returns a Boolean, so you have to use ! because that’s how you negate a Boolean.

@pengyh I’ve noticed you’ve been asking many basic questions regarding syntax. I don’t mean to be rude or anything, and we are more than happy to help, but I think you would benefit from a bit more serious study of Scala. Maybe pick up a book, or try out an online course? Effective Scala is intended to help people who are already programmers to get up to speed with Scala, sbt and so on.

3 Likes

Like @spamegg1 explained, negating a boolean is done with !. For filter, there is also a filterNot, which keeps elements for which the given function returns false.

In sortBy, a - does not mean “reverse”. The sortBy function extracts some key for the objects you want to sort by applying the given function, and then sorts those keys (which means it must be known how to sort them, i.e. there must be an Ordering for their type).

In the code from your other thread, the key you extract is an Int. If you negate two ints, their order is swapped: if a < b, then -a > -b. That is why they are reversed, but this method only works for numbers.

A more clear, albeit a bit more verbose, way which works for any type with an Ordering is to use a reversed Ordering with sorted, e.g.

list.sorted(Ordering.by(_._2).reverse)
//instead of list.sortBy(-_._2)

Ordering.by creates an ordering for the type in your list, the passed in function works like the one you give to sortBy. Note that reverse is called on the Ordering, not on the List`, so it doesn’t first sort in the wrong order and then reverse the whole list.

2 Likes

As @spamegg1 mentioned, many of these questions are fairly basic. I don’t know where you are in your study of programming and software development but there could be some benefit in getting more foundational knowledge in place to help you. I teach CS1 and CS2 using Scala I have links to the video lectures on YouTube that you can find from the websites.

I haven’t had a chance to update them to Scala 3. That is a future project.

2 Likes

I think it means “inverse”. I don’t actually know why we need a different unary prefix operator for boolean.

It’s too bad the message says

did you mean unary_!?

which suggests the hypothetical

scala> c.filter( !? b.contains(_) )

and a great addition to Scala 3 would be unary prefix ops which are arbitrary strings of ! and ?.

Other synonyms

scala> c.filter( !b.contains(_) )
val res1: List[Int] = List()

scala> c.filterNot( b.contains(_) )
val res2: List[Int] = List()

scala> c.filterNot(b.contains)
val res3: List[Int] = List()

The other gentle suggestions for further reading are great, but also indicate why the forums are intimidating, as opposed to chat where you can “ask me anything”.

I would ask Odersky why he doesn’t have a dog. Dogs make everything better. I know why I don’t have a dog. I’m sure there is an intern at EPFL who would volunteer to walk the dog, there is nothing worse than when you’re a student at university and you can’t have a dog, but if only a professor, modulo allergies, had a dog, at least you could take one for a walk and throw a stick.

1 Like

The - operator is for the negation of numeric values. -a is similar to -5, just like one would expect from math. Filter needs a function that returns a Boolean value. The ! operator is Boolean negation. Note that these aren’t things that Scala created. I know that both go back to C and are used in all C-family languages.

The thing is, neither means “reverse”. It just so happens that sorting the negation of numbers puts them in reverse order, but that isn’t because - means reverse. - means arithmetic negation in the mathematical sense.

The reason that people are suggesting further reading or other sources is that your questions indicate that there are certain key concepts that you haven’t yet learned, and many might not be Scala specific. While you can keep trying to go forward and just get past one problem at a time, you would inevitably be better off going back and gaining a more fundamental understanding of what is going on. If you don’t, you will move forward with significant misconceptions that will likely cause problems in the future. We aren’t trying to be rude or abrasive, we are trying to help you out so that you will be a better developer in the future.

2 Likes

I’d be grateful if you happen to know where ! for negation came from.

I just pulled my old K&R off the shelf, which is still fascinating.

Under “anachronisms”, it reminds us that op= was originally =op as in x=-1.

It asks whether if (!inword) is more perspicacious than if (inword == 0).

Also the heading, “What’s in a name?” in the language appendix must have appealed to me back then.

1 Like

I actually don’t. I was tempted to say earlier that ! originated in C, but I don’t know that for certain. Given that C was based on the B language, it is possible it came from there.

I find it interesting that the two inword examples imply different types for many newer languages, including Scala. The ability to treat integers as boolean values in C went out of style and beginning around Java things changed so that the argument to if has to be a Boolean. Technically, C didn’t have a Boolean type so that wasn’t really an option. I wonder if anyone here knows the first language that introduced Boolean as its own type and whether that language predates C or not.

1 Like

It seems to me that either all of the bits are zero, or otherwise, irrespective of how many bits. I guess I am old school. I am also a staunch defender of

var x: Int = _

which has been subject to much calumny.

The recent conversation on one of the forums about a student implementing a compiler for a certain dialect of C was also an occasion for nostalgia of a kind.

An article today about employers switching from requiring 4-year degrees to training in apprentice programs makes me wonder if certain questions of professional practice will someday reduce to questions of provenance, much as, for example, pianists trace their training back to Beethoven.

1 Like

I’m with you on the = _ syntax. Getting default values in Scala is hard. The fun one is when the type is a parameter. As far as I can tell, the best syntax for that is null.asInstanceOf[A] and that is clearly ugly.

What you describe is how many parts of academia work. You are often known by who your Ph.D. advisor was and there is a form of lineage there.

1 Like

Thanks for all your suggestions and help. It make things clear to me now.
Yes I would take time to pick up a whole book about Scala for learning.
Which book do you suggest for the first book to beginners?
I have the experience on other languages such as C, ruby, perl and python.

Thanks.

The de-facto book for Scala is “Programming in Scala” (Amazon.com). The newest edition covers Scala 3. One thing to keep in mind though is that it is a book on the Scala language. At some point, you probably want to read a book that is aimed more at the general concepts of programming and computer science and not at specific languages.