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
|
tags: Serene language
|
||||||
theme: dark
|
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
|
for a while now. I'm still on early stages and I'm working on
|
||||||
[choosing the right platform](/programming/choosing-the-target-platform/)
|
[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
|
to spend time on doing enough research and make decision based
|
||||||
on facts, scientific papers and collected data from experiments
|
on facts, scientific papers and collected data from experiments
|
||||||
rather than rushing into things and end up with a mess.
|
rather than rushing into things and end up with a mess.
|
||||||
I believe those languages that take their time and move slowly
|
I believe those languages that take their time and move slowly
|
||||||
but with great research, plan and design are more successful in
|
but with great research, plan and design are more successful in
|
||||||
the long term (Thanks to **Pouya** for pointing it out). Take **Clojure**
|
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
|
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
|
pace. However, some other languages like Python are extremely
|
||||||
popular and consequently has more contributors. Dealing with all
|
popular and consequently has more contributors. Dealing with all
|
||||||
those contributors caused Python to move faster than it should and
|
those contributors caused Python to move faster than it should and
|
||||||
they ended up with some bad choices and horrible designs that
|
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,
|
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
|
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
|
[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
|
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
|
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/)
|
As I mentioned [earlier](/programming/choosing-the-target-platform/)
|
||||||
I think **GraalVM** and **Truffle** is the right answer for
|
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)
|
[experiment reports](https://gitlab.com/serene-lang/experiment-reports/tree/master/001)
|
||||||
repository.
|
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).
|
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
|
This is a dummy version, 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.
|
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.
|
> I'm referring to the simple version.
|
||||||
|
|
||||||
## Data structures
|
## Data structures
|
||||||
Since I tried to avoid unnecessary work I didn't do much and implemented
|
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
|
just 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
|
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
|
data structures, this List is not a functional one and is a simple linked
|
||||||
list. You can find the implementation under `serene.simple.ListNode`.
|
list. You can find the implementation under `serene.simple.ListNode`.
|
||||||
|
|
||||||
For the number types I just added the support for `Long` and `Double` numbers
|
For the number types I just added support for `Long` and `Double`
|
||||||
via `serene.simple.SNumber` class which act as a dispatcher between two inner
|
via `serene.simple.SNumber` class which acts as a dispatcher between two inner
|
||||||
classes.
|
classes.
|
||||||
|
|
||||||
For Strings, boolean types and `nil`, I just used the equivalent Java data
|
For Strings, boolean types and `nil`, I just used the equivalent Java data
|
||||||
|
@ -64,34 +66,34 @@ structures directly.
|
||||||
|
|
||||||
## Reader/Parser
|
## Reader/Parser
|
||||||
Instead of using a parser generator or a sophisticated parser, I just created
|
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`
|
appropriate method to create the corresponding `Node`. the `serene.simple.Node`
|
||||||
is an abstract class that has just one important method, `eval`. The whole
|
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
|
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
|
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
|
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
|
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 :))
|
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.
|
interop as well which I leave it out of this blog post.
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
Scope are simply a mapping between symbol names and values. Serene consists of two
|
Scopes are simply a mapping between symbol names and values. Serene consists of two
|
||||||
different scopes, both implemented `serene.simple.IScope` and extends
|
different scopes, both implemented in `serene.simple.IScope` and extend
|
||||||
`serene.simple.AScope` abstract class that contains the logic for symbol
|
`serene.simple.AScope` abstract class that contains the logic for symbol
|
||||||
lookup and insertion. These two classes are `serene.simple.Scope` which
|
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
|
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
|
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 top level scope. Beside that, `RootScope` is pre-populated with all
|
||||||
the builtin functions and types.
|
the built-in functions and types.
|
||||||
|
|
||||||
## Special forms
|
## Special forms
|
||||||
Serene's [special forms](https://courses.cs.northwestern.edu/325/readings/special-forms.php)
|
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`
|
are pretty limited. All of them all classes which extend `serene.simple.SpecialForm`
|
||||||
abstract class and inherit from `Node` indirectly. The difference between
|
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
|
Serene does not evaluate the arguments and leaves the evaluation to the special form
|
||||||
itself. Here is the list of Serene's special forms:
|
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
|
```clojure
|
||||||
(def inc (fn (x) (+ 1 x)))
|
(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
|
```clojure
|
||||||
(quote (1 2 3 4)) ;; => (1 2 3 4)
|
(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
|
```clojure
|
||||||
(if (= x 1)
|
(if (= x 1)
|
||||||
|
@ -117,7 +119,7 @@ itself. Here is the list of Serene's special forms:
|
||||||
(...)) ;; if x is not 1
|
(...)) ;; 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
|
```cl
|
||||||
(let ((x 1)
|
(let ((x 1)
|
||||||
|
@ -125,7 +127,7 @@ itself. Here is the list of Serene's special forms:
|
||||||
(println x y))
|
(println x y))
|
||||||
```
|
```
|
||||||
|
|
||||||
`do`: Simple group several expressions together.
|
`do`: Simply groups several expressions together.
|
||||||
|
|
||||||
```clojure
|
```clojure
|
||||||
(do
|
(do
|
||||||
|
@ -156,17 +158,17 @@ important built in functions:
|
||||||
|
|
||||||
`(count coll)`: Returns the number of elements in the given COLL.
|
`(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.
|
`(list 1 2 3..)`: Creates a list from the given arguments.
|
||||||
|
|
||||||
`(first coll)`: Returns the first element of the given COLL.
|
`(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.
|
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
|
`(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 ?
|
## What is missing ?
|
||||||
Since Serene (simple) is an experimental language and I'll abandon it eventually.
|
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
|
So I sacrificed lots of details. Here is a list of the most important missing
|
||||||
details:
|
details:
|
||||||
|
|
||||||
|
@ -239,12 +241,13 @@ details:
|
||||||
is a massive task and needs tons of work which doesn't make sense for a toy
|
is a massive task and needs tons of work which doesn't make sense for a toy
|
||||||
project.
|
project.
|
||||||
* Unified function interface.
|
* Unified function interface.
|
||||||
* Requiring different namespaces
|
* Requiring different namespaces.
|
||||||
* A sophisticated parser. My Reader implementation is really cheap that
|
* A sophisticated parser. My Reader implementation is really cheap that
|
||||||
suits a toy project. It might worth investigating on different solutions
|
suits a toy project. It might worth investigating on different solutions
|
||||||
including using a parser generator or a head of time read implementation.
|
including using a parser generator or ahead of time read implementation.
|
||||||
* Primitive functions in Serene. I implemented lots of primitive functions
|
* Primitive functions in Serene. I used lots of primitive functions
|
||||||
in java rather than Serene itself mostly because of two reasons. Lack of
|
from java rather than implementing them inSerene itself, mostly because
|
||||||
|
of two reasons. Lack of
|
||||||
macros and namespaces.
|
macros and namespaces.
|
||||||
* Decent [functional] data structures. The only data structure I implemented
|
* Decent [functional] data structures. The only data structure I implemented
|
||||||
is list.
|
is list.
|
||||||
|
@ -253,8 +256,8 @@ details:
|
||||||
|
|
||||||
## Conclusion
|
## Conclusion
|
||||||
I'm not going to improve the simple version anymore at this stage. I'm going to run
|
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
|
some benchmarks and measure different aspects of the current implementation and then
|
||||||
I'll move to the **Truffle** version to continue the
|
I'll move to the **Truffle** version and continue the
|
||||||
[experiment(001)](https://gitlab.com/serene-lang/experiment-reports/tree/master/001).
|
[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.
|
I'm available throw social media and email.
|
||||||
|
|
Loading…
Reference in New Issue