/manju

Manju is a simple object oriented, dynamically typed, functional language that runs on the Erlang virtual machine (BEAM).

Primary LanguageElixirMIT LicenseMIT

Manju

Manju is a simple object oriented, dynamically typed, functional language that runs on the Erlang virtual machine (BEAM). Manju's syntax is Python-like syntax. Manju also got an influence from Ruby and Mochi.

Its compiler is written in Elixir. The compiler translates a program written in Manju to Erlang's AST / bytecode.

Language Features

Builtin Types

### Numbers

49  # integer
4.9 # float

### Booleans

True
False

### Atoms

'foo'

### Lists

list = [2, 3, 4]
list2 = [1|list] # => [1, 2, 3, 4]
[1, 2, 3|rest] = list2
rest # => [4]

list.append(5) # => [2, 3, 4, 5]
list # => [2, 3, 4]


list.select(lambda item: item > 2)
    .map(lambda item: item * 2) # => [6, 8]
list # => [2, 3, 4]

# list comprehensions
[n * 2 for n in list] # => [4, 6, 8]

### Tuples

tuple = (1, 2, 3)
tuple.select(lambda item: item > 1)
     .map(lambda item: item * 2) # => [4, 6]

tuple.to_list() # => [1, 2, 3]


### Dicts (Maps)

dict = {'foo': 1, 'bar': 2}
dict2 = dict.put('baz', 3) # => {'foo': 1, 'bar': 2, 'baz': 3}
dict # => {'foo': 1, 'bar': 2}
dict.get('baz', 100) # => 100

### Strings

"Abc"

### Binaries

<<1, 2, 3>>
<<"abc">>
<<1 , 2, x>> = <<1, 2, 3>>
x # => 3

### Anonymous functions

add = lambda x, y: x + y
add(40, 9) # => 49

multiply = lambda x, y:
  x * y

multiply(7, 7) # => 49

Class definition

Car.mj:

class Car:
    def __new__():
        {'name': "foo",
         'speed': 100}

    def format(self):
        # self's state is immutable and private.
        # self's state can be referred by "self.attr_name" form.
        self.name.display()
        self.speed.display()

# # usage:
# car = new Car()
# car.format()

Module definition

Enumerable.mj:

def select(self, func):
    _select = lambda item, acc:
        if func.(item):
            acc.append(item)
        else:
            acc

    self.reduce([], _select)


def map(self, func):
    _map = lambda item, acc:
        acc.append(func.(item))

    self.reduce([], _map)

Mixing in Modules

SampleList.mj:

class SampleList:
    include Enumerable

    def __new__(items):
        {'items': items}

    def reduce(self, acc, func):
        lists::foldl(func, acc, self.items)

# # usage:
# sample_list = new SampleList([1, 2, 3])
# sample_list.select(lambda item: item > 1)
#            .map(lambda item: item * 2}
#            # => [4, 6]

Module attributes

SampleList.mj:

class SampleList:
    include Enumerable
    @author("i2y", "others")

    def __new__(items):
        {'items': items}

    @obsolete
    def reduce(self, acc, func):
        lists::foldl(func, acc, self.items)

    @obsolete("since version 12")
    def append(self, item):
        self.items.append(item)

# # usage:
# list = new SampleList([1, 2, 3])
# list.class_attr_values('author')
# # => [["i2y", "others"]]
# list.class_attr_values('obsolete')
# # => [[('reduce', 3)], ["since version 12", ('append', 2)]]

Pipe operator

[1, 2, 3] |> lists::append([4, 5, 6])
          |> lists::append([7, 8, 9])
# => [1, 2, 3, 4, 5, 6, 7, 8, 9]

[1, 2, 3] |>> lists::append([4, 5, 6])
          |>> lists::append([7, 8, 9])
# => [7, 8, 9, 4, 5, 6, 1, 2, 3]

Other assorted features

### Ranges
1..10 # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# WIP

Not supported features

  • Class inheritance
  • Lisp-like Macro definition

Requirements

  • Erlang/OTP >= 18.0
  • Elixir >= 1.1

Installation

$ git clone https://github.com/i2y/manju.git
$ cd manju
$ mix archive.build
$ mix archive.install
$ mix escript.build
$ cp manju <any path>

Usage

Command

Compiling:

$ ls
foo.mj
$ manju foo.mj
$ ls
foo.beam foo.mj

Compiling and Executing:

$ cat foo.mj
def bar():
    123.display()
$ manju -r foo::bar foo.mj
123

Mix

mix.exs file example:

defmodule MyApp.Mixfile do
  use Mix.Project

  def project do
    [app: :my_app,
     version: "1.0.0",
     compilers: [:manju|Mix.compilers],
     deps: [{:manju, git: "https://github.com/i2y/manju.git"}]]
  end
end

".mj" files in source directory(src) is automatically compiled by Mix command.