Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How pure and lazy can Scala be?

Tags:

This is just one of those "I was wondering..." questions.

Scala has immutable data structures and (optional) lazy vals etc.

How close can a Scala program be to one that is fully pure (in a functional programming sense) and fully lazy (or as Ingo points out, can it be sufficiently non-strict)? What values are unavoidably mutable and what evaluation unavoidably greedy?

like image 835
The Archetypal Paul Avatar asked Sep 26 '11 08:09

The Archetypal Paul


People also ask

Is Scala purely functional?

Scala is not a functional programming language. It is a statically typed object oriented language with closures.

Does Scala do lazy evaluation?

Lazy Evaluation in ScalaHaskell is a functional programming language that uses lazy evaluation by default.

What is lazy in Scala?

Vals and Lazy vals are present in Scala. lazy keyword changes the val to get lazily initialized. Lazy initialization means that whenever an object creation seems expensive, the lazy keyword can be stick before val.

Which languages have lazy evaluation?

Languages that support lazy evaluation are usually functional programming languages like Haskell, which is lazy by default. Some languages, like OCaml and Scheme, let you opt into lazy behavior. Other languages like Swift and Perl 6 support it only for lists.


1 Answers

Regarding lazyness - currently, passing a parameter to a method is by default strict:

def square(a: Int) = a * a 

but you use call-by-name parameters:

def square(a: =>Int) = a * a 

but this is not lazy in the sense that it computes the value only once when needed:

scala> square({println("calculating");5}) calculating calculating res0: Int = 25 

There's been some work into adding lazy method parameters, but it hasn't been integrated yet (the below declaration should print "calculating" from above only once):

def square(lazy a: Int) = a * a 

This is one piece that is missing, although you could simulate it with a local lazy val:

def square(ap: =>Int) = {   lazy val a = ap   a * a } 

Regarding mutability - there is nothing holding you back from writing immutable data structures and avoid mutation. You can do this in Java or C as well. In fact, some immutable data structures rely on the lazy primitive to achieve better complexity bounds, but the lazy primitive can be simulated in other languages as well - at the cost of extra syntax and boilerplate.

You can always write immutable data structures, lazy computations and fully pure programs in Scala. The problem is that the Scala programming model allows writing non pure programs as well, so the type checker can't always infer some properties of the program (such as purity) which it could infer given that the programming model was more restrictive.

For example, in a language with pure expressions the a * a in the call-by-name definition above (a: =>Int) could be optimized to evaluate a only once, regardless of the call-by-name semantics. If the language allows side-effects, then such an optimization is not always applicable.

like image 111
axel22 Avatar answered Nov 02 '22 11:11

axel22