/oczor

Oczor is a simple statically typed language that compiles to JavaScript, Lua, Ruby and Emacs Lisp

Primary LanguageHaskellMIT LicenseMIT

The goal

A simple statically typed language that should be easily compiled to dynamically typed languages

Build Status

Occam's Razor

Entities should not be multiplied unnecessarily.

-- William of Ockham

For example, many languages has these entites

  • variables
     var foo = 1;
     var bar = 2;
    
  • parameters
     function (foo,bar) { return foo + bar; }
    
  • objects
     {foo : 1, bar : 2}
    
  • tuples
     (1,2)
    

Oczor uses records instead of all these entities

Example of generated JavaScript code

OczorJavaScript
x1 = 1

x2 = 
  foo = 1
  bar = 1


func x y = x + y + 1



x3 = func 1 2

func2 x = 
  temp = x == 1
  in not (temp && false)

  var x1 = 1;

  var x2 = {
    foo : 1,
    bar : 1
  };

  var func = function(x,y){
    return x + y + 1;
  };

  var x3 = func(1,2);

  var func2 = function(x){
    var temp = x === 1;
    return !(temp && false);
  };

Other languages

Syntax

Most syntax constructions have two options - comma or indent separation

CommaIndentation
x = (foo = 1, bar = 2)



type Cat = name : String, age : Int



x = 
  foo = 1
  bar = 2

type Cat = 
  name : String
  age : Int
  

Records

x = (foo = 1, bar = 2)

labels

print x.foo
print x.bar

record update

y = x with (foo = 2)

tuples

Tuple is a record with labels itemN

x = (2,3)

same as

x = (item1 = 2, item2 = 3)

Destructuring assignment

x = (2,3)
(y,z) = x
print y
x = (foo = 1, bar = 2)
 
(foo = y, bar = z) = x
print y

Functions

anonymous

x y => (x,y) or \x y => (x,y) -- \ is optional

function definition

function definition is a syntax sugar for a label with anonymous function

foo x y = (x,y)

same as

foo = \x y => (x,y)
z = foo 1 2

For example, it is possible to group functions like this

bar = 
  foo x y = (x,y)
  id z = z
bar.foo 1 2
bar.id 1

Pattern matching

Parameters can be matched with literals, tuples, records or external variables

x = 1
foo = case
  1 => 2
  (x,2) => 3
  (foo = x, bar = 3) => 4
  ^x => 5

partial application

inc : Int => Int
inc = add _ 1

x = inc 1

Foreign function interface

function eqAny(x,y) {
  return x === y;
}
ffi eqAny : a, a => Bool

Operators

infix == 4 eqAny
x = if 1 == 2 then 1 else 2 

Types

Record Type

type Cat = 
  name : String
  age : Int
cat = (name = "Tiger", age = 25)

Union Type

type Number = Int | Double

x : Array Number
x = [1, 2.0, 3]

Ad-hoc polymorphism

ffi eqInt : Int, Int => Bool
ffi eqString : String, String => Bool

class equal a : a => Bool

instance Int equal x y = eqInt x y
instance String equal x y = eqString x y

infix == 4 equal

x = 1 == 1
y = "foo" == "foo"

Development state

Alpha/Experimental

Installation

  1. Install stack.

  2. clone or download this repository

  3. In project directory run

    stack setup
    stack install
    

    stack install will install the occ executable into ~/.local/bin, which you should add to your PATH.

How to use

  1. create a directory hello

  2. copy std directory from libs directory

  3. create a file hello.oc

    import std
    print "hi"
    
  4. run occ to compile hello.oc

    occ hello.oc
    

    hello.js should be in output directory

  5. hello.js can be run with node

    node output/hello.js
    

    should print hi

  6. occ --help to display the compiler options