asc-community / asc-community/AngouriMath

Lambdas & functions as entities

Open
#495 2 comments 0 reactions 0 assignees View on GitHub
Accepted Design document
Dominant language
C#
Stars
831
Forks
79
Avg merge
3h 23m
Merged PRs (30d)
309

Description

# Lambdas and function entities

This was planned for 1.6, but may be implemented much sooner (as soon as it's clear what we are going to do).

The plan consists of two key points: `apply` node and `lambda` node.

## Apply node

This node indicates that something is applied to something.

### Declaration

```cs
record Application(Entity Expression, LList Arguments);
```

`LList` is a linked list from Honk# 1.0.3+.

### Syntax

It will have syntax `apply(expr, ...)`, for example,
```
apply(a, x)
apply(a, x, y, z)
apply(1 + sqrt(y), x)
apply(y + y, y + y)
apply(y + y, y + y, apply(y + y, y + y))
```
etc.

With implicit parsing disabled by default, it will create an apply node for cases when an expression follows another expression, for example,
```
x x
a 5
sin x
f a b
```
but with priority higher than operators:
```
f a b = apply(apply(f, a), b)
f a b * 2 = apply(apply(f, a), b) * 2
```

The priority is higher than all others except for `Leaf` and is defined as
```
Func = 80 | NumericalOperation,
```
(this existed before for functions, no additional is added for application)

Comma-separated arguments are still allowed:

```
f a b
```
is the same as
```
f(a, b)
```

## Relaxing syntax for calling built-in functions

Currently you cannot have spaces between parentheses when calling a built-in function: `sin(x)` is valid,
but `sin (x)` will be interpreted as `sin * x`.

Now it won't be so with implicit parsing disabled. `sin (x)` will be interpreted as `sin(x)`.

Moreover, there will be no need to set parentheses. `sin x` will be equal to `sin(x)`. In this case, operator has a lower priority (that is, `sin x * x` is `(sin x) * x`).

## Lambda node

This node is for declaration lambdas. All logic about lambdas is going to be borrowed from lambda-calculus.

### Declaration

```cs
record Lambda(Variable Var, Entity Body);
```

### Syntax

List of variables separated by space, followed by `=>`, followed by the lambda's body. For example,
```
a => a + 3
a => a + b
a b => a + b (the same as a => b => a + b)
a b c => 3 (the same as a => b => c => 3)
a 3 => 3 Invalid
```

As synonym, `lambda` can be used:
```
lambda(x, x + 3)
lambda(x, y, x + 3)
lambda() // error
lambda(x) // error
```

#### Parameters syntax

Identifiers (variables), separated by space, before `=>`, substitute lambdas' parameters, so it reads from the right to the left. A non-variable interrupts it.

```
2 + a => 3 (the same as 2 + (a => 3), will be parsed to the left starting from =>)
a b quack c => 3
a + b * c => a + b (the same as a + b * (c => a + b))
```

The priority of `=>` will be lower than `provided` (and hence, lower than any other operator and construction).

### Logic

When simplifying, apply of lambda and something will result in lambda's body substituted with the argument:
```
(a b => a + b) 4
becomes
b => a + 4
```

When substituting, lambda may be alpha-converted on demand. For example:
```
(a b => a + b) b
```
will become
```
c => b + c
```

Derivative, integral, limit do not affect lambdas, if the latter are passed as parameters.

**Currying** of built-in functions is allowed via lambdas:
```
derivative (x + a)
```
is inner simplified to
```
y => derivative (x + a) y
```

## Differentiation and integration

Derivative and integral of an applied function now can be reduced by corresponding rules, for example:
```
derivative(f (x ^ 2), x)
```
will be reduced to
```
derivative(f (x ^ 2), x ^ 2) * derivative(x ^ 2, x)
```

## Breaking changes

By default, implicit parsing is enabled currently. To enable proper application syntax, it will be disabled (but remains as an option in the settings).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.