Serene simple version post has been updated
This commit is contained in:
parent
7e55aa7476
commit
f30332a982
|
@ -6,30 +6,32 @@ categories: Programming
|
|||
tags: Serene language
|
||||
theme: dark
|
||||
---
|
||||
As you might already know I'm working on [my own programming language ](programming/my-new-programming-language/)
|
||||
As you might already know I'm working on [my own programming language ](/programming/my-new-programming-language/)
|
||||
for a while now. I'm still on early stages and I'm working on
|
||||
[choosing the right platform](/programming/choosing-the-target-platform/)
|
||||
for [#Serence](https://social.lxsameer.com/tags/Serene) and trying
|
||||
for [#Serene](https://social.lxsameer.com/tags/Serene) and trying
|
||||
to spend time on doing enough research and make decision based
|
||||
on facts, scientific papers and collected data from experiments
|
||||
rather than rushing into things and end up with a mess.
|
||||
I believe those languages that take their time and move slowly
|
||||
but with great research, plan and design are more successful in
|
||||
the long term (Thanks to **Pouya** for pointing it out). Take **Clojure**
|
||||
as an example. They are taking their time experimenting and validating
|
||||
as an example. They are taking their time, experimenting and validating
|
||||
their hypothesis. As a result, Clojure is a well designed, stable
|
||||
and highly backward compatible language with amazing productivity
|
||||
and highly backward compatible language with amazing and productive
|
||||
pace. However, some other languages like Python are extremely
|
||||
popular and consequently has more contributors. Dealing with all
|
||||
those contributors caused Python to move faster than it should and
|
||||
they ended up with some bad choices and horrible designs that
|
||||
fixing them requires an humongous effort. Little by little, it becomes
|
||||
fixing them requires an humongous effort. Gradually, it becomes
|
||||
harder and harder to fix those and move away from them. GIL is a good example,
|
||||
instead of fixing the issue and removing the GIL, they are introducing
|
||||
(at the of writing this article they added some basic support to latest
|
||||
python release but far from what they want)
|
||||
[something else](https://lwn.net/Articles/754162/) to fix the original
|
||||
problem but it might become a pain point itself. In order to avoid these kind
|
||||
of problem as much as possible I'm trying to take my time and do as
|
||||
many as experiments that I need.
|
||||
many as experiments as I need.
|
||||
|
||||
As I mentioned [earlier](/programming/choosing-the-target-platform/)
|
||||
I think **GraalVM** and **Truffle** is the right answer for
|
||||
|
@ -40,23 +42,23 @@ I'll update the experiment files accordingly at the
|
|||
[experiment reports](https://gitlab.com/serene-lang/experiment-reports/tree/master/001)
|
||||
repository.
|
||||
|
||||
I spend several days and implemented the pure java version. There repository
|
||||
I spent several days and implementing the pure java version. The repository
|
||||
of the simple version is available in the [gitlab repo](https://gitlab.com/serene-lang/simple-version).
|
||||
This version is a dumb but good enough lisp that I didn't paid too much attention
|
||||
to the details and created a very simple lisp which follows the specification below.
|
||||
This is a dummy version, but good enough lisp that I didn't paid too much attention
|
||||
to the details and just created a very simple lisp with the following specification.
|
||||
|
||||
> Node: In this post where ever I use the name **Serene** for the implementation,
|
||||
> Note: In this post whereever I use the name **Serene** for the implementation,
|
||||
> I'm referring to the simple version.
|
||||
|
||||
## Data structures
|
||||
Since I tried to avoid unnecessary work I didn't do much and implemented
|
||||
only one collection type which is the most important and essential data
|
||||
structure of Lisp, the mighty List. While my final goal is to have functional
|
||||
Since I tried to avoid unnecessary work, I didn't do much and implemented
|
||||
just one collection type which is the most important and essential data
|
||||
structure in any Lisp, the mighty List. While my final goal is to have functional
|
||||
data structures, this List is not a functional one and is a simple linked
|
||||
list. You can find the implementation under `serene.simple.ListNode`.
|
||||
|
||||
For the number types I just added the support for `Long` and `Double` numbers
|
||||
via `serene.simple.SNumber` class which act as a dispatcher between two inner
|
||||
For the number types I just added support for `Long` and `Double`
|
||||
via `serene.simple.SNumber` class which acts as a dispatcher between two inner
|
||||
classes.
|
||||
|
||||
For Strings, boolean types and `nil`, I just used the equivalent Java data
|
||||
|
@ -64,34 +66,34 @@ structures directly.
|
|||
|
||||
## Reader/Parser
|
||||
Instead of using a parser generator or a sophisticated parser, I just created
|
||||
a simple read ahead position based parser that reads two chars and call the
|
||||
a simple read ahead of position based parser that reads two chars and calls the
|
||||
appropriate method to create the corresponding `Node`. the `serene.simple.Node`
|
||||
is an abstract class that has just one important method, `eval`. The whole
|
||||
purpose of the reader is to parse the code and create an AST like data structure
|
||||
which each node extends the `Node` class (I should've create the interface for
|
||||
it but too lazy to change it now). The `eval` method of `ListNode` is a bit
|
||||
special. It calls the `eval` method on all the elements on the list
|
||||
and the call the first element as a function and pass the rest of elements
|
||||
and then calls the first element as a function and pass the rest of the elements
|
||||
as the arguments to that function. First rule of lisp :))
|
||||
|
||||
The `eval` method of `ListNode` contains more details regarding to java
|
||||
The `eval` method of `ListNode` contains lots more details regarding to java
|
||||
interop as well which I leave it out of this blog post.
|
||||
|
||||
## Scope
|
||||
Scope are simply a mapping between symbol names and values. Serene consists of two
|
||||
different scopes, both implemented `serene.simple.IScope` and extends
|
||||
Scopes are simply a mapping between symbol names and values. Serene consists of two
|
||||
different scopes, both implemented in `serene.simple.IScope` and extend
|
||||
`serene.simple.AScope` abstract class that contains the logic for symbol
|
||||
lookup and insertion. These two classes are `serene.simple.Scope` which
|
||||
is the general scope and it has a parent/child type of relationship with
|
||||
other instances of the same class or `serene.simple.RootScope` that is
|
||||
the top level scope. Beside that, `RootScope` is pre-populated with all
|
||||
the builtin functions and types.
|
||||
the built-in functions and types.
|
||||
|
||||
## Special forms
|
||||
Serene's [special forms](https://courses.cs.northwestern.edu/325/readings/special-forms.php)
|
||||
are pretty limited. All of them all classes which extend `serene.simple.SpecialForm`
|
||||
abstract class and inherit from `Node` indirectly. The difference between
|
||||
special form evaluation and function evaluation is that in case of special forms
|
||||
special form evaluation and function evaluation is that in case of special forms,
|
||||
Serene does not evaluate the arguments and leaves the evaluation to the special form
|
||||
itself. Here is the list of Serene's special forms:
|
||||
|
||||
|
@ -104,12 +106,12 @@ itself. Here is the list of Serene's special forms:
|
|||
```clojure
|
||||
(def inc (fn (x) (+ 1 x)))
|
||||
```
|
||||
`quote`: Prevent the evaluation of the given argument and return it as it is:
|
||||
`quote`: Prevents the evaluation of the given argument and return it as it is:
|
||||
|
||||
```clojure
|
||||
(quote (1 2 3 4)) ;; => (1 2 3 4)
|
||||
```
|
||||
`if`: Evaluated the body based on the return value of the given predicate.
|
||||
`if`: Evaluates the body based on the return value of the given predicate.
|
||||
|
||||
```clojure
|
||||
(if (= x 1)
|
||||
|
@ -117,7 +119,7 @@ itself. Here is the list of Serene's special forms:
|
|||
(...)) ;; if x is not 1
|
||||
```
|
||||
|
||||
`let`: Setup a local scope and runs its body using that scope.
|
||||
`let`: Sets a local scope and runs its body using that scope.
|
||||
|
||||
```cl
|
||||
(let ((x 1)
|
||||
|
@ -125,7 +127,7 @@ itself. Here is the list of Serene's special forms:
|
|||
(println x y))
|
||||
```
|
||||
|
||||
`do`: Simple group several expressions together.
|
||||
`do`: Simply groups several expressions together.
|
||||
|
||||
```clojure
|
||||
(do
|
||||
|
@ -156,17 +158,17 @@ important built in functions:
|
|||
|
||||
`(count coll)`: Returns the number of elements in the given COLL.
|
||||
|
||||
`(reverse coll)`: Return a new list which is the reverse of COLL.
|
||||
`(reverse coll)`: Returns a new list which is the reverse of COLL.
|
||||
|
||||
`(list 1 2 3..)`: Creates a list from the given arguments.
|
||||
|
||||
`(first coll)`: Returns the first element of the given COLL.
|
||||
|
||||
`(rest coll)`: Return all the elements beside the first of the given COLL.
|
||||
`(rest coll)`: Returns all the elements beside the first element of the given COLL.
|
||||
|
||||
`(doc fn)`: Return the documentation for the given symbol if any.
|
||||
`(doc fn)`: Returns the documentation for the given symbol if any.
|
||||
|
||||
`(reduce f coll initial)`: Reduce the COLL by applying F to its elements with the
|
||||
`(reduce f coll initial)`: Reduces the COLL by applying F to its elements with the
|
||||
INITIAL as the default value. F takes two arguments 1) the accumulation 2) the element.
|
||||
|
||||
`(new Class arg1 arg2...)`: Create a new instance of the given CLASS by passing the given
|
||||
|
@ -231,7 +233,7 @@ Here is an example program in Serene simple version (`benchmarks/fib.srns` in th
|
|||
|
||||
## What is missing ?
|
||||
Since Serene (simple) is an experimental language and I'll abandon it eventually.
|
||||
I didn't want to go into a rabbit hole and tried to get to the point as soon as possible.
|
||||
I didn't want to fall into the rabbit hole and just tried to get to the point as soon as possible.
|
||||
So I sacrificed lots of details. Here is a list of the most important missing
|
||||
details:
|
||||
|
||||
|
@ -239,12 +241,13 @@ details:
|
|||
is a massive task and needs tons of work which doesn't make sense for a toy
|
||||
project.
|
||||
* Unified function interface.
|
||||
* Requiring different namespaces
|
||||
* Requiring different namespaces.
|
||||
* A sophisticated parser. My Reader implementation is really cheap that
|
||||
suits a toy project. It might worth investigating on different solutions
|
||||
including using a parser generator or a head of time read implementation.
|
||||
* Primitive functions in Serene. I implemented lots of primitive functions
|
||||
in java rather than Serene itself mostly because of two reasons. Lack of
|
||||
including using a parser generator or ahead of time read implementation.
|
||||
* Primitive functions in Serene. I used lots of primitive functions
|
||||
from java rather than implementing them inSerene itself, mostly because
|
||||
of two reasons. Lack of
|
||||
macros and namespaces.
|
||||
* Decent [functional] data structures. The only data structure I implemented
|
||||
is list.
|
||||
|
@ -253,8 +256,8 @@ details:
|
|||
|
||||
## Conclusion
|
||||
I'm not going to improve the simple version anymore at this stage. I'm going to run
|
||||
some benchmarks to measure different aspect of the current implementation and then
|
||||
I'll move to the **Truffle** version to continue the
|
||||
some benchmarks and measure different aspects of the current implementation and then
|
||||
I'll move to the **Truffle** version and continue the
|
||||
[experiment(001)](https://gitlab.com/serene-lang/experiment-reports/tree/master/001).
|
||||
Please let me know if you have any comment or question on this topic. As always
|
||||
Please let me know if you have any comments or questions on this topic. As always
|
||||
I'm available throw social media and email.
|
||||
|
|
Loading…
Reference in New Issue