8

In OCaml, the let...in expression allows you to created a named local variable in an expression rather than a statement. (Yes I know that everything is technically an expression, but Unit return values are fairly useless.) Here's a quick example in OCaml:

let square_the_sum a b = (* function definition *)
    let sum = a + b in (* declare a named local called sum *)
        sum * sum (* return the value of this expression *)

Here's what I would want the equivalent Scala to look like:

def squareTheSum(a: Int, b: Int): Int =
    let sum: Int = a + b in
        sum * sum

Is there anything in Scala that I can use to achieve this?

kiritsuku
  • 52,967
  • 18
  • 114
  • 136
GJK
  • 37,023
  • 8
  • 55
  • 74

1 Answers1

14

EDIT:

You learn something new every day, and this has been answered before.

object ForwardPipeContainer {
  implicit class ForwardPipe[A](val value: A) extends AnyVal {
    def |>[B](f: A => B): B = f(value)
  }
}

import ForwardPipeContainer._

def squareTheSum(a: Int, b: Int): Int = { a + b } |> { sum => sum * sum }

But I'd say that is not nearly as easy to read, and is not as flexible (it gets awkward with nested lets).


You can nest val and def in a def. There's no special syntax; you don't need a let.

def squareTheSum(a: Int, b: Int): Int = {
  val sum = a + b
  sum * sum
}

I don't see the readability being any different here at all. But if you want to only create the variable within the expression, you can still do that with curly braces like this:

val a = 2                                       //> a  : Int = 2
val b = 3                                       //> b  : Int = 3
val squareSum = { val sum = a + b; sum * sum }  //> squareSum  : Int = 25

There is no significant difference here between a semicolon and the word "in" (or you could move the expression to the next line, and pretend that "in" is implied if it makes it more OCaml-like :D).

val squareSum = {
  val sum = a + b // in
    sum * sum
}

Another, more technical, take on this: Clojure's 'let' equivalent in Scala. I think the resulting structures are pretty obtuse compared to the multi-statement form.

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • That's the way I'm currently doing it, and it's obviously 100% correct. I was just wondering if there was a way to do it using only expressions (I really like the readability of the let expression in OCaml). – GJK Dec 13 '13 at 14:33
  • @GJK if you treat `val` as a `let` keyword, yes, there is a way (nothing stops your from assigning function to val: `val plusOne = (x: Int) => x + 1`) – om-nom-nom Dec 13 '13 at 14:35
  • 2
    It's really more that I'm just curious if I can write Scala code using only expressions (so no `val` or 'statements' that return `Unit`). I'm not looking to program this way, I'm just a bit curious. (OK, you got me. I fascinated with Lisp.) – GJK Dec 13 '13 at 14:42
  • I see the point. I'd argue it's a functional-purity question rather than readability, since it's really hard to argue that the "in" form is actually more readable or clear (or less; it's just different). But that doesn't invalidate it. I don't believe you could do it without actual language support (a new keyword). I don't believe you could write an `in` postfix operator that worked this way. – Rob Napier Dec 13 '13 at 14:47
  • That said… if I were going to explore this further, I would probably look into macros, macro annotations, and quasiquotes. There are a lot of things you can do (especially in 2.11) to adjust Scala in interesting ways. I don't have a full answer there; but it's where I would start researching how to make a `let…in` construct. – Rob Napier Dec 13 '13 at 14:55
  • I haven't looked into the new Macros yet, but it looks like this might be the time to do that. Thanks for the help. I'll come back with what I find out. – GJK Dec 13 '13 at 15:07
  • I posted before your update, but thanks for the link. I hadn't found that one in my searches. As you said, maybe not the most readable form ever, but it certainly satisfied my curiosity. Thanks again. – GJK Dec 13 '13 at 15:08
  • You might also want to look at scalaz (typelevel.org). It adds more functional components onto Scala. – Rob Napier Dec 13 '13 at 15:13
  • Thx! in short: `let name=` ... `in` ... in Scala is the scala expression `{ val name = let_expression; in_expression_using_name }` which returns `in_expression_using_name`. Fancy! – Hartmut Pfarr May 16 '20 at 13:24