disclaimer: parts of this answers are generalizations of other answers found here.
Use lambdas without specifying their argument types
It's allowed to submit something like this: a=>a.size
instead of (a:String)=>a.size
.
Use ascii-symbols as identifiers.
These include !%&/?+*~'-^<>|
. Because they arent't letters, they get parsed seperated when they're next to letters.
Examples:
a=>b //ok
%=>% //error, parsed as one token
% => % //ok
val% =3 //ok
&contains+ //ok
if(x)&else* //ok
Use Set instead of contains
if (Seq(1,2,3,'A')contains x)... //wrong
if (Set(1,2,3,'A')(x))... //right
This is possible because Set[A] extends (A => Boolean)
.
Use a curried function when you need two arguments.
(a,b)=>... //wrong
a=>b=>... //right
Use the _
-syntax when possible
The rules for this are somewhat obscure, you have to play a little bit around sometimes to find the shortest way.
a=>a.map(b=>b.size)) //wrong
a=>a.map(_.size) //better
_.map(_.size) //right
Use partial application
a=>a+1 //wrong
_+1 //better, see above
1+ //right; this treats the method + of 1 as a function
Use ""+
instead of toString
a=>a.toString //wrong
a=>a+"" //right
Use strings as sequences
""
is sometimes the shortest way to create an empty sequence if you don't care about the actula type
Use BigInt to convert numbers to and from strings
The shortest way to convert a number to a string in a base other than base 10 is through BigInt's toString(base: Int)
method
Integer.toString(n,b) //wrong
BigInt(n)toString b //right
If you want to convert a string to a number, use BigInt.apply(s: String, base: Int)
Integer.parseInt(n,b) //wrong
BigInt(n,b) //right
Be aware that this returns a BigInt, which is useable like a number most of the times, but can't be used as an index for a sequence, for example.
Use Seq to create sequences
a::b::Nil //wrong
List(...) //also wrong
Vector(...) //even more wrong
Seq(...) //right
Array(...) //also wrong, except if you need a mutable sequence
Use Strings for Seqences of chars:
Seq('a','z') //wrong
"az" //right
Make use of Stream for infinite sequences
Some challenges ask for the n-th element of an infinite sequence. Stream is the perfect candidate for this. Remember that Stream[A] extends (Int => A)
, that is, a stream is a function from an index to the element at that index.
Stream.iterate(start)(x=>calculateNextElement(x))
Use symbolic operators instead of their wordy counterparts
:\
and :/
instead of foldRight
and foldLeft
a.foldLeft(z)(f) //wrong
(z/:a)(f) //right
a.foldRight(z)(f) //wrong
(a:\z)(f) //right
hashCode
-> ##
throw new Error()
-> ???
Use &
and |
instead of &&
and ||
They work the same for booleans, but will always evaluate both operands
Alias long method as functions
def r(x:Double)=math.sqrt(x) //wrong
var r=math.sqrt _ //right; r is of type (Double=>Double)
Know the functions in the standard library
This especially applies to the methods of collections.
Very useful methods are:
map
flatMap
filter
:/ and :\ (folds)
scanLeft and scanRight
sliding
grouped (only for iterators)
inits
headOption
drop and take
collect
find
zip
zipWithIndex3
distinct and/or toSet
startsWith
This applies to C++ as well with
#define
for example, but I admit it's nice thatdef
andval
are shorter. – Matthew Read – 2011-11-11T18:21:17.607Hm.
def
is the keyword to define a method, and a simple translation to c++ forval
is 'const', and it is a declaration, but the type is often inferred. The shortening is in the first case thetype=
which is closer totypedef
- isn't it? The second example isn't from me and it is new to me. I have to watch out, where to use it. – user unknown – 2011-11-11T19:01:00.933typedef long long ll;
is the same as#define ll long long
, so the latter's shorter by 1. But yeah,typedef
does work. Looking at theval
example again I definitely misread it. It seems even less Scala-specific.x = thingWithAReallyLongComplicatedNameForNoReason
is a pretty general strategy :P – Matthew Read – 2011-11-11T19:21:31.447@userunknown When you instantiate a
List
orArray
etc with syntaxval x = List(1,2,3)
you're just calling theapply
method on theList
object. (This technique for object creation is known as a "factory method", in contrast to using a constructor withnew
.) So above, we're just making a new variable that points to the same singleton object as the variable nameArray
. Since it's the same thing, all the methods, includingapply
, are available. – Luigi Plinge – 2011-11-12T17:36:28.080