What does #> operator mean in Scala Lift? - scala

Studying Lift I've immediately found a non-familiar #> operator. What exactly does it mean?
Example:
/**
* Put the messages in the li elements and clear
* any elements that have the clearable class.
*/
def render = "li *" #> msgs & ClearClearable
I can read the comment to know what's the line for, but am not sure about the code mechanics here.

The operator #> is used to create CSS Selector Transformers.
You provide a CSS selector as a string and then apply it to the given argument which can be a sequence, a string or a NodeSeq and get a function of type NodeSeq => NodeSeq that applies the transformations. The & is used to chain those transformations.

There is no operator in Scala, and hence, there is no #> operator.
What looks like an operator is a method, and if it is a method, it isn't in Scala but in a class. On Smalltalk, you would say, that you can send the object a #> - message.
Since the object on the right is a String, and String does not have a #>-message, there must be an implicit in scope, which takes a String, and transforms it into an object, which has such a method.
Implicits are only searched for in the code itself or directly imported code, not in code imported from imported code, so it shouldn't be too much work, to search for #>. Maybe your IDE can tell you, where it is defined.

Related

Special grammar in scala

I am very new at Scala and Spark area, and I found a strange grammar usage in the scala inside the Apache beam project and I can't understand.
Here is the strange place:
JavaDStream<Metadata> metadataDStream = mapWithStateDStream.map(new Tuple2MetadataFunction());
// register ReadReportDStream to report information related to this read.
new ReadReportDStream(metadataDStream.dstream(), id, getSourceName(source, id), stepName)
.register();
From the above code, you can see inside the constructor of ReadReportDstream, the first parameter is
metadataDStream.dstream()
If we go inside the dstream() method, you will see the following code:
class JavaDStream[T](val dstream: DStream[T])(implicit val classTag: ClassTag[T])
extends AbstractJavaDStreamLike[T, JavaDStream[T], JavaRDD[T]] {
I am wondering why it uses "metadataDStream.dstream()" in the constructor instead of "metadataDStream.dstream"? What does the "()" do?
It's mostly a question of convention. Methods with empty parameter lists are evaluated for their side-effects. Methods without parameters are assumed to be purely functional, and free of side-effects. You can read more about that here - https://docs.scala-lang.org/style/method-invocation.html (Arity-0 section)
So in that case, we're probably having some side-effects in metadataDStream.dstream(). However, syntactically writing it as metadataDStream.dstream won't be an error.

When to use asInstanceOf?

I'm trying out scalajs and am quite confused about how to access DOM elements using the org.scalajs.dom.html package.
By trial and error, I've discovered that some elements need to be cast to certain types using asInstanceOf, but some do not. Is there a general rule as to when and where asInstanceOf needs to be used?
For example, say I have a input element with id myinput. In order to access the value of the input I need to use asInstanceOf:
val content = document.getElementById("myinput").asInstanceOf[html.Input].value
But when it comes time to display content in my div of id contentdiv, the compiler didn't complain when I did not use asInstanceOf on the div element:
val mydiv = document.getElementById("contentdiv")
mydiv.innerHTML = content
Also, as a bonus is there a central place to find all the possible asInstanceOf arguments and a mapping of them to actual HTML elements?
The signature of getElementById is
def getElementById(id: String): DOMElement
and DOMElement is defined as
trait DOMElement extends js.Object {
var innerHTML: String = js.native
def appendChild(child: DOMElement): Unit = js.native
}
So, whenever you call getElementById you get a DOMElement back and the only operations you can perform on it are innerHTML and appendChild.
That's why your last example works without explicit casting.
But DOMElement is a very generic type. Sometimes you know that getElementById will return - say - an <input> element.
And that's when you can use asInstanceOf to inform the compiler about this extra piece of knowledge you have.
document.getElementById("myinput").asInstanceOf[html.Input].value
^
|
hey compiler, I KNOW this is going to be an html.Input,
please let me do my things and explode otherwise.
Needless to say, you need to be careful when using asInstanceOf. If you are wrong, the compiler won't be able to save you from a runtime crash this time.
To answer the second part of your question:
is there a central place to find all the possible asInstanceOf arguments and a mapping of them to actual HTML elements?
You can search for "extends HTMLElement" in Html.scala.

What does "!" mean in scala?

I am looking at a piece of code with the following:
graph.vertices.filter(!_._2._1)
I understand that _ are wildcard characters in scala but I do not know what the ! is supposed to do.
What does ! mean in scala?
Scala doesn't have operators at the syntax level. All operations are methods.
For example, there is no add operator in the syntax, but numbers have a + method:
2.+(3) // result is 5
When you write 2 + 3, that's actually syntax sugar for the expression above.
Any type can define a unary_! method, which is what !something gets desugared to. Booleans implement it, with the obvious meaning of logical negation ("not") that the exclamation mark has in other languages with C heritage.
In your question, the expression is an abbreviated form of the following call:
graph.vertices.filter { t => !(t._2._1) }
where t is a tuple-of-tuples, for which the first element of the second element has a type that implements unary_! and (as required by .filter) returns a Boolean. I would bet the money in my pocket that the element itself is a Boolean, in which case ! just means "not."
As Robert said, ! is a method name. It can be tricky determining which ! method is being used. For example, in the line of code:
val exitValue = command.!(ProcessLogger(stdoutWriter.println, stderrWriter.println))
where command is a String (or Seq), command can be implicitly converted to a ProcessBuilder, so its ! method would apply. Your IDE may be able to help. IntelliJ IDEA Ultimate was able to tell me where ! was defined.

Why we defined `def hello() = "world"`, but we can invoke it as "hello"?

If we have a method:
def hello() = "world"
I'm told that we can call it as:
hello()
also
hello
They both work and will output world, but why?
PS:
I see some words in this https://stackoverflow.com/a/12340289/342235:
No, actually, they are not. Even though they both call a method without parameters, one is a "method with zero parameter lists" while the other is a "method with one empty parameter list"
But I still not understand why hello would work
Scala allows the omission of parentheses on methods of arity-0 (no arguments):
You should only omit the parenthesis when there are no side effects to the invokation though
http://docs.scala-lang.org/style/method-invocation.html
As stated in Oliver Shaw's answer, Scala lets you leave out the parenthesis in functions with 0 arguments. As for why, it's likely to facilitate easy refactoring.
If you have a function that takes no arguments, and produces no side-effects, it's equivalent to an immutable value. If you always call such functions without parentheses, then you're free to change the underlying definition of the function to a value without having to refactor it everywhere it's referenced.
It's worth noting that val definitions are actually modeled as 0-arity methods in scala (unless specified with a private final beforehand).
Scala does something similar with its treatment of arity-1 functions defined on classes. You are allowed to omit the dot and the parenthesis. For example:
case class Foo(value: String) {
def prepend(value2: String) = Foo(value2 + value)
}
Foo("one").prepend("two")
// is the same as...
Foo("one") prepend "two"
This is because Scala models all operators as arity-1 functions. You can rewrite 1 + 2 as 1.+(2) and have it mean the same thing. Representing operators as fully-fledged functions has some nice qualities. You can expect to pass an operator anywhere that you could pass a function, and the definition of the operator is actually defined for class instances (as opposed to a language like C#, where the infix operators are actually static methods that use special syntactic sugar to let them be represented as infix).

Scala: why doesn't List[=>Int] work?

I've been working on learning the ins and outs of scala, and recently I've come across something I'm curious about.
As I understand, if I want to pass a block of code that is effectively lazily evaluated to a function, (without evaluating it on the spot) I could type:
def run(a: =>Int):Int = {...}
In this sense, the function run receives a block of code, that is yet to be evaluated, which it evaluates and returns the computed Int of. I then tried to extend this idea to the List data structure. Typing:
def run(a: List[=>Int]) = {...}
This however, returns an error. I was wondering why this is disallowed. How, other than by this syntax can I pass a list of unevaluated blocks of code?
=>Int is the syntax for by name parameters. =>Int is not a type, so it can't be used as a parameter to List. However, ()=>Int is a type. It's the type of nullary functions that return Int. So this works:
def run(a: List[()=>Int]) = {...}
by-name parameter is not a first-class type in Scala.
List[()=>Int] is one of the solution. otherwise, You can use following Lazy data structure.
https://gist.github.com/1164885
https://github.com/scalaz/scalaz/blob/v6.0.4/core/src/main/scala/scalaz/Name.scala#L99-107
https://github.com/scalaz/scalaz/blob/v7.0.0-M7/core/src/main/scala/scalaz/Name.scala#L37-L60
https://github.com/scala/scala/blob/v2.10.0/src/reflect/scala/reflect/internal/transform/Transforms.scala#L9-23
https://github.com/harrah/xsbt/blob/v0.12.1/compile/api/SafeLazy.scala
https://github.com/okomok/ken/blob/0.1.0/src/main/scala/com/github/okomok/ken/Lazy.scala
https://github.com/playframework/Play20/blob/2.1-RC1/framework/src/play/src/main/scala/play/api/libs/functional/Util.scala#L3-L11