Browse Source

Replace jekyll with org-publish

org
Sameer Rahmani 5 months ago
parent
commit
f72707fc4b
100 changed files with 2038 additions and 6803 deletions
  1. +3
    -1
      .gitignore
  2. +17
    -0
      Cask
  3. +0
    -30
      Gemfile
  4. +0
    -74
      Gemfile.lock
  5. +13
    -0
      Makefile
  6. +0
    -2
      README.md
  7. +0
    -71
      _config.yml
  8. +0
    -121
      _drafts/mvcc.md
  9. +0
    -80
      _layouts/_nav.html
  10. +0
    -23
      _layouts/categories.html
  11. +0
    -124
      _layouts/default.html
  12. +0
    -48
      _layouts/home.html
  13. +0
    -11
      _layouts/page.html
  14. +0
    -67
      _layouts/post.html
  15. +0
    -9
      _posts/2018-11-02-I-am-moving-to-gitlab.md
  16. +0
    -116
      _posts/2019-04-26-transaction-variants.md
  17. +0
    -48
      _posts/2019-11-25-my-new-programming-language.md
  18. +0
    -56
      _posts/2019-12-01-rational-and-a-name.md
  19. +0
    -184
      _posts/2019-12-07-choosing-the-target-platform.md
  20. +0
    -261
      _posts/2020-01-03-serene-simple-version.md
  21. +0
    -32
      _posts/2020-08-14-sameers-pyramid.md
  22. +0
    -8
      _sass/bulma.sass
  23. BIN
     
  24. +0
    -5
      _sass/bulma/base/_all.sass
  25. +0
    -130
      _sass/bulma/base/generic.sass
  26. +0
    -276
      _sass/bulma/base/helpers.sass
  27. +0
    -84
      _sass/bulma/base/minireset.sass
  28. +0
    -15
      _sass/bulma/components/_all.sass
  29. +0
    -75
      _sass/bulma/components/breadcrumb.sass
  30. +0
    -74
      _sass/bulma/components/card.sass
  31. +0
    -77
      _sass/bulma/components/dropdown.sass
  32. +0
    -75
      _sass/bulma/components/level.sass
  33. +0
    -39
      _sass/bulma/components/list.sass
  34. +0
    -48
      _sass/bulma/components/media.sass
  35. +0
    -50
      _sass/bulma/components/menu.sass
  36. +0
    -86
      _sass/bulma/components/message.sass
  37. +0
    -113
      _sass/bulma/components/modal.sass
  38. +0
    -428
      _sass/bulma/components/navbar.sass
  39. +0
    -144
      _sass/bulma/components/pagination.sass
  40. +0
    -101
      _sass/bulma/components/panel.sass
  41. +0
    -151
      _sass/bulma/components/tabs.sass
  42. +0
    -16
      _sass/bulma/elements/_all.sass
  43. +0
    -24
      _sass/bulma/elements/box.sass
  44. +0
    -275
      _sass/bulma/elements/button.sass
  45. +0
    -25
      _sass/bulma/elements/container.sass
  46. +0
    -151
      _sass/bulma/elements/content.sass
  47. +0
    -602
      _sass/bulma/elements/form.sass
  48. +0
    -21
      _sass/bulma/elements/icon.sass
  49. +0
    -69
      _sass/bulma/elements/image.sass
  50. +0
    -35
      _sass/bulma/elements/notification.sass
  51. +0
    -39
      _sass/bulma/elements/other.sass
  52. +0
    -65
      _sass/bulma/elements/progress.sass
  53. +0
    -126
      _sass/bulma/elements/table.sass
  54. +0
    -130
      _sass/bulma/elements/tag.sass
  55. +0
    -64
      _sass/bulma/elements/title.sass
  56. +0
    -4
      _sass/bulma/grid/_all.sass
  57. +0
    -504
      _sass/bulma/grid/columns.sass
  58. +0
    -32
      _sass/bulma/grid/tiles.sass
  59. +0
    -5
      _sass/bulma/layout/_all.sass
  60. +0
    -6
      _sass/bulma/layout/footer.sass
  61. +0
    -156
      _sass/bulma/layout/hero.sass
  62. +0
    -13
      _sass/bulma/layout/section.sass
  63. +0
    -8
      _sass/bulma/utilities/_all.sass
  64. +0
    -5
      _sass/bulma/utilities/animations.sass
  65. +0
    -50
      _sass/bulma/utilities/controls.sass
  66. +0
    -85
      _sass/bulma/utilities/derived-variables.sass
  67. +0
    -62
      _sass/bulma/utilities/functions.sass
  68. +0
    -72
      _sass/bulma/utilities/initial-variables.sass
  69. +0
    -261
      _sass/bulma/utilities/mixins.sass
  70. +0
    -88
      _sass/code.scss
  71. +0
    -9
      about.md
  72. BIN
     
  73. BIN
     
  74. BIN
     
  75. BIN
     
  76. BIN
     
  77. BIN
     
  78. +0
    -91
      assets/fonts/OFL.txt
  79. BIN
     
  80. +0
    -25
      assets/js/main.js
  81. +800
    -0
      assets/styles/dark.css
  82. +20
    -0
      assets/styles/main.css
  83. +0
    -220
      assets/styles/web.sass
  84. +0
    -14
      blog.md
  85. +122
    -0
      build.el
  86. +800
    -0
      build/html/assets/styles/dark.css
  87. +20
    -0
      build/html/assets/styles/main.css
  88. +63
    -0
      build/html/index.html
  89. +32
    -0
      build/html/sitemap.html
  90. +0
    -17
      categories.html
  91. +0
    -4
      categories/cooking.md
  92. +0
    -84
      coh.md
  93. +10
    -0
      config.org
  94. +0
    -4
      gpg.md
  95. +0
    -5
      index.md
  96. +81
    -0
      lisp/ox-template.el
  97. +24
    -0
      orgs/index.org
  98. +3
    -0
      orgs/sitemap.inc
  99. +29
    -0
      templates/blog.html
  100. +1
    -0
      templates/footer.html

+ 3
- 1
.gitignore View File

@@ -2,4 +2,6 @@ _site
.sass-cache
.jekyll-metadata
_tmp/
*~
*~
.cask/
*.elc

+ 17
- 0
Cask View File

@@ -0,0 +1,17 @@
(source gnu)
(source melpa)

(package-file "build.el")

(development
(depends-on "f")
(depends-on "ecukes")
(depends-on "ert-runner")
(depends-on "el-mock"))

(depends-on "mustache")
(depends-on "ht")
(depends-on "org")
(depends-on "ox-publish")
(depends-on "htmlize")
(depends-on "dracula-theme")

+ 0
- 30
Gemfile View File

@@ -1,30 +0,0 @@
source "https://rubygems.org"

# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 3.8.5"

# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
# gem "github-pages", group: :jekyll_plugins

# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.6"
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]

# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.0" if Gem.win_platform?

gem 'jekyll-seo-tag'
gem 'jekyll-sitemap'
gem 'sass'

+ 0
- 74
Gemfile.lock View File

@@ -1,74 +0,0 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
colorator (1.1.0)
concurrent-ruby (1.1.4)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
eventmachine (1.2.7)
ffi (1.10.0)
forwardable-extended (2.6.0)
http_parser.rb (0.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jekyll (3.8.5)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 0.7)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (~> 1.14)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
jekyll-feed (0.11.0)
jekyll (~> 3.3)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.5.0)
jekyll (~> 3.3)
jekyll-sitemap (1.2.0)
jekyll (~> 3.3)
jekyll-watch (2.1.2)
listen (~> 3.0)
kramdown (1.17.0)
liquid (4.0.1)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
mercenary (0.3.6)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.0.3)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
rouge (3.3.0)
ruby_dep (1.5.0)
safe_yaml (1.0.5)
sass (3.7.3)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)

PLATFORMS
ruby

DEPENDENCIES
jekyll (~> 3.8.5)
jekyll-feed (~> 0.6)
jekyll-seo-tag
jekyll-sitemap
sass
tzinfo-data

BUNDLED WITH
2.0.1

+ 13
- 0
Makefile View File

@@ -0,0 +1,13 @@
clean:
rm -rf build
rm -rf `find . -iname "*~"`

dev-build:
./build.el


build:
LXHOME_PROD=t ./build.el

serve: build
npx http-server -p 3003 ./build

+ 0
- 2
README.md View File

@@ -1,2 +0,0 @@
# LxHome
My personal website and blog. Posts are licensed under CC and code is published under MIT license.

+ 0
- 71
_config.yml View File

@@ -1,71 +0,0 @@
# Welcome to Jekyll!
#
# This config file is meant for settings that affect your whole blog, values
# which you are expected to set up once and rarely edit after that. If you find
# yourself editing this file very often, consider using Jekyll's data files
# feature for the data you need to update frequently.
#
# For technical reasons, this file is *NOT* reloaded automatically when you use
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.

# Site settings
# These are used to personalize your new site. If you look in the HTML files,
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
# You can create any custom variable you would like, and they will be accessible
# in the templates via {{ site.myvariable }}.
title: lxsameer's nest
email: lxsameer@gnu.org
author: lxsameer
description: >- # this means to ignore newlines until "baseurl:"
lxsameer's view of the world
baseurl: "" # the subpath of your site, e.g. /blog
url: "https://lxsameer.com" # the base hostname & protocol for your site, e.g. http://example.com
twitter_username: lxsameer
github_username: lxsameer
twitter:
username: lxsameer
card: summary
social:
name: lxsameer
links:
- https://twitter.com/lxsameer
- https://www.linkedin.com/in/lxsameer
- https://github.com/lxsameer

permalink: /:categories/:title/


# Build settings
markdown: kramdown
plugins:
- jekyll-feed
- jekyll-sitemap
- jekyll-seo-tag
# Exclude from processing.
# The following items will not be processed, by default. Create a custom list
# to override the default setting.
# exclude:
# - Gemfile
# - Gemfile.lock
# - node_modules
# - vendor/bundle/
# - vendor/cache/
# - vendor/gems/
# - vendor/ruby/


sass:
sass_dir: _sass


collections:
category:
output: true

defaults:
-
scope:
path: ""
type: category
values:
layout: "category"

+ 0
- 121
_drafts/mvcc.md View File

@@ -1,123 +0,0 @@
layout: post
title: "Multi-Version Concurrency Control"
date: 2019-04-28
categories: DB
tags: concurrency
theme: dark

Multi version concurrency control or **MVCC** for short is a famous and commonly used concurrency
control methods in [DBMS](https://en.wikipedia.org/wiki/Database#Database_management_system)s
and some programming languages (for [Transactional Memory](https://en.wikipedia.org/wiki/Transactional_memory)).
Like lots of other concepts and algorithms in computer science it is old (introduced in 70s).

Before we start I presume you are familiar with
[transaction processing](https://en.wikipedia.org/wiki/Transaction_processing). Also as an heads up, Since
MVCC is a huge topic and far beyond a blog post, I'll split this topic into several posts. In this post
we're going to have an overview of MVCC.

## What is Concurrency Control ?
Concurrency control is the procedure in data oriented systems such as a DBMS or a programming language for managing
simultaneous operations without conflicting with each another. Concurrent access is quite easy if all everyone
wants to just read data. In a read only environment there is no way that read operations can interfere with one
another. But the purpose of every system in this world is to process some data and make changes to the world. Write
operations are important part of each system and concurrency controll is all about handling simultaneous write
operations in a conflict free way.

**MVCC** is one of the most popular and widely used concurrency control methods. For more on concurrency control
checkout [this wikipedia page](https://en.wikipedia.org/wiki/Concurrency_control)

## MVCC
According to MVCC, the system (DBMS or a programming language) maintains multiple physical versions of a single
logical object (any thing under the control of the system, either a tuple in relational DBMSs or some data
in memory controlled by a programming language ) in the system:

* When a transaction writes to an object, the system creates a new version of that object.
* When a transaction reads an object, it reads the newest version that existed when the transaction started.

We'll see how MVCC works in a minute but let's discuss why to use MVCC ?

There are lots of benefits to using MVCC as the concurrency control method but some of the main benefits
are:

* Writes don't block readers:
With MVCC write operations can be done in a way which no reader would get blocked by the write operation
which is the case in [Two Phase Locking](https://en.wikipedia.org/wiki/Two-phase_locking)

* Lock free read operations via consistent snapshots:
Read only transactions don't have to acquire a lock anymore because they will provided by a snapshot
of the current state of the system to operate on.

* Time Traveling Operations:
With storing all the versions of an object in the system, we easily can operate on a specific version
of an object for a given time. For example in the case of DBMS, we can run a query against the state
of the database from 2 years ago.

MVCC useful not just for concurrency control. It can shine when it comes to multi version data control
as well.

## Snapshot Isolation (SI)
In order to understand how MVCC works, first we need to know about snapshot isolation (SI). MVCC and
SI have a two way relationship. By two way relationship I mean, In order to implement MVCC we need
to implement SI and if we want to have SI in our system we need to have MVCC as well (does it make sense?).

Basically when a transaction starts, the system provides the transaction with a consistent
snapshot of the current state of system. By current, I mean the exact state of the system just before
the transaction started and by consistent I mean, the snapshot would not contain any uncommited data
from a running transaction. So If in any given time transaction T1 is running and T2 is about to start,
the system would not include T1 changes in the snapshot which is going to be used for T2. Simple as that.

This way we would not end up with torn writes (for example when a writes operation which is supposed to
write two objects in the state, writes only the first one) from any running transaction.

Also the important rule here is that if two transactions want to update the same object the first one
will wins and the second one has to retry.

Snapshots might be physical or logical. Depends on the system. For example in a DBMS it does not make
sense to copy the database state to each transaction (physical snapshot) because obviously it would be
huge. Instead it use logical snapshots which using the same physical data. But in a programming language,
it might be much faster to just use a physical snapshot of some data in memory instead of handling the overhead
of the necessary book keeping for a logical snapshot.

It's important to bear in mind that SI is not serializable isolation by default. If you need to implement
serializable isolation for the snapshots in your system you have to take care of some extra stuff.

## Design of MVCC
In order to implement MVCC in a system we need to decide between different aspects of the system
which would be involved with MVCC. The most crucial aspects are:

* Book keeping of data we need to store
* Concurrency control protocol
* Index Management
* Garbage Collection
* Storage

### Data book keeping
Depends on the concurrency control protocol we want to use, we have to manage some extra data about
every object in our system. In general we need to keep track of the following information about each
object:

* Transaction ID (`TxID`)
* Life time of each object:
* When the transaction that operate on this object began: `BEGIN-TS`
* When the transaction that operate on this object ended: `END-TS`
* A link to the previous/next versions of the same object

And some other information depends on the protocol we use for concurrency control. It's crucial to
decide who to manage and store these data in your system and it's totally depends on the nature of
your system. Is it a disk oriented, single node databse management system ? is it a programming
language operating on a single threaded environment ? or maybe it's an in-memory, distributed
database management system ?

Whatever it is you have to keep in mind that computer science is about tradeoffs. There is no
ultimate answer. For example storing these kind of data along side with the object it self can
increase your storage usage but can save you lots of computation time. It can be wise to do it
in a DBMS but not in a programming language to implement STM.

### Concurrency control protocols for MVCC

* Mutli Version Timestamp Ordering (MTVO)
* The "Optimistic Concurrency Control" (MVOCC)
* Multi Version 2 Phase Locking (MV2PL)
* Serializable Snapshot Isolation (SSI)

+ 0
- 80
_layouts/_nav.html View File

@@ -1,80 +0,0 @@

<section class="section">
<div class="container">











<div class="level">

<a class="navlink" href="https://gitlab.com/lxsameer">
<div class="level-item">
</div>
</a>

<a class="navlink" href="/feed.xml">
<div class="level-item">
<span class="icon is-large">
<i class="fas fa-rss fa-lg"></i>
</span>

</div>
</a>

{% if page.url != "/" %}
<a class="level-item" href="/">
<div class="column">
<span class="icon is-large">
<i class="fas fa-home fa-lg"></i>
</span>
</div>
</a>
{% endif %}

<!-- {% if page.url != "/gpg.html" %}
<div class="column navlink">
<a class="" href="/gpg.html">
<span class="icon is-large">
<i class="fas fa-key fa-lg"></i>
</span>
</a>
</div>
{% endif %} -->

{% if page.url != "/blog/" %}
<a class="navlink" href="/blog/">
<div class="level-item">
<span class="icon is-large">
<i class="fas fa-blog fa-lg"></i>
</span>
</div>
</a>
{% endif %}

<a class="navlink" href="https://www.linkedin.com/in/lxsameer/">
<div class="level-item">
<span class="icon is-large">
<i class="fab fa-linkedin fa-lg"></i>
</span>
</div>
</a>

<a class="navlink" href="https://twitter.com/lxsameer">
<div class="level-item">
<span class="icon is-large">
<i class="fab fa-twitter fa-lg"></i>
</span>
</div>
</a>

</div>
</div>

</section>

+ 0
- 23
_layouts/categories.html View File

@@ -1,25 +0,0 @@
layout: default
theme: dark

<div class="columns is-flex centered">

<div class="column is-half">
<h2>Posts on: {{ page.title }}</h2>

{% unless page.content == '' %}
<p>{{ page.content }}</p>
{% endunless %}

{% for post in site.categories[page.category] %}
<div class="post-preview">
<a href="{{ post.url | prepend: site.baseurl }}">
<h2 class="post-title is-size-2">
{{ post.title }}
</h2>
</a>
</div>
{% endfor %}
</div>
</div>

+ 0
- 124
_layouts/default.html View File

@@ -1,124 +0,0 @@
<!DOCTYPE html>
<html class="{% if page.theme %}{{page.theme }}{% else %}light{% endif %}">
<head>
<meta charset="UTF-8" />
<meta name="theme-color" content="#49438B" />
{% seo %}
<link href="/assets/styles/web.css?1" rel="stylesheet" />
<link
rel="stylesheet"
href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
crossorigin="anonymous"
/>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body class="{% if page.theme %}{{page.theme }}{% else %}light{% endif %}">
<nav
class="navbar is-primary"
role="navigation"
aria-label="main navigation"
>
<div class="container">
<div class="navbar-brand">
<a
role="button"
class="navbar-burger burger"
aria-label="menu"
aria-expanded="false"
data-target="navcontainer"
>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a>
</div>

<div id="navcontainer" class="navbar-menu">
<div class="navbar-start">
<a href="/" class="navbar-item {% if page.url == '/' %}is-active{% endif %}">
Home
</a>

<a href="/code-of-honor/" class="navbar-item {% if page.url == '/code-of-honor/' %}is-active{% endif %}">
Code of Honor
</a>

<a href="https://dl.lxsameer.com/lxsameer.pub.gpg" class="navbar-item">
GPG Key
</a>

<a href="/about/" class="navbar-item {% if page.url == '/about/' %}is-active{% endif %}">
About Me
</a>
</div>

<div class="navbar-end">
<a class="navbar-item" href="https://gitlab.com/lxsameer">
<span class="icon is-large is-hidden-mobile">
<i class="fab fa-gitlab fa-lg"></i>
</span>
<span class="is-large is-hidden-desktop">
<i class="pad fab fa-gitlab fa-lg"></i>
Gitlab
</span>
</a>

<a class="navbar-item" href="https://social.lxsameer.com/">
<span class="icon is-large is-hidden-mobile">
<i class="fab fa-mastodon fa-lg"></i>
</span>

<span class="is-large is-hidden-desktop">
<i class="pad fab fa-mastodon fa-lg"></i>
ActivityPub
</span>
</a>

<a class="navbar-item" href="https://www.linkedin.com/in/lxsameer/">
<span class="icon is-large is-hidden-mobile">
<i class="fab fa-linkedin fa-lg"></i>
</span>
<span class="is-large is-hidden-desktop">
<i class="pad fab fa-linkedin fa-lg"></i>
Linkedin
</span>
</a>

<a class="navbar-item" href="https://twitter.com/lxsameer">
<span class="icon is-large is-hidden-mobile">
<i class="fab fa-twitter fa-lg"></i>
</span>

<span class="is-large is-hidden-desktop">
<i class="pad fab fa-twitter fa-lg"></i>
Twitter
</span>
</a>
<a class="navbar-item" href="/feed.xml">
<span class="icon is-large is-hidden-mobile">
<i class="fas fa-rss fa-lg"></i>
</span>

<span class="is-large is-hidden-desktop">
<i class="pad fas fa-rss fa-lg"></i>
RSS Feed
</span>
</a>

</div>
</div>
</div>
</nav>

<div class="container">
{{ content }}
</div>
<footer class="footer">
<div class="content has-text-centered">
<p>© 2010-2020 Sameer Rahmani</p>
</div>
</footer>
<script src="/assets/js/main.js?1"></script>
</body>
</html>

+ 0
- 48
_layouts/home.html View File

@@ -1,50 +0,0 @@
layout: default


<div class="column is-half-desktop is-offset-one-quarter-desktop para">
<section class="section is-size-4-desktop is-size-5-mobile">
<p class="text-centered">
<img
class="avatar is-rounded"
alt="lxsameer"
src="/assets/images/avatar.jpg"
/>
</p>
<p class="info text-justified">
Hi! I'm <b>Sameer</b> and I usually write about
technology and software development (hmmm more like nagging instead of writing). Since
I'm lazy, my posts are short so I can write more often.

<!-- <p class="info text-justified"> -->
<!-- If you have any comment on the articles or anything in general either send me an -->
<!-- email for connect to me via my <a class="home" href="https://activitypub.rocks/">activity pub</a> -->
<!-- feed on <a class="home" href="https://social.lxsameer.com">lxsameer@social.lxsameer.com</a>. -->
</p>
</p>
</section>
</div>


<div class="column is-half-desktop is-offset-one-quarter-desktop">
<section class="section">
<h3 class="header is-size-4">
Blog Posts:
</h3>

{% for post in site.posts %}

<div class="columns">
<div class="column">
<h2 class="is-size-3-desktop is-size-4-mobile">
<a class="post-title-link" href="{{ post.url }}">
<i class="fas fa-link"></i> {{ post.title }}
</a>
</h2>
</div>
</div>

{% endfor %}
</section>
</div>

+ 0
- 11
_layouts/page.html View File

@@ -1,13 +0,0 @@
layout: default
theme: light
<div class="column is-half-desktop is-offset-one-quarter-desktop">
<h1 class="is-size-1">
{{page.title}}
</h1>

<content class="post">
{{ content }}
</content>
</div>

+ 0
- 67
_layouts/post.html View File

@@ -1,69 +0,0 @@
layout: default
theme: dark

<div class="column is-half-desktop is-offset-one-quarter-desktop">
<h1 class="is-size-2">
{{page.title}}
</h1>
<div class="columns">
<div class="column">
<ul class="details is-size-7">
<li>{{page.date | date_to_string }} |</li>

{% for tag in page.tags %}
<li class="">#{{ tag | capitalize }}</li>
{% endfor %}

{% for tag in page.categories %}
<li class="category">
#{{ tag | capitalize }}
</li>
{% endfor %}
</ul>
</div>

<div class="column">
</div>


</div>

<content class="post">
{{ content }}
</content>


<div class="share-page">
<div class="columns is-flex right-aligned">
<a href="https://twitter.com/intent/tweet?text={{ page.title }}&url={{ site.url }}{{ page.url }}&via={{ site.twitter_username }}&related={{ site.twitter_username }}" rel="nofollow" target="_blank" title="Share on Twitter">
<div class="column">
<span class="icon is-large">
<i class="fab fa-twitter fa-lg"></i>
</span>
</div>
</a>

<a href="http://www.linkedin.com/shareArticle?mini=true&url={{page.url}}&title={{page.title}}&summary={{page.description}}&source={{site.url}}" rel="nofollow" target="_blank" title="Share on LinkedIn">
<div class="column">
<span class="icon is-large">
<i class="fab fa-linkedin fa-lg"></i>
</span>
</div>
</a>

<a href="https://plus.google.com/share?url={{ site.url }}{{ page.url }}" rel="nofollow" target="_blank" title="Share on Google+">
<div class="column">
<span class="icon is-large">
<i class="fab fa-google fa-lg"></i>
</span>
</div>
</a>
</div>
</div>
</div>
<div class="columns is-flex centered">
<div class="column is-half-desktop has-text-centered">
</div>
</div>

+ 0
- 9
_posts/2018-11-02-I-am-moving-to-gitlab.md View File

@@ -1,11 +0,0 @@
layout: post
title: "I moved from Github to Gitlab"
date: 2018-11-02
categories: Announcements
tags: gitlab
theme: dark
As soon as I hear about Micro$oft acquiring Github I decided to migrate to Gitlab. My guts tells me to do not trust a corporation behind the [Halloween document](https://en.wikipedia.org/wiki/Halloween_documents). Micro$oft might be a different company these days but their history is enough to not to trust them. Even if they are different and have no bad intentions, but still acquiring company such as Github means that the very first thing they will do is to integrate Github with their own services and that is enough for me to move.

In the other hand Gitlab is a free software with tons of feature like built-in CI and docker registry and other cool stuff. I totally recommend Gitlab as a better alternative to Github.

+ 0
- 116
_posts/2019-04-26-transaction-variants.md View File

@@ -1,118 +0,0 @@
layout: post
title: "Transaction Variants"
date: 2019-04-26
categories: DB
tags: transaction
theme: dark

In this post I want to talk about different variants of
[database transactions](https://en.wikipedia.org/wiki/Database_transaction), I assume you already
know about database transactions. So, let's cut to the chase.

## Flat Transaction
Flat transaction are those regular transactions we know about and are the most common transactions
in the [DBMS](https://en.wikipedia.org/wiki/Database#Database_management_system)s.

Flat transactions are simple but they can not address two problems:

* Multi stage transactions
For example, Let's say we want to book flight from City C1 to C2. Since there is no direct fly we
have to book 4 flights from, `C1 -> CA -> CB -> C2`. The process of booking each of these flights
is a transaction by itself and the whole process is a transaction too.

* Bulk updates
Let's say we want to update billion tuples. What if the very last tuple fails to update and cause
the transaction to abort. Then we need to revert the changes made by the transaction and revert
a billion tuples which obviously is a huge task.


## Transaction Savepoints
These transactions are similar to flat transaction with addition of one extra thing which is
save points. So any where in there transaction users case ask for a save point and again they can
rollback to a save point or rollback the entire transaction.

```sql
BEGIN
READ(A)
WRITE(A)
SAVEPOINT 1
WRITE(B)
SAVEPOINT 2
ROLLBACK TO 1
COMMIT
```

Note: **These transactions only solve the multi stage transaction problem.**

## Nested transactions
Nested transactions are similar to save points transactions, but instead save points these
transactions break down to smaller flat transactions. Each transaction commits separately from
other transactions. But result of the parent transaction rule them all, so if the parent
transaction fails all the nested transactions have to rollback.

```sql
BEGIN
BEGIN T1
...
COMMIT T1
BEGIN T2
...
COMMIT T2
COMMIT
```

Note: **These transactions only solve the multi stage transaction problem.**

## Chained transactions
In these kind of transactions, smaller flat transaction can be applied in a chain in the way that
the result of each of them is not visible to the outside world until the end of the chain.

In theory chained transactions should be applied in sequence but in practice in some cases we can
interleave their operations. Also Between T1 and T2 of a chained transaction, No other thread of
code shouldn't be able to make changes to those resources which T2 will operates on.

If any transaction in the chain fails, it has nothing to do with the previous transactions in the
chain. For example:

```
T1 -> T2 -> T3
S -> S -> F
```

In the chained transaction above only T3 failed and T1 and T2 are successfully committed to storage.
We don't have to roll them back.

While chained transactions can break big transactions into smaller pieces for better parallelism but
**they only solve the multi stage transaction problem** Not the bulk update problem.

## Compensating transactions
This type of transactions are special transactions which are designed to semantically reverse the
effect of another transaction which already committed.

One important thing to remember about compensating transactions is that they know how to revert
the *logical* effect of other transactions *NOT the physical* effect. For example, If a transaction
increase a counter by one. The physical revert would be to changes the binary data that inserted
for that counter to what it was before the transaction, but the logical revert would be to
decrease the counter by one when needed.

So basically these kind of transactions know about how to put the database in correct state before
the other transaction.

## Saga Transactions
A saga transaction is a sequence of chained transactions `T1 - Tn` and compensating transaction
`C1 - C(n-1)` where the following guaranteed:

* The transactions will commit in the order `T1...Tj`, `Cj...C1` (where `j < n`).

So basically this means that a saga transaction is a seq of chained transactions which applies the
smaller transactions in order with their corresponding compensating transactions.

In a chained transaction when ever transaction Tn aborts, the transactions before Tn stay committed,
but in saga transactions they will be rollback using compensating transactions that know how to
roll them back *logically*.

So Saga transactions can be fix both multi-staging and bulk update problems. But the issue here is
that the compensating transactions are something that requires application level understanding of
the use case so most of the time they are implemented in the application frameworks instead of DBMSs.

+ 0
- 48
_posts/2019-11-25-my-new-programming-language.md View File

@@ -1,50 +0,0 @@
layout: post
title: "My new programming language"
date: 2019-11-25
categories: Programming
tags: Serene language
theme: dark
As a software engineer, one of my joys in life is to learn new things. I can't describe the
pleasure of learning a new technology or stepping forward in the world of science. If you experienced
such a delight, you would know that how addictive it is. I can't satisfy my hunger for knowledge and
it might sounds like a gloat but it's truly joyful (ok mate, you love to "read", get on with it).

Programming languages are the most common tool among programmers and software engineers (Duh!).
I believe that learning new programming languages helps us to widen our vision as engineers and
help us improve our mentality about software architecture and design. So clearly I never say "No"
to learning a new programming language and because of that I have lots of experience with different
languages. Each language taught me tons of new things and helped me enhance my skills. I've studied
many languages and have a long list of them as my "To Learn" list.

Approximately a year ago, I was frustrated with Python and nagging to my wife about it (She always listens to
my gibberish). All of a sudden she suggested to me that "Why don't you write your own programming language ?".
That got me thinking, "Is it a good idea to do so ????".

People have different routines for learning. I'm one of those people who likes to learn new
things by understanding how it works first. I'd like to start my learning process by understanding
the laws of the universe. In this case, "universe" is the implementation and theory behind
the thing I'm trying to learn. It might seem like crazy idea but that's how I learn better.
For instance, when I was a teenager and was learning about how to use Gnu/Linux, I was so
obsessed with internal of a Linux distribution to a degree that I decided to build my own
distribution. Of course as a teenager I was naive and dreamed about my distro ( Which I used
to call Liniera ) to become a well-known and popular distribution. Aside from my childhood dreams
I learned a lot by creating a distribution. Learned about Linux kernel, boot process, bootloaders
and tons of other complicated pieces that normally people don't get to know at first (I was using
LFS and Debian tools). So after that delightful but tough experience, I always try to build a minimal
prototype of whatever I'm trying to learn to comprehend the universe of that thing which
helped me a lot to this day.

Based on my history, routines and the question that my wife has planted in my mind and after about a year
researching and thinking about it, Finally I realized it can be a good idea to create a new
programming language. To be honest it is not a task to be taken lightly. Whenever I created something
that wasn't out of my needs, I just failed. But this time I think creating a programming language can
massively help me to gain a better grasp of "the universe". Trying to overcome this challenge will help
me to grow and be a better engineer despite the fact that this new language may not even make it to the
list of known programming languages. I'm fine with that as long as it pushes me a step forward in my way
of life and brings me joy of wondering around in the world of science and engineering.

I'm going to write more blog posts about my journey through this humongous task as a journal for myself and other
enthusiastic people. After all it will be a hobby of mine and not my day to day job. So I'll take my time and
move slowly but steady.

+ 0
- 56
_posts/2019-12-01-rational-and-a-name.md View File

@@ -1,58 +0,0 @@
layout: post
title: "Step 1: Rational (take one) and a name"
date: 2019-12-01
categories: Programming
tags: Serene language
theme: dark

**This post is a draft and I'll finish it gradually**

As I mentioned in [My new programming language](/programming/my-new-programming-language/),
I'm creating a new programming language. I'll try to pick up good points
of different programming languages and avoid the cons of them. One of the
most important aspects of any project is to have a rational for it.
It's what I learned from [Clojure](http://clojure.org)'s culture. Rationals
are a big deal in any clojure developers world. As fan I'd like to start
my new programming language by writing down the rational of what I'm trying
to achieve.

### Rational(Take 1) and goals
So far, the main reason to create a new language for me is to **learn more and
educate myself**. But it doesn't mean that I'm aiming for a toy language. I want
to create a general purpose language that solves some problems. Here is a list of
reasons that made me consider the idea of creating a new language (in no specific order):

#### Lisp is superior
I think the world needs more and more dialects of Lisp. It's the second oldest
programming language in the world and as far as I know the oldest one that is
still active. **Lisp** is elegant and amazing, but unfortunately not so many
programmers know about it. Even most of the those people who heard the name
are distracted by the "parenthesis". But they're missing the fact that there
is a good reason for all those parenthesis. Lisp is the simplest language I
know, its programs are written in its own datatypes. How simple is that???

You might hear that
[God has created the universe in Lisp](https://twobithistory.org/2018/10/14/lisp.html).
Lisp is amazing and I consider a programmer who has understood **the Lisp way**, the
[luckiest](https://twitter.com/lxsameer/status/1172220581992980480).

I'd my new language to be Lisp, because just being a Lisp brings a huge deal to the
table.

#### Simplicity
#### FP is the future
#### Development process
#### Better core development
#### Built-in Concurrency and parallelism

### A Name
If you're a programmer, I'm pretty sure that you already experienced the terror
of trying to find a name for your project. Frankly, It's even hard to find a good
name for your variable.

After about 10 days of searching finally my wife came up with a good name. **Serene**.
Calm and peaceful. I like it. It's simple and beautiful with a great meaning.

I can't wait to start working on it. :P

+ 0
- 184
_posts/2019-12-07-choosing-the-target-platform.md View File

@@ -1,186 +0,0 @@
layout: post
title: "Choosing the right platform"
date: 2019-12-07
categories: Programming
tags: Serene language
theme: dark
After wrapping my head around the [rational](/programming/rational-and-a-name/) of
[My new programming language](/programming/my-new-programming-language/), I have
a big decision to make. Choose a platform.

As programmers, we have a tough life when it comes to making a decision that
has direct impact on our product. I'm pretty sure you went through this process
at least once. From choosing a semantically great name for a variable to choosing
a right technology for your next billion dollar startup. It is always hard to
pick a tech stack for a new project. Especially when the new product happens to be
a new programming language. If I get my hands dirty with a wrong tech stack for
a simple web application, no big deal. I still can rewrite the whole thing and
pay a penalty. But in the case of programming languages that's not the case. Wrong
platform can easily destroy you. From the dawn of computers, many smart people
created tons of languages. But only few of them made it to the top. While there
are so many reasons for their success, going with the right platform is one
the most important ones.

The obvious question that comes to mind when we're talking about "The platform"
is, should we build a platform from scratch or should we piggyback on others?
Creating a programming language and a virtual machine from scratch is gigantic and
bone crushing task. It needs a crazy set of skills and knowledge. Even with such
wisdom and experience people who went through it has made many mistakes and had to
constantly iterate to come up with the right implementation. The evolution of
programming languages such as [Scheme](https://en.wikipedia.org/wiki/Scheme_%28programming_language%29)
is a good example of it (for more information take a look at [R6RS](http://www.r6rs.org/)).

Building a VM is hard and Building a fast VM is even harder. While I think creating
a programming language and a VM from scratch is really fun, but it can be really
frustrating as well. I don't want to get annoyed with myself during the process and
abandon my goal. I should ride on the shoulders of the giants to gain benefit from
their great work. I should choose a platform that helps me to move faster and iterate
through different ideas quicker.

From a technical perspective, Starting from scratch means that I have to write a
program that includes at least a parser and a compiler. Building a compiler
is no joke. Hypothetically let's say we have a working compiler and parser, What
about use libraries and ecosystem ?? It would be really hard to convince people
to use a programming language that does not have any useful library and they have
to build everything by themselves. It might have been the case 30 years ago but
it is not the case in the modern age of programming languages anymore.

So the idea of creating [Serene](https://serene-lang.org) from scratch is out of
the picture. We need to find a good platform for it. But what are the options ???

## Racket
> Racket is a general-purpose programming language as well as the world’s first ecosystem
> for language-oriented programming. Make your dream language, or use one of the dozens
> already available.

[Racket](http://racket-lang.org) is a dialect of Lisp which allows us to build our own
language by extending it. While Racket is really cool and have a long list of pros and
[many reasons why to use it](https://beautifulracket.com/appendix/why-racket-why-lisp.html)
(It's Lisp after all), it has the disadvantage that forced me to stop thinking about it
for **Serene**. As I mentioned in the [rational](/programming/rational-and-a-name/)
I'm not trying to build a toy language or a domain specific one and Racket's ecosystem
isn't as great as a battle tested and well-known ecosystem like Java or Python (or other
popular ecosystems).

## Javascript
We're living in the age of Web and one of the big players in this era is Javascript. The number
of the programming languages that compile to Javascript is increasing rapidly. Javascript
as a language [sucks](https://whydoesitsuck.com/why-does-javascript-suck/) but as platform
it is amazing. Lots of money and engineering effort has been spent on improving Javascript engines.
As a result Javascript is a crappy language with well engineered engines such as
[V8](https://v8.dev/).

Creating a language based on Javascript platform means that I have to be involved with the whole
transpiling scenario and deal with the fact that this new language can be used on different
browsers or on the backend. Or even on IE6 (Just kidding). I don't want to deal with all this.
I think Javascript platform can't be a good fit for what I need. So I won't go into details about
it

## Python
Python is another famous platform form creating programming languages. Many people have built
programming languages on top of Python (Checkout [Lispy](http://norvig.com/lispy.html) if you're
a Python fan). Python is super popular these days and you'll see it everywhere. Creating a language
on top of Python (just like Javascript) gives me access to a rich ecosystem with huge number of
libraries and a robust ecosystem.

But as I mentioned in the [rational](/programming/rational-and-a-name/) I want support for built-in
concurrency and parallelism. Python isn't even good when it comes to parallelism and concurrency.
I'm using python for more than 10 years now and I'm very familiar with it. I know about all the
effort to create useful concurrency and parallelism such as asyncIO. But the fact is Python
is not designed for this job. **GIL** is a huge problem in Python that literally prevents
us from Running two pieces of code in parallel in two kernel space thread. It is a problem
for me. If you can't do a decent concurrency and parallel execution you have no chance
against modern languages like Clojure, Go, Elixir and others. Python is fine now despite
of its problems because it is good at other stuff and people accepted it for what it is.
Python is out there for about 25 years now and it has established a big community. If
Guido van Rossum created Python a year ago, I'm pretty sure that it would've failed because
it can't compete with modern languages. Don't get me wrong, I'm not trying to trash Python.
It is great and it has many good qualities but a good Concurrency and parallel execution model
ain't one of them.

## BEAM
Erlang ecosystem is amazing, Robust and well tested. I have read a lot about it and when
ever I'm studying anything around computer science that can be related to Erlang, I ask
myself "How is Erlang doing it?". Erlang ecosystem truly had a huge impact on the world
today.

The problem with Erlang ecosystem for me is that I always read about it and my knowledge
around it is only theoretical. Building a language on top a platform needs a good level
of practical experience on the platform as well which I don't have that. So it's obvious
that I have to pass.

## The JVM
As much as I dislike Java (Mostly because of the syntax and the fact that it is an object
oriented language), I like JVM a lot. The JVM is battle tested, well design (Well, sort of.
But it's certainly evolving.) and fast VM. It should be the most popular VM in the world
(I'm just guessing). It is one of the world's most heavily-optimized pieces of software.
Plenty of researches have been made to make it better and better.

The JVM has a mature ecosystem and a massive community of developers that resulted in an
unbelievable number of libraries (not the largest though, NPM is the largest artifact
repository. But it has a huge amount of useless BS as well). By targeting the JVM,
users will have an easy time adopting the new languages because of the rich tools set
provided by the Java ecosystem and all the languages that targeted JVM as well. For example,
it will be possible to use libraries written in Scala or Clojure as well.

Long story short, I think the JVM is the right platform for me. The fact that many languages
have chosen it as their base platform shows how useful it can be. But there is a problem.
Targeting a higher level virtual machines like the JVM means that I'll have an easier job to
create a compiler. But I still have to write one. A compiler that takes the code and produces
JVM bytecode. As I mentioned earlier, writing a compiler is an enormous task and the chance
of doing it wrong with someone like me who has never built a compiler before is very high.

## One VM to rule them all
Luckily there is a solution. I can write an interpreter in a VM that is designed to optimize
my interpreter with all that wonderful JIT compilation magic. Oracle has released a new VM
that hopes to make writing language interpreters both easy and fast. It can also leverage
the huge ecosystem of the JVM. It is an enhanced JVM that contains a new JIT compiler which
can speed up interpreters to near Java speed. The new JIT compiler is called Graal. To use
the Graal’s JIT magic we can use the Truffle library to create the interpreter. We will
annotate the interpreter and give Graal some hints on invariants and type information.
According to Graal's documents, By doing this integration effort we get significant speedups
in out interpreter without having to resort to writing a bytecode compiler.

[GraalVM](https://www.graalvm.org/) is a Java VM and JDK based on HotSpot/OpenJDK,
implemented in Java. It supports different execution modes, like ahead-of-time compilation
of Java applications for fast startup and low memory footprint.

> GraalVM is a universal virtual machine for running applications written in JavaScript,
> Python, Ruby, R, JVM-based languages like Java, Scala, Groovy, Kotlin, Clojure, and
> LLVM-based languages such as C and C++.
>
> GraalVM removes the isolation between programming languages and enables
> interoperability in a shared runtime. It can run either standalone or in
> the context of OpenJDK, Node.js or Oracle Database.

I copied the above paragraph from GraalVM's official website. It is truly a VM to rule
them all.

[Truffle](https://github.com/oracle/graal/tree/master/truffle) library is one the key
players in GraalVM. The initial results of Truffle are super exciting. Implementations
of Ruby in Truffle has a performance on the same order of magnitude as the much bigger
projects of JRuby. Just checkout [Truffle Ruby](https://chrisseaton.com/truffleruby/)'s
website to get amazed by it.
There is a [Javascript implementation](https://github.com/graalvm/graaljs)
as well which showed great progress as well.
Lots of research has been dedicated to this topic and the result is mind blowing.
The interesting thing is that these Truffle implementations were done with fewer people
in a shorter period of time. This means you can create your own language on the JVM that
takes advantage of all it’s existing libraries, native threading, JIT compiler without
having to write your own compiler, and you get speeds that took other languages years
to achieve.

Using GraalVM as the platform for my new language will help me to be much faster because
All I need to do is to build an [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree)
interpreter and Graal will handle the rest. It means that I can start by building what is
important and use a very well engineered toolkit in my advantage to get to my goal quicker
and then later on replace any part that I like with my own implementation. How cool is that???

But as an engineer and a wannabe scientist I'd like to see the proof with my own eyes. Not
because I don't trust academic work, Just because it feels good to experience the proof.

So to begin with I'm going to create a dead simple Serene interpreter in Java and OpenJDK
and then build the same interpreter using Java on GraalVM using Truffle library and
compare the results and prove myself that choosing GraalVM is the right choice.

+ 0
- 261
_posts/2020-01-03-serene-simple-version.md View File

@@ -1,263 +0,0 @@
layout: post
title: "Step 2: Serene (Simple) version"
date: 2020-01-03
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/)
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 [#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
their hypothesis. As a result, Clojure is a well designed, stable
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. 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 as I need.

As I mentioned [earlier](/programming/choosing-the-target-platform/)
I think **GraalVM** and **Truffle** is the right answer for
Serene. But to verify my initial Idea I decided to run an experiment.
The experiment is all about implementing a Lisp in two environments.
A pure Java implementation vs a **Truffle** implementation.
I'll update the experiment files accordingly at the
[experiment reports](https://gitlab.com/serene-lang/experiment-reports/tree/master/001)
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 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.

> 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
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 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
structures directly.

## Reader/Parser
Instead of using a parser generator or a sophisticated parser, I just created
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 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 lots more details regarding to java
interop as well which I leave it out of this blog post.

## Scope
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 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,
Serene does not evaluate the arguments and leaves the evaluation to the special form
itself. Here is the list of Serene's special forms:

`def`: Creates a binding between a symbol name and the given value:
```cl
(def name "serene")
```

`fn`: Creates an anonymous function:
```clojure
(def inc (fn (x) (+ 1 x)))
```
`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`: Evaluates the body based on the return value of the given predicate.

```clojure
(if (= x 1)
(...) ;; if x is 1
(...)) ;; if x is not 1
```

`let`: Sets a local scope and runs its body using that scope.

```cl
(let ((x 1)
(y 2))
(println x y))
```

`do`: Simply groups several expressions together.

```clojure
(do
(println ...)
(if ....))
```

`cond`: Gets several predicates and only evaluates the body corresponding
to the first truthy predicate.

```cl
(cond
((= x 1) (body1...)
((= x 2) (body2...))
(true (else...))))
```

## Builtin Function
All the build in function are created by extending the `serene.simple.builtin.AFn`
abstract class and follow the same `Node` convention. Here is a list of the most
important built in functions:

`(println ....)`: Prints all the arguments on the stdout.

`(quit)`: Quits the program.

`(conj coll x...)`: Returns a new list by adding the given arguments.

`(count coll)`: Returns the number of elements in the given 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)`: Returns all the elements beside the first element of the given COLL.

`(doc fn)`: Returns the documentation for the given symbol if any.

`(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
arguments to its constructor.

### Example program
Here is an example program in Serene simple version (`benchmarks/fib.srns` in the repo):

```clojure
;; We have a reduce function but just in case...
(def reduce1
(fn (f xs initial-value)
(cond
((first xs) (reduce f (rest xs) (f initial-value (first xs))))
(true initial-value))))

;; A simple map function implementation in serene
(def map
(fn (f xs)
(reduce (fn (acc x) (cons acc (f x))) xs (list))))

(def range-list
(fn (x y init)
(if (< y x)
(do
(conj (range-list x (+ y 1) init) y))
init)))

(def range
(fn (x)
(range-list x 0 (list))))

(def fib
(fn (n)
(def fib-iter
(fn (x y z)
(if (= x 0)
z
(fib-iter (- x 1)
z
(+ y z)))))
(fib-iter n 0 1)))

(def benchmark-fn
(fn (x)
(let ((start (now)))
(println (fib x))
(- (now) start))))


(def run-benchmark
(fn (times)
(map (fn (x)
(println "Benchmark: " x)
(println "Took: " (benchmark-fn 500)))
(range times))))

(run-benchmark 20)

```


## What is missing ?
Since Serene (simple) is an experimental language and I'll abandon it eventually.
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:

* A namespace functionality. Because creating and compiling dynamic classes
is a massive task and needs tons of work which doesn't make sense for a toy
project.
* Unified function interface.
* 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 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.
* Quality code. The general quality of this implementation is not great, I
sacrificed quality for time.

## Conclusion
I'm not going to improve the simple version anymore at this stage. I'm going to run
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 comments or questions on this topic. As always
I'm available throw social media and email.

+ 0
- 32
_posts/2020-08-14-sameers-pyramid.md View File

@@ -1,34 +0,0 @@
layout: post
title: "Sameer's Pyramid"
date: 2020-08-14
categories:
tags: technology rant
theme: dark
**TL,DR**: Don't follow trends in the world of technology because usually they are not based on scientific
reasons and only based on so many people who don't have enough insight talking about a subject.

During my day to day life I see many conversations on social media around trends in technology. People
try to settle many debates by resorting to trends. "Everyone is using it, so it has to be the best!",
"It's all over the web, so it has to be true" or "It's impossible for so many people to be wrong, so
it must be good" or tons of similar reasonings. I always wondered about the nature of trends and hypes
and how they navigate the world. This post is the summary of my thoughts on the topic that lead me to
a hypathesis on the behavior of trends and how to ride them.


By evolution, humans are social creatures. During the course of human history, we always tend to form
groups and communities, villages, cities and civilizations. We have found our comfort and safety living among others
and society. Trading with other, fighting along side others and exchange words and wisdom with other. Society gives us
confident and the sense of stability. Often, we seek validation in a group. Dealing we the unknown is out of our comfort
zone and plays with our minds and puts us in a doubtful state of mind. Humans by nature are againt change we don't want
to loose the sense of stability and safety by changes to our surroundings and being in doubt creates fear. In a situation
like this people tend to resort to a group of other people to validate their thoughts and get ride of the doubt that is
bugging them. Exchanging experience and thoughts helps us to think better and stay calm. Seeing people who
had the same experience gives us courage and helps us to push the fear away. Community validates our way of dealing with
the unknown in life. It gives us direction.

But in the history of mankind there were many people (but few in compare to total number of humans) who were adventurous
and overcame their fear of the unknown. //Instead of hiding within the worm and welcoming and few people who breaks it . superstitios

In many cases people try to follow the hurd and the collective wisdom.

+ 0
- 8
_sass/bulma.sass View File

@@ -1,8 +0,0 @@
@charset "utf-8"
/*! bulma.io v0.7.4 | MIT License | github.com/jgthms/bulma */
@import "bulma/utilities/_all"
@import "bulma/base/_all"
@import "bulma/elements/_all"
@import "bulma/components/_all"
@import "bulma/grid/_all"
@import "bulma/layout/_all"

BIN
View File


+ 0
- 5
_sass/bulma/base/_all.sass View File

@@ -1,5 +0,0 @@
@charset "utf-8"

@import "minireset.sass"
@import "generic.sass"
@import "helpers.sass"

+ 0
- 130
_sass/bulma/base/generic.sass View File

@@ -1,130 +0,0 @@
$body-background-color: $white !default
$body-size: 16px !default
$body-rendering: optimizeLegibility !default
$body-family: $family-primary !default
$body-color: $text !default
$body-weight: $weight-normal !default
$body-line-height: 1.5 !default

$code-family: $family-code !default
$code-padding: 0.25em 0.5em 0.25em !default
$code-weight: normal !default
$code-size: 0.875em !default

$hr-background-color: $background !default
$hr-height: 2px !default
$hr-margin: 1.5rem 0 !default

$strong-color: $text-strong !default
$strong-weight: $weight-bold !default

html
background-color: $body-background-color
font-size: $body-size
-moz-osx-font-smoothing: grayscale
-webkit-font-smoothing: antialiased
min-width: 300px
overflow-x: hidden
overflow-y: scroll
text-rendering: $body-rendering
text-size-adjust: 100%

article,
aside,
figure,
footer,
header,
hgroup,
section
display: block

body,
button,
input,
select,
textarea
font-family: $body-family

code,
pre
-moz-osx-font-smoothing: auto
-webkit-font-smoothing: auto
font-family: $code-family

body
color: $body-color
font-size: 1rem
font-weight: $body-weight
line-height: $body-line-height

// Inline

a
color: $link
cursor: pointer
text-decoration: none
strong
color: currentColor
&:hover
color: $link-hover

code
background-color: $code-background
color: $code
font-size: $code-size
font-weight: $code-weight
padding: $code-padding

hr
background-color: $hr-background-color
border: none
display: block
height: $hr-height
margin: $hr-margin

img
height: auto
max-width: 100%

input[type="checkbox"],
input[type="radio"]
vertical-align: baseline

small
font-size: 0.875em

span
font-style: inherit
font-weight: inherit

strong
color: $strong-color
font-weight: $strong-weight

// Block

fieldset
border: none

pre
+overflow-touch
background-color: $pre-background
color: $pre
font-size: 0.875em
overflow-x: auto
padding: 1.25rem 1.5rem
white-space: pre
word-wrap: normal
code
background-color: transparent
color: currentColor
font-size: 1em
padding: 0

table
td,
th
text-align: left
vertical-align: top
th
color: $text-strong

+ 0
- 276
_sass/bulma/base/helpers.sass View File

@@ -1,276 +0,0 @@
// Float

.is-clearfix
+clearfix

.is-pulled-left
float: left !important

.is-pulled-right
float: right !important

// Overflow

.is-clipped
overflow: hidden !important

// Overlay

.is-overlay
@extend %overlay

// Typography

=typography-size($target:'')
@each $size in $sizes
$i: index($sizes, $size)
.is-size-#{$i}#{if($target == '', '', '-' + $target)}
font-size: $size !important

+typography-size()

+mobile
+typography-size('mobile')

+tablet
+typography-size('tablet')

+touch
+typography-size('touch')

+desktop
+typography-size('desktop')

+widescreen
+typography-size('widescreen')

+fullhd
+typography-size('fullhd')

$alignments: ('centered': 'center', 'justified': 'justify', 'left': 'left', 'right': 'right')

@each $alignment, $text-align in $alignments
.has-text-#{$alignment}
text-align: #{$text-align} !important

@each $alignment, $text-align in $alignments
+mobile
.has-text-#{$alignment}-mobile
text-align: #{$text-align} !important
+tablet
.has-text-#{$alignment}-tablet
text-align: #{$text-align} !important
+tablet-only
.has-text-#{$alignment}-tablet-only
text-align: #{$text-align} !important
+touch
.has-text-#{$alignment}-touch
text-align: #{$text-align} !important
+desktop
.has-text-#{$alignment}-desktop
text-align: #{$text-align} !important
+desktop-only
.has-text-#{$alignment}-desktop-only
text-align: #{$text-align} !important
+widescreen
.has-text-#{$alignment}-widescreen
text-align: #{$text-align} !important
+widescreen-only
.has-text-#{$alignment}-widescreen-only
text-align: #{$text-align} !important
+fullhd
.has-text-#{$alignment}-fullhd
text-align: #{$text-align} !important

.is-capitalized
text-transform: capitalize !important

.is-lowercase
text-transform: lowercase !important

.is-uppercase
text-transform: uppercase !important

.is-italic
font-style: italic !important

@each $name, $pair in $colors
$color: nth($pair, 1)
.has-text-#{$name}
color: $color !important
a.has-text-#{$name}
&:hover,
&:focus
color: darken($color, 10%) !important
.has-background-#{$name}
background-color: $color !important

@each $name, $shade in $shades
.has-text-#{$name}
color: $shade !important
.has-background-#{$name}
background-color: $shade !important

.has-text-weight-light
font-weight: $weight-light !important
.has-text-weight-normal
font-weight: $weight-normal !important
.has-text-weight-semibold
font-weight: $weight-semibold !important
.has-text-weight-bold
font-weight: $weight-bold !important

.is-family-primary
font-family: $family-primary !important

.is-family-secondary
font-family: $family-secondary !important

.is-family-sans-serif
font-family: $family-sans-serif !important

.is-family-monospace
font-family: $family-monospace !important

.is-family-code
font-family: $family-code !important

// Visibility

$displays: 'block' 'flex' 'inline' 'inline-block' 'inline-flex'

@each $display in $displays
.is-#{$display}
display: #{$display} !important
+mobile
.is-#{$display}-mobile
display: #{$display} !important
+tablet
.is-#{$display}-tablet
display: #{$display} !important
+tablet-only
.is-#{$display}-tablet-only
display: #{$display} !important
+touch
.is-#{$display}-touch
display: #{$display} !important
+desktop
.is-#{$display}-desktop
display: #{$display} !important
+desktop-only
.is-#{$display}-desktop-only
display: #{$display} !important
+widescreen
.is-#{$display}-widescreen
display: #{$display} !important
+widescreen-only
.is-#{$display}-widescreen-only
display: #{$display} !important
+fullhd
.is-#{$display}-fullhd
display: #{$display} !important

.is-hidden
display: none !important

.is-sr-only
border: none !important
clip: rect(0, 0, 0, 0) !important
height: 0.01em !important
overflow: hidden !important
padding: 0 !important
position: absolute !important
white-space: nowrap !important
width: 0.01em !important

+mobile
.is-hidden-mobile
display: none !important

+tablet
.is-hidden-tablet
display: none !important

+tablet-only
.is-hidden-tablet-only
display: none !important

+touch
.is-hidden-touch
display: none !important

+desktop
.is-hidden-desktop
display: none !important

+desktop-only
.is-hidden-desktop-only
display: none !important

+widescreen
.is-hidden-widescreen
display: none !important

+widescreen-only
.is-hidden-widescreen-only
display: none !important

+fullhd
.is-hidden-fullhd
display: none !important

.is-invisible
visibility: hidden !important

+mobile
.is-invisible-mobile
visibility: hidden !important

+tablet
.is-invisible-tablet
visibility: hidden !important

+tablet-only
.is-invisible-tablet-only
visibility: hidden !important

+touch
.is-invisible-touch
visibility: hidden !important

+desktop
.is-invisible-desktop
visibility: hidden !important

+desktop-only
.is-invisible-desktop-only
visibility: hidden !important

+widescreen
.is-invisible-widescreen
visibility: hidden !important

+widescreen-only
.is-invisible-widescreen-only
visibility: hidden !important

+fullhd
.is-invisible-fullhd
visibility: hidden !important

// Other

.is-marginless
margin: 0 !important

.is-paddingless
padding: 0 !important

.is-radiusless
border-radius: 0 !important

.is-shadowless
box-shadow: none !important

.is-unselectable
@extend %unselectable

+ 0
- 84
_sass/bulma/base/minireset.sass View File

@@ -1,84 +0,0 @@
/*! minireset.css v0.0.4 | MIT License | github.com/jgthms/minireset.css */
// Blocks
html,
body,
p,
ol,
ul,
li,
dl,
dt,
dd,
blockquote,
figure,
fieldset,
legend,
textarea,
pre,
iframe,
hr,
h1,
h2,
h3,
h4,
h5,
h6
margin: 0
padding: 0

// Headings
h1,
h2,
h3,
h4,
h5,
h6
font-size: 100%
font-weight: normal

// List
ul
list-style: none

// Form
button,
input,
select,
textarea
margin: 0

// Box sizing
html
box-sizing: border-box

*
&,
&::before,
&::after
box-sizing: inherit

// Media
img,
embed,
iframe,
object,
video
height: auto
max-width: 100%

audio
max-width: 100%

// Iframe
iframe
border: 0

// Table
table
border-collapse: collapse
border-spacing: 0

td,
th
padding: 0
text-align: left

+ 0
- 15
_sass/bulma/components/_all.sass View File

@@ -1,15 +0,0 @@
@charset "utf-8"

@import "breadcrumb.sass"
@import "card.sass"
@import "dropdown.sass"
@import "level.sass"
@import "list.sass"
@import "media.sass"
@import "menu.sass"
@import "message.sass"
@import "modal.sass"
@import "navbar.sass"
@import "pagination.sass"
@import "panel.sass"
@import "tabs.sass"

+ 0
- 75
_sass/bulma/components/breadcrumb.sass View File

@@ -1,75 +0,0 @@
$breadcrumb-item-color: $link !default
$breadcrumb-item-hover-color: $link-hover !default
$breadcrumb-item-active-color: $text-strong !default

$breadcrumb-item-padding-vertical: 0 !default
$breadcrumb-item-padding-horizontal: 0.75em !default

$breadcrumb-item-separator-color: $grey-light !default

.breadcrumb
@extend %block
@extend %unselectable
font-size: $size-normal
white-space: nowrap
a
align-items: center
color: $breadcrumb-item-color
display: flex
justify-content: center
padding: $breadcrumb-item-padding-vertical $breadcrumb-item-padding-horizontal