nbuilding/N-lang

Breaking change: change function argument syntax

Closed this issue · 4 comments

  • Use parentheses rather than square brackets
  • Require commas between name-type pairs
  • Argument and return types can be inferred, so syntactically they're optional

See https://discord.com/channels/710932856251351111/710936824121655396/878023177572347936

The following should have no syntax errors. Note that this is just for a syntax test; these examples may not necessarily pass type checking.

let square = (n) -> { return n * n }

let add = (a: float, b: float) -> { return a + b }

let getSchedule = ({ schedule }) -> { return schedule }

Not in this issue:

  • How the argument/return types are inferred
  • Allowing type annotations inside patterns (eg ((a: int, b: int)) -> ...)
  • Whether parentheses around a single argument can be omitted
  • A shorthand function expression that lets you just give an expression with an implicit return statement

Hmm, I think the syntax for functions with multiple arguments should be

let add = a: float -> b: float -> { return a + b }

This way, currying is explicit, and it better reflects the function type.

Doing it this way

let add = (a: float, b: float) -> { return a + b }

would then be a function of type (float, float) -> float (destructuring a tuple), which I think is more familiar at the cost of not supporting currying

See #258 (reply in thread)

I feel like the way that makes currying more explicit is just too unfamiliar to get people to use, while you can still do curring with the second syntax it is just not as explicit.

sure

Hmm, I should write a syntax test for this then

I feel like the way that makes currying more explicit is just too unfamiliar to get people to use, while you can still do curring with the second syntax it is just not as explicit.

So to clarify, if you say the second syntax should still be curried, so a function takes a float then returns a function that takes a second float and returns a float would be:

assert type (a: float, b: float) -> { return a + b } : float -> float -> float

While a function that takes a tuple of two floats and returns a float would look like:

assert type ((a, b): (float, float)) -> { return a + b } : (float, float) -> float

I'm not a fan of this because it results in ugly double parentheses if you want to take a tuple as an argument, and it's a bit confusing since the second function type annotation resembles the first function expression more