What is the name given to the way that I can create Strings in Scala like this?
val foo = "hello"
val bar = "world"
val s = s"$foo $bar" /// <-- Does this construct have a name?
I'm trying to find if Javascript has a similar way of building strings and I wasn't sure what to search for.
It's called string interpolation
ES6 has 'template strings', if you're using ES5 you're out of luck. Coffeescript has string interpolation that compiles to regular string concatenation.
I'd like to add that underscore.js has a nice templating function, though it's not exactly string interpolation.
Related
This article has this code here:
// flatMap
let flatCars = peopleArray.flatMap({ $0.cars })
print("Flatmap: \(flatCars)")
/*Result: Flatmap: ["i20", "Swift VXI", "Crita", "Swift VXI"]*/
What is going on in the print function. Why can it not just be this:
print("Flatmap: ", flatCars) //typed outside of IDE
Is "Flatmap: \(flatCars)" meant to be string formatting similar to javascript's template literals e.g "Flatmap: ${flatCars}" in Js?
Useful resources for better understanding would be great.
Yes, it is similar to ${} in javaScript, and it is called String Interpolation:
String interpolation is a way to construct a new String value from a mix of constants, variables, literals, and expressions by including their values inside a string literal.
You can find more detailed information in here: Swift Documentation
under the section "String Interpolation".
I was looking at this solution for calculating the product of a string's unicode code points.
One of the answers includes this snippet:
"Hello" map (i => BigInt(i)) product
I had no idea this would compile. Can someone explain to me how this works? Why does it work with the whitespaces?
The line can be read as
{val string = "Hello"
val charList = string.map(i=>BigInt(i))
charList.product}
which returns the product as the result of the block of code
You are allowed to omit . for method calls. In Scala, foo.bar is equivalent to foo bar. And foo.bar(baz) is the same as foo bar baz.
This style is not often used, and usually discouraged for all but the simplest code. This line overall is equivalent to:
"Hello".map(i => BigInt(i)).product
I'm wondering how the scala.xml library is implemented, to get an Elem-instance out of XML.
So I can write:
val xml = {
<myxml>
Some wired text withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
</myxml>
}
xml.text
String =
"
Some text wired withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
"
A look at the source code doesn't gave me the insight, how this is achieved.
Is the "XML-detection" a (hard) scala language feature or is it an internal DSL? Because I would like to build my own things like this:
var x = LatexCode {
\sqrt{\frac{a}{b}}
}
x.toString
"\sqrt{\frac{a}{b}}"
or
var y = PythonCode {
>>> import something
>>> something.func()
}
y.toString
"""import something ..."""
y.execute // e.g. passed to python as python-script
or
object o extends PythonCode {
import x
x.y()
}
o.toString
"""import x...."""
I would like to avoid using such things like PythonCode { """import ...""" } as "DSL". And in scala, XML is magically transported to a scala.xml-Class; same with Symbol which I can get with val a = 'symoblname, but in the source code there's no clue how this is implemented.
How can I do something like that on myself, preferably as internal DSL?
XML is a scala language feature (*) - see the SLS, section 1.5.
I think that string interpolation is coming in 2.10, however, which would at least allow you to define your own DSL:
val someLatex = latex"""\sqrt{\frac{a}{b}}}"""
It's an experimental feature explained more fully in the SIP but has been additionally blogged about by the prolific Daniel Sobral. The point of this is (of course) that the correctness of the code in the String can be checked at compile time (well, to the extent possible in an untyped language :-) and your IDE can even help you write it (well, to the extent possible in an untyped language :-( )
(*) - We might expect this to change in the future given the many shortcomings of the implementation. My understanding is that a combination of string interpolation and anti-xml may yet be the one true way.
It's an XML literal, just like "foo" is a string literal, 42 is an integer literal, 12.34 is a floating point literal, 'foo is a symbol literal, (foo) => foo + 1 is a function literal and so on.
Scala has fewer literals than other languages (for example, it doesn't have array literals or regexp literals), but it does have XML literals.
Note that in Scala 2.10 string literals become vastly more powerful by allowing you to intercept and re-interpret them using StringContexts. These more powerful string literals would allow you to implement all of your snippets, including XML without separate language support. It is likely that XML literals will be removed in a future version of the language.
In Java, it's a common best practice to do string concatenation with StringBuilder due to the poor performance of appending strings using the + operator. Is the same practice recommended for Scala or has the language improved on how java performs its string concatenation?
Scala uses Java strings (java.lang.String), so its string concatenation is the same as Java's: the same thing is taking place in both. (The runtime is the same, after all.) There is a special StringBuilder class in Scala, that "provides an API compatible with java.lang.StringBuilder"; see http://www.scala-lang.org/api/2.7.5/scala/StringBuilder.html.
But in terms of "best practices", I think most people would generally consider it better to write simple, clear code than maximally efficient code, except when there's an actual performance problem or a good reason to expect one. The + operator doesn't really have "poor performance", it's just that s += "foo" is equivalent to s = s + "foo" (i.e. it creates a new String object), which means that, if you're doing a lot of concatenations to (what looks like) "a single string", you can avoid creating unnecessary objects — and repeatedly recopying earlier portions from one string to another — by using a StringBuilder instead of a String. Usually the difference is not important. (Of course, "simple, clear code" is slightly contradictory: using += is simpler, using StringBuilder is clearer. But still, the decision should usually be based on code-writing considerations rather than minor performance considerations.)
Scalas String concatenation works the same way as Javas does.
val x = 5
"a"+"b"+x+"c"
is translated to
new StringBuilder()).append("ab").append(BoxesRunTime.boxToInteger(x)).append("c").toString()
StringBuilder is scala.collection.mutable.StringBuilder. That's the reason why the value appended to the StringBuilder is boxed by the compiler.
You can check the behavior by decompile the bytecode with javap.
I want to add: if you have a sequence of strings, then there is already a method to create a new string out of them (all items, concatenated). It's called mkString.
Example: (http://ideone.com/QJhkAG)
val example = Seq("11111", "2222", "333", "444444")
val result = example.mkString
println(result) // prints "111112222333444444"
Scala uses java.lang.String as the type for strings, so it is subject to the same characteristics.
I need to print a formatted string containing scala.Long.
java.lang.String.format() is incompatible with scala.Long (compile time) and RichLong (java.util.IllegalFormatConversionException)
Compiler warns about deprecation of Integer on the following working code:
val number:Long = 3243
String.format("%d", new java.lang.Long(number))
Should I change fomatter, data type or something else?
You can try something like:
val number: Long = 3243
"%d".format(number)
The format method in Scala exists directly on instances of String, so you don't need/want the static class method. You also don't need to manually box the long primitive, let the compiler take care of all that for you!
String.format("%d", new java.lang.Integer(number))
is therefore better written as
"%d".format(number)
#Bruno's answer is what you should use in most cases.
If you must use a Java method to do the formatting, use
String.format("%d",number.asInstanceOf[AnyRef])
which will box the Long nicely for Java.