lento-lang / lento-csharp Goto Github PK
View Code? Open in Web Editor NEWA strongly typed, and expressive functional programming language.
Home Page: http://lento-lang.org
License: MIT License
A strongly typed, and expressive functional programming language.
Home Page: http://lento-lang.org
License: MIT License
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
.
Add support for function block bodies
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.
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.
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.
Check recursively for constant value expressions on variable declaration and constant fold on compile time.
First add a field on variables IsConstant: bool
.
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
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
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
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:
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)
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
}
[a, 10, b | [(42, c), tail]] = [-2, 10, 25, (42, "Hello"), 0]
# a = -2, b = 25, c = "Hello" and tail = [0]
firstname + " " + lastname = "John Doe"
# firstname = "John" and lastname = "Doe"
meaning + life = 42
)
a = 1000
b ^ 3 = a
# b = 10
More suggestions may come, this list is not complete.
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
.
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
...
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)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.