Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret function value wrapped in curly braces (ammonite issue)

Tags:

scala

ammonite

After reading What is the formal difference in Scala between braces and parentheses, and when should they be used?, I still don't know how to understand function value wrapped in {}.

Consider the following two REPL sessions:

@ val f = { (x: Int) =>
    x
    val y = x
    y
  }
f: Int => Int = ammonite.$sess.cmd30$$$Lambda$1765/0x0000000801346840@24c7b944
@ { (x: Int) =>
    x
    val y = x
    y
  }
cmd31.sc:3: not found: value x
  val y = x
          ^
Compilation Failed

I have several questions.

  1. Why the first snippet compiles while the second doesn't? In the first snippet, compiler knows the {...} as a whole is a function value. In the second snippet, only the (x: Int) => \n x part is function value (Sorry about the \n to indicate line break). Why?
  2. Regarding the { (x: Int) => \n ... }, when is it interpreted as function value and when is it not?
  3. Is the curly brace ({}) part of the function value, or only (...) => ... inside is function value? If it is a part it, does the form have a name? For example, I think (_ + _) could be called function value's placeholder syntax.

Update: This is purely an Ammonite issue. See answer for detail.

like image 370
Naitree Avatar asked Jun 24 '20 09:06

Naitree


People also ask

What do the curly brackets mean in code?

In programming, curly braces (the { and } characters) are used in a variety of ways. In C/C++, they are used to signify the start and end of a series of statements. In the following expression, everything between the { and } are executed if the variable mouseDOWNinText is true. See event loop.

What are the curly brackets {{ }} used for?

In writing, curly brackets or braces are used to indicate that certain words and/or sentences should be looked at as a group. Here is an example: Hello, please pick your pizza toppings {chicken, tomatoes, bacon, sausage, onion, pepper, olives} and then follow me.

How do you match curly braces with regular expressions?

To match literal curly braces, you have to escape them with \ . However, Apex Code uses \ as an escape, too, so you have to "escape the escape". You'll need to do this almost every time you want to use any sort of special characters in your regexp literally, which will happen more frequently than not.

What happens in a IF statement where there is no curly braces?

In C# curly braces are optional, but only for the first line of code. Meaning that if the statement does not have braces, only the line of code right after the if condition (the statement body) will be executed. Everything else falls outside the statement body and therefore will not be executed. Save this answer.


1 Answers

The problem here is ammonite.

Scala REPL has a paste mode allowing you to paste multiple lines before evaluating:

:paste
sealed trait X
class Implementation extends X // impossible without doing it at once
// Ctrl+D

Ammonite doesn't have such paste mode, but it allows you to perform multi-line copy paste... but wrapping them all in {} which ammonite would unwrap. So your code:

{ (x: Int) =>
  x
  val y = x
  y
}

is seen by compiler as

(x: Int) =>
  x // end of function definition
val y = x // new variable calling x, which isn't defined anywhere
y // call to undefined y, because previous line failed

The first example works because you have val f = so ammonite's parser cannot assume that all of your code is within one block, so it doesn't strip it before passing it into compiler.

As docs suggest if you don't want this behavior you should add another layer of curly brackets:

{{ (x: Int) =>
  x
  val y = x
  y
}}

This isn't a compiler and language specification issue as much as issue with some particular REPL implementation.

like image 191
Mateusz Kubuszok Avatar answered Oct 15 '22 10:10

Mateusz Kubuszok