Coder Social home page Coder Social logo

lento-lang / lento-csharp Goto Github PK

View Code? Open in Web Editor NEW
6.0 1.0 0.0 376 KB

A strongly typed, and expressive functional programming language.

Home Page: http://lento-lang.org

License: MIT License

C# 100.00%
programming-language functional object-oriented strongly-typed lazy-evaluation expressive expressiveness programming language

lento-csharp's People

Contributors

williamragstad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

lento-csharp's Issues

Fix functions with code block body

Problem

Running

func(int e) = {e2 = e + 12; e2 * 2}

Throws the following error Parse error at line 1 column 2: Unexpected LeftParen token. Expected parameter identifier type.

Solution

Add support for function block bodies

Allow function interface declaration

Languages like Haskell allows functions to define a interface before the implementation.
This is something that would be useful for longer function declarations.

Real f(double k, double m, double x); # Like this?
f = k * x + m

Do some more research before implementing anything like this.

Assignment `=` expressiveness

So assignments in languages throughout history have always been implemented as statements. But in the recent functional era of languages code have gotten more and more expressive based. Though assignment expressions returned their value for allowing code like below is nice.

a = b = c = 0 # Multi assignment

I got the idea to fully combine assignments with pattern matching, making the expression return true or false weather the "matching" was successful. This way we could also write code like this

a = 2 * 2 + 1
b = 10 / 2
if (a = b) ...

and only use one operator for both assignment and comparison.
The = operator could therefore be seen as an infix operator evaluated right-to-left and updating the environment after matching every term in the expression, thus fulfilling the transitive property of equality. This would allow for code as show in the first example, AND in the latter.

Then one problem arises. What if we would like a variable to obtain the boolean value of if two other variables were the same.
Because = would be an boolean infix operator with side-effects. Wrapping an expression in parenthesis would force that expression to evaluate first and then return true or false if the matching was successful, meaning the terms were equal or one variable were undefined and therefore defined with the value of the other terms value (true), or the expression was not equal (false).
So, this code would be valid:

a = 7
b = 42
c = (a = b) # false

Linked to #12.

Variable scope shadowing

Allow scopes to shadow variable values defined in a parent environment. Such as in the example below:

x = 5
{
   x = 10
   print(x)
}

The reason for this is primarily to prohibit external/global code to interfere with function bodies. Hence allowing functions to not worrying about declaring local temporary variables that might already be defined in a parent scope.

Linked to #12.

Constant folding and variables

Check recursively for constant value expressions on variable declaration and constant fold on compile time.
First add a field on variables IsConstant: bool.

Add Lambda Functions

Add first class lambda functions. Inline anonymous function declarations with the following syntax:

plusOne(any f) = (int x, int y) -> f(x, y) + 1; # Lambda
add(int a, int b) = a + b
addPlusOne = plusOne(add)
addPlusOne(5, 6) # 12

Remove function declaration style ambiguities

So we need to determine a standard way for function vs variable declarations.
Easiest is to enfoce parenthesis around the parameter vector after the function name in declarations.

f(float x, int m) = 2*x + m #inferred return type
PI = 3.1415 # inferred value type

This makes it easy to differentiate between a variable and a parameterless function.
Both variable and function declarations can thereforce ommit return/value types and let those be inferred.

double f(float x, int m) = 2*x + m
Real PI = 3.1415

Add tuples the good way

So a tulle is simply a static data container. So (10) for example only holds the value 10, which 10 also does, hence they are equal. This is also true from a mathematical standpoint.
The interesting part is adding tuples of more elements in the same fashion. So ditching old thought of special syntax for tuple values, and using our good old' parenthesis.
Much like done in kesh and their data notation format. (Future container data types will follow similar syntax)

10 == 10 # trivial
10 == (10) # true, single element tuple cast to single expression
10 == (10, 0) # false, cannot compare integer and tuple of integers
(10, 0) == (10, 0) # trivial

Proper pattern matching

Currently the = operator is more of a naive "statementy" expression verifying that the variable in an assignment isn't already defined in the global scope. This has also caused problems such as #1.

The features suggested in this issue is to move towards the functional idea of the = operator. Meaning allowing LHS and RHS to be swapped at will (symmetric property), but most importantly the implementation must be compatible with #11.

The desired functionality would be:

  • Comparison
    a = 10 # true, side-effect: a is defined
    a = 10 # true, no side-effect
    5 * 2 = a # true, no side-effect
    b = 80
    c = b / 2 = a * 4 # true, side-effect: c is defined
    3.1415926535 = c / a # false (nice try tho)
  • Variable scope shadowing #2
    a = 10 # true, side-effect: a is defined in global scope
    a = 42 # false
    {
      a = 42 # true, side-effect: a is defined in local scope, shadow parent scope
    }
  • Destructuring with recursive pattern matching
    [a, 10, b | [(42, c), tail]] = [-2, 10, 25, (42, "Hello"), 0]
    # a = -2, b = 25, c = "Hello" and tail = [0] 
  • Reverse concatination
    firstname + " " + lastname = "John Doe"
    # firstname = "John" and lastname = "Doe"
  • Basic reverse aritmetics (for non-ambigious, single "answer" expressions. Not meaning + life = 42)
    a = 1000
    b ^ 3 = a
    # b = 10

More suggestions may come, this list is not complete.

Generic numerical type names and infinity

Add a general name for all sum types of integers (natural) and decimal (real) numbers. Integer = int | long | BigInt and Real = float | double. Hence, a function f can take all integer types.

f(Integer i) = i^2
f 1 // int
f 10000000 // long
f 10000000000000000 // BigInt

Thus all numers would consist of Number = Integer | Real which would be equal to the union of all numerical types in the language: Number = int | long | BigInt | float | double.

Additional Infinity

Infinities could be represented as a NaN constants of the type Number strictly larger or smaller than any other numbers.
These could therefore be hard-coded into the comparison operators ==, !=, <, <=, > and >=.

_ < Infinity = true
_ < -Infinity = false
_ > Infinity = false
_ > -Infinity = true
Infinity == Infinity = true
...

Add partial functions

Allow for creation of partially applied functions using currying.

f(int x, int y) = x + y
g = f(5) # Missing one argument, g becomes a function with the remaining arguments for f
g(37) # Finally evaluated to the integer 42 (All arguments passed)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.