Jena - pure functional Lisp descendant

taqmuraz

Taqmuraz

Posted on December 28, 2023

Jena - pure functional Lisp descendant

Yes, Jena -- one more programming language. I am the author.

Why do I develop a new programming language?

For my personal use, at least. I have a lot of ideas that most of modern programming languages don't meet. I am tired of compromises.

What is a purpose of this language?

I would like to write short and declarative code. With no syntax garbage such as classes or interfaces.
Next, I need as independent language as possible. But, it must communicate with at least one existing language, to ensure it will not die right after birth. I chose Java. Simple, portable, fast enough -- all I need.

Common idea

Lisp influenced me a lot. Maybe, it is my most loved language. After Jena, of course.
Lisp has a simple syntax, based on lists. Commonly list is interpreted as a function call.
(a b c)in Lisp is the same, as a(b, c) in C.
In Jena it would be like as a b c. Yes, that simple. No annoying parentheses everywhere, same flexibility.

Everything is a function

In Jena everything is a function. Any function always accepts only one parameter and always returns another function. Jena has no types (or classes), objects or methods. You may think that such OOP things are necessary, but soon you will see -- they are not.

Everything is an expression

Another Jena primary concept -- everything is an expression. Jena does not require you to declare something before you use it. File with Jena program contains only one expression. It may be even string or number literal.

Literals

Every Jena expression is a literal or a list of literals.
For example, 1 is just a number literal, when print 1 is a list of literals : name literal and number literal.
All existing literals with examples :

  • number : 1, 2, 150, 1.5, 0.25
  • string : "hello, world", "Hello\nI am Peter"
  • operator : + - * / % == != > < & | !
  • name : peter, a, b, myValue, his_value
  • symbol : .name, .people, .count
  • parentheses : (1), (a + b), (a + (b.c))
  • array : [], [1, 5.2, "text"], [[1 + b], value]
  • entry : a:b, "code":23, (1 + 9):"ten"
  • map : {}, { 1:"first", 2:"second" }, { .age:25, .name:"Peter" }
  • none : ()
  • binding : name = "John" => println name, a = 10 => print(a == 10)
  • function : arg -> arg * 2, a -> b -> a + b, () -> 10.times

Code examples

I know, you can't wait to see code examples.
Let us look at the next simple C program :

#include "stdio.h"
int main()
{
    int a, b;
    scanf("%d", &a);
    scanf("%d", &b);
    printf("a + b = %d", a + b);
}
Enter fullscreen mode Exit fullscreen mode

It reads from the input stream two lines as decimal integer numbers and writes their sum to the output stream.
How will look Jena program that does the same?

print(readInt() + readInt())
Enter fullscreen mode Exit fullscreen mode

Well, too simple. Maybe, we want to calculate sum of squares?
C:

#include "stdio.h"
int main()
{
    int a, b;
    scanf("%d", &a);
    scanf("%d", &b);
    printf("a + b = %d", a * a + b * b);
}
Enter fullscreen mode Exit fullscreen mode

Jena:

a = readInt() =>
b = readInt() =>
print(a * a + (b * b))
Enter fullscreen mode Exit fullscreen mode

In Jena operators are just functions, and they don't define dedicated execution order. It means, that expression 1 + 2 * 3 will have 9 as a result, but never 7, because interpreter will see ((((1 +) 2) *) 3).
What is 1 + then?

True functions

Everything is a function. Numbers as well.
Expression a b is a function call expression, where a is a function and bis an argument. So, in expression 1 + function is 1 and argument is +. What the result of this expression? Another function, right. To complete addition, we have to call that another function, giving second argument.
Let us write a function, that will behave as a 2D vector.
vector.jena

x -> vec = self => y ->
{
    .x:x,
    .y:y,
    +:v -> vec (x + (v.x)) (y + (v.y)),
    .printTo:p -> ["x = ", x, " y = ", y].each p,
}
Enter fullscreen mode Exit fullscreen mode

And now we are going to use that function :
main.jena

vector = source "vector.jena" =>
a = vector 1 5 =>
b = vector (-10) 11 =>
(a + b).printTo print
Enter fullscreen mode Exit fullscreen mode

As you see, self is a special name. It is a reference to the function, expressed by the outer function literal.

That's all for today.
Thanks if you read that to the end.

Please, ask questions or share critique in comments.

💖 💪 🙅 🚩
taqmuraz
Taqmuraz

Posted on December 28, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related