title: Custom "let" expression in Scala
body: <p>I'd love to have <code>let</code> construct similar to the one in Haskell in Scala. I tried a few ways, but none seems to be good. Here's some code:</p>
  
  <pre class="lang-scala prettyprint-override"><code>object CustomLet extends App {
    val data = for (i &lt;- 1 to 1024; j &lt;- 1 to 512) yield (i % j) * i * (i + 1) - 1
  
    def heavyCalc() = { println("heavyCalc called"); data.sum }
  
    def doSomethingWithRes(res: Int) = {
      println(s"${res * res}")
      1
    }
  
    def cond(value: Int): Boolean = value &gt; 256
  
    // not really usable, even though it's an expression (2x heavyCalc calls)
    def withoutLet() = if (cond(heavyCalc())) doSomethingWithRes(heavyCalc()) else 0
  
    // not an expression
    def letWithVal(): Int = {
      val res = heavyCalc()
      if (cond(res)) doSomethingWithRes(res)
      else 0
    }
  
    // a lot of code to simulate "let", at least it is an expression
    def letWithMatch(): Int = heavyCalc() match {
      case res =&gt; if (cond(res)) doSomethingWithRes(res) else 0
    }
  
    // not perfect solution from
    // http://stackoverflow.com/questions/3241101/with-statement-equivalent-for-scala/3241249#3241249
    def let[A, B](param: A)(body: A =&gt; B): B = body(param)
  
    // not bad, but I'm not sure if it could handle more bindings at once
    def letWithApp(): Int = let(heavyCalc()) {res =&gt; if (cond(res)) doSomethingWithRes(res) else 0}
  
    List[(String, () =&gt; Int)](
      ("withoutLet", withoutLet),
      ("letWithVal", letWithVal),
      ("letWithMatch", letWithMatch),
      ("letWithApp", letWithApp)
    ).foreach(
      item =&gt; item match {
        case (title, func) =&gt; {
          println(s"executing $title")
          val ret = func()
          println(s"$title finished with $ret")
          println()
        }
      }
    )
  }
  </code></pre>
  
  <p>This is the ideal look of it (with only one binding, more could be separated by <code>,</code>; not sure about the <code>in</code> keyword):</p>
  
  <pre class="lang-scala prettyprint-override"><code>  // desired look
    def letTest(): Int =
      let res = heavyCalc() in
        if (cond(res)) doSomethingWithRes(res) else 0
  </code></pre>
  
  <p>I'm not sure if it's possible, but I have no experience with most of advanced Scala stuff like macros, so I can't really tell.</p>
  
  <p>EDIT1: To be clear, the main things I'm expecting from it are: being <strong>expression</strong> and relatively <strong>simple syntax</strong> (like the one outlined above).</p>