Getting Started

Installation

First get olang(.exe) file or go get -v gitlab.com/olanguage/olang and run olang(.exe) (-r) <filename> (-d=true [debug mode])

Thats it.

First Example

Create file with example.ola;

show("Hello Galaxy!")

Run files

Run file with olang;

olang example.ola

"Hello Galaxy!"

Thats all.

Files

Olang files is to simple. Default file extension “.ola”. Let’s start by examining the programming language example.

test.ola

def hello = fn(name){ return ("Hello, "+name+"! Welcome to O-lang!") }

def result = hello("Oytun") show(result)

Run: $ chmod a+x test.ola $ ./test.ola or $ olang test.ola

Output: Hello, Oytun! Welcome to Olang

What is SOFPL?

System Oriented Functional Programming Language (SOFPL) is a specific structure that interprets each line separately and outputs the result. Shorten the functions performed in normal programming languages. For example, you can do the functions you can do in 10 lines with a line. It is up to you to determine what you will do in 9 lines. :)

In addition, you can start the process on the system, you can open the port and start data transfer. Simple socket software and transaction management functions are available and developed.

Use single line save for lines

C lang Hello World example;

# include < stdio.h > int main() { // printf() displays the string inside quotation printf("Hello, World!"); return 0; }

With the C programming language you have spent 7 lines to write the hello world.

Hello World example;

def hello = fn(name){ return "Hello, "+name+"! Welcome to O-lang!" } hello("Oytun")

No function write as:

"Hello, World!"

Print function write as:

show("Hello, World!")

or:

println("Hello, World!")

You can do this in just one line. Save more time with Olang.

The SLFPL structure saves you a lot of lines.

Socket is suitable for programming and transaction management.

You can run system processes directly and then write applications on the results.

dial_serve.ola (dial serve example): sock socket "tcp4" "9050" "0.0.0.0"; def messages = { "ping": "pong", "call": "Calling... NOPE! :)", "help": "Not helpfull!" } dial_service(socket, messages);

The 9050 port is ready to connect.

dial_client.ol (dial client example):

sock socket "tcp4" "9050" "0.0.0.0"; def send = fn(message){ println(dial_send(socket, message)) } send("call") send("help")

Output: Calling... NOPE! :) Not helpfull!

In this example, a dial was made. Runs a socket directly on the system and exchanges messages.

proc ls "ls" "/home/olang-home" ["-alh"] env "TEST" "test" rintln(sysenv("TEST")) println(ls)

test ...folder contents....

In this example, a process is set up and output is provided. In addition, we have defined the system variable and let it do so.

Scopes

The scope structure is similar to class structures. All the functions defined in scope form subfunctions of a scope. In this way you can clustering by writing functions in the main scope.

Scope definition: scope example { def hello = fn(x){ return ("Hello "+x) }; def subone = fn(x){ return (x + 1) }; }

Scope call:

def hello = example::hello("Oytun") def number = example::subone(1) show(hello) show(number)

Scope output:

Hello Oytun 2

Loops

Cycles differ from other languages by a semicolon.

loop.ola (loop example): def i = 0; loop(i>100){ println(i); def i = (i+1); } def arr = [1,2,3,4,5] for(arr in k,v){ println(v) } def arrtwo = {"one":1, "two":2}; for(arrtwo in k,v){ println(k) println(v) }

Output:

1 2 3 4 .... 100 1 2 3 4 5 one 1 two 2

Loading Modules

Olang files is to simple. File extension “.ol”. Let’s start by examining the programming language example.

hello.ol (as hello module):

def hello = fn(name){ show("Hello, "+name+"! Welcome to Olang") }

load.ol (main file):

load "hello.ol" def name = "Oytun"; hello(name);

Run:

$ olang load.ol

Output:

Hello, Oytun! Welcome to Olang

Literals

The literal definition is used to describe the system invariants. These definitions maintain their validity throughout the system. Similar to definitions. There is no need to use a parameter for a single variable. But for multiple variables, brackets and commas are the same as in functions.

Example;

literal db(name){ createdb(name) } db "database" literal writedb(name, key, data){ insertdb(name, key, data) } writedb ("database", "olang", "Hello olang data struct!")

Output: ...created db ...writed data

HTTP/S Sockets

You can use the http(path, port, response) or https(path, port, response, servercrt, serverkey) function to easily create an http socket.

httptest.ol:

show("Listening 0.0.0.0:8080... Ctrl+C to exit.") http("/", "8080", "Hello, Olang World from Web!");

httpstest.ol: show("Listening 0.0.0.0:8443... Ctrl+C to exit.") https("/", "8443", "Hello, Olang World from Web!", "server.crt", "server.key");

First we loaded our “hello” module with load. Later in the hello() function on the 8080 or 8443 (needs; server.crt and server.key)port to provide this output. When we enter port localhost:8080 or localhost:8443 (needs; server.crt and server.key) from our browser or curl, the result will be;

~> curl localhost:8080 Hello, Oytun! Welcome to Olang

Dialer Functions

Dialer functions can automatically initiate a socket or provide sockete access and automatically communicate over a socket.

dial_serve.ola (dial serve example):

`sock socket “tcp4” “9050” “0.0.0.0”; def messages = { “ping”: “pong”, “call”: “Calling… NOPE! :)”, “help”: “Not helpfull!” } dial_service(socket, messages)

The 9050 port is ready to connect.

dial_client.ol (dial client example):

sock socket "tcp4" "9050" "0.0.0.0"; def send = fn(message){ println(dial_send(socket, message)) } send("call") send("help")

Output: Calling... NOPE! :) Not helpfull!

Definitions

Simple casting definition; def something = something;

Hash

Simple casting hashes; def pyramid = {"x":10, "y":10, "z":10} pyramid["x"] 10

Array

Simple casting arrays; def triangle = [10,20,30] triangle[1] 10

Integer

Simple casting integer; def zero = 0 0

String

Simple casting string; def name = "Oytun" "Oytun"

Functions

Simple casting functions; def sum = fn(x,y){ return x+y; } sum(10,6) 16

Process

Simple casting system processes; proc procname "command" "work path" ["arg1","arg2"]

Socket

Simple casting system sockets; sock socketname "type" "port" "ip"

Exception Management

O-Lang Exception Management

Exception management is an array that allows you to check whether an error has occurred depending on an object. The content is checked to see if there is an error, or to the end if no error has occurred.

Begin is used to control an object.

begin object{ ...... }

“Expect” and “recover” are used to debug and print out errors. Automatic “error” identification is done. In this way, we can use this definition as an internal variable.

def test = "hello" begin object{ if (test == "hello"){ except test "Hello is not usefull. Please use Hi on project." } recover test{ println(error) } }

If no errors are received, “final” is used. If there is no error in this way, the values in “final” are automatically executed.

def test = "hello" begin object{ if (test == "hello"){ except test "Hello is not usefull." } recover object{ println(error) } final object{ println("Hello is not used. Yay!") } }

This is how we debug it. Exception detection can be used in this way.

Search

Search all in database with single and multiple queries. Results always array.

def resultdef = (search(modeldef, [.....strings] or string))

Resultdef is your result definition and modeldef is your model definition. Query side is too simple. Use one string to search or use array for multiple search in single result. Thats magic.

This too easy for query management.

For example you make indexing pages but you cannot find best pages with query;

def indexdb = (database("internal","./indexdb")) def page = (model(indexdb, "pages", {})) def i = 0; loop(i>=100){ create(page, {"page_"+i:"Example Page ("+i+")"}) def i = (i+1); } def results = (search(page, ["page_8","page_5", "Example Page 4"]))

...page_8, page_5 or "Example Page 4" search results

Automaticaly search in key,value based storage and gives results for use.

Sub Note:

Some database types can give you results based on variables you give. You can create your own functions in unsupported types.

Query

If you need more customized sql queries. Query function is too simple;

def resultdef = (query(modeldef, "YOUR QUERY....", params))

Resultdef is your result definition and modeldef is your model definition. Queries and params prepare for query. It needs more customization for your needs.

For example we get users query with limited data;

def limited_users = (query(user, "SELECT * FROM users LIMIT ?", 100))

We defined limited_users and run parameterized query. We limited 100 users to get. All done.

Fetch

Now we look changes and etc. Use simple ussage;

def resultdef = (fetch(modeldef, {...keys and values}))

Resultdef is result definition and model definition with keys or empty for all data.

For example we need to view payment changes;

def payment_list = (fetch(payment, {"id": 1}) inspect(payment_list)

We fetch first user from payments and defined to payment_list definition. Inspect command looks to some definition debugging.

Delete

We need to delete something from model. Use simple case;

def resultdef = (delete(modeldef, {....keys and values}))

Resultdef for result (maybe true, false or error). Modeldef is your model definition. Keys and values (aka hash) for what do you need to delete.

For example delete maked payment;

def deleted = (delete(payment, {"id": 1})); if (deleted){ show("Payment 1 deleted.") } Deleted definition is simple. We are deleted first payment.

Create and Update

Now everything was ready. We go on create and update statements.

create(modeldef, {values and keys... for create}) update(modeldef, {values and keys...}, {values and keys...})

Create function needs two things;

  1. Modeldef is your model definition and objects are your objects.
  2. Keys and values (Hash) for what do you want to create.

For example;

create(user, { "id": 1, "name": "Oytun", "username": "oytunistrator", #.....other information })

create(payment, { "user_id": 1, "money": 100, "currency": "$" #....other information })

We created one user and created payment for example. Now we need to change payment values;

update(payment, {"user_id":1}, {"money": 200})

Payment changed 100 -> 200 for first user.

Models and Connections

Connections;

First we need to define database connection;

def db = (database("dbtype","dbstring"))

Database type and Database strings are connection types. For example you need sqlite3 connection;

def db = (database("sqlite3","sqlite_database_example.db"))

Now ready to connect models and databases;

def modeldef = (model(db, "modelname", {....table definitions}))

Db is your database connection. Model name and table definitions make table structure. Modeldef is simple model definition.

For example we need to users and payments tables;

def user = (model(db, "users", { "id": "int" "name": "text", "surname": "text", "username": "text", "email": "text", "password": "text", }))

def payment = (model(db, "payments", { "user_id": "int", "money": "int", "currency": "text", "datetime": "DATETIME", "duedate": "DATETIME" }))

All models ready for use. If you need migration with database;

drop(modeldef) #=> if your table exist in database use drop function first before migration. migrate(modeldef)

Modeldef is your definition. We need two models for migrate;

drop(user) drop(payment) migrate(user) migrate(payment)

Tokens

Token List For General Use;

fn

Function: def object = fn(...){....}

def

Define: def object = something

true

Boolean: true

false

Boolean: false

if

If statement: if(...boolean){ .... }

else

Else statement: else{ .... }

return

Return: def pi = fn(x){** return "3.14" **}

show

Show (builtin function): show(object)

println

Print (builtin function): println(object)

loop

Loop array variables (or define with return)

loop(condition){...result}

def result = loop(condition){return ...result}

....results array or object

Example;

def i = 0; loop(i>100){ println(i); def i = (i+1); }

...results...

for

For loop generates results from loops

def arr = [1,2,3,4,5] for(arr in k,v){ println(v) } def arrtwo = {"one":1, "two":2}; for(arrtwo in k,v){ println(k) println(v) }

...results...

load

Load some olang module, file etc: load "filename"

scope

Create scope for functions or variables:

scope scopename { def scopevar = somevariable; def scopefn = fn(....){....} } scopename::scopevar scopename::scopefn(....)

proc

Create system process; proc procname "command" "work path" ["arg1","arg2"] ....process result

sock

Create system socket; sock socketname "type" "port" "ip" ...sock result

env

Create system environment value or change; env "type" "value" getenv(result) ....value

Functions

itostr

Convert integer to string. But strings and integers not connect with plus iteration (Ex: “Hello”+0 => imposible need to convert 0 or “Hello” to string or integer in IRL[In real life]).

For example; def i = 0; 0 def str = itostr(i) "0"

len

Gives something to length. Sometimes usefull for length calculation. Easy to use.

Example;

def arr = [1,2,3,4,5] def lenArr = len(arr) 5

first

All objects gives first item. Thats all.

Example;

def hsh = {"x":10, "y":20, "z":30} def fhsh = first(hsh) {"x":10} def arr = [1,2,3,4,5] def farr = first(arr) 1

last

All objects gives last item. Thats all.

Example;

def hsh = {"x":10, "y":20, "z":30} def fhsh = last(hsh) {"z":30} def arr = [1,2,3,4,5] def farr = last(arr) 5

rest

Extract first element from arrays;

def arr = [1,2,3,4,5] len(arr) 5 rest(arr) len(arr) 4 arr [2,3,4,5]

push

Add element to arrays;

def arr = [1,2,3,4,5] push(arr, 6) [1,2,3,4,5,6]

println

Print every type convert string and show one line;

def hello = "Hello"; println(hello) # => "Hello\n"

show

Print every type convert string and show directly;

def hello = "Hello"; show(hello)

"Hello"

colorize

This is colorize function colorize some object and show directly. Run only ASCII consoles. You need to enabled colors.

colorize(colorstring, string, background:true|false)

Colorlist:

  • red
  • blue
  • green
  • yellow
  • grey
  • black
  • bold
  • magenta
  • white

http

Runs http server with string or rendered objects.

http(routepath, port, string object);

https

Runs http server with string or rendered objects.

http(route path, port, string object, crt key, server key);

file

Opens some file gives content directly.

def definition = file(file name)

Example;

def hellofile = file("hello.txt") "This is test file content for example"

atostr

Gives some arrays from some key with string object.

Example;

def arr = [1,2,3,4,5] atostr(arr, 0) "1"

router

Router definition function. Simple create router use for web servers or micro servers.

router(port, hash definition);

Example;

def config = { "/": { "type": "GET", "response": "Hello!", }, }; router("8080", config)

Defined new route with this example;

GET http://0.0.0.0:8080/ "Hello!"

createdb

Creates new database with inline named folder.

createdb(dbname)

Created new key based database in current folder.

insertdb

Insert database something.

insertdb(dbname, key, value)

getdb

Get database with some key.

getdb(dbname, key)

deletedb

Delete database with some key.

deletedb(dbname, key)

searchdb

Directly search all database with get all objects.

searchdb(dbname, some string)

getval

Get some value converts to string. After automaticaly show or define value.

Example;

def x = 12; getval(x) "12"

jsonp

Automaticaly parse json string and return hash object.

Example; def js = "{val1:1,val2:2}" jsonp(js) {"val1":1, "val2":2}

xmlp

Convert all xml string to hash or array object

Example; def xmlo = "<arr><type1>1<type1><type2>2<type2><type3>2<type3></arr>" xmlp(xmlo) {"arr":{"type1":1,"type2":2,"type3":3}}

wdir

Return current working directory.

wdir() "/home/oytun/olang/"

chdir

Change directory and return changed directory.

chdir("/home/oytun/olang/") "/home/oytun/olang/"

renderf

File render function. Some objects to render some file and gives string.

Example;

file.txt: output:

script: renderf("file.txt", {"output": "Olang Render Example"})

result: Olang Render Example

sysenv

Shows system environment tables or set some environment variable sysenv(some system environment string, ...some system environment string)

Example; sysenv("PATH") /usr/local/bin:/bin:/usr/bin

proc_kill

Kill some proccess with system pid proc_kill(pid integer only)

Example; proc_kill(330) ...killed 330 pid application or service

proc_exec

Execute some system command in background and return Process object. proc_exec(command strings...)

Example; proc_exec("ls -al") Files....

proc_out

Executed process show or define output proc example "ls" "/home/olang" ["-lha"] proc_out(example) .....files

proc_pid

Executed process pid return proc example "ls" "/home/olang" ["-lha"] proc_pid(example) 12345 (proc pid)

inspect

This is debugging function for variables. inspect(...objects)

Example; def x = 1; inspect(x) 1

regexp_check

Check regexp and string return bool object result. def rex = "[A-Z][a-z]" def matched = regexp_check(rex, "Hello!") true

regexp_find

Find all regexp results and return array object. def rex = "el" def matched = regexp_find(rex, "Hello!") ["el"]

dial_service

Create dial messaging service from socket. All requests and response need to hash iteration. sock socket "tcp4" "9050" "0.0.0.0"; def messages = {"ping": "pong"} dial_service(socket, messages);

Created dial service.

dial_send

Send messages to dial_service sock socket "tcp4" "9050" "0.0.0.0" dial_send(socket, "ping")

Returns “pong” called from dial_service.

quit

Quit from olang quit()

File Types

File Types and mimes for general use;

  • Olang Singe File (.ola) - olang/single-file
  • Olang Module File (.ols) - olang/scope-file
  • Olang Module File (.olm) - olang/module-file
  • Olang Process File (.olproc) - olang/process-file
  • Olang Program File (.olprog) - olang/program-file
  • Olang Library File (.olibrary) - olang/library-file
  • Olang Compresed File (.olc) - olang/compresed-file
  • Olang Packaging File (olpfile.json) - olang/olpfile
  • Olang Process File (Opsfile) - olang/opsfile

XML Parser

The xmlp() function is used to parse the XML. It is extremely simple to use. Returns the result as a hash.

def result = (xmlp("test.xml")) show(result)

Output: ...xml content...

URL Fetcher

The urlfetch(< type (GET, POST) >, < url >, < data for POST >) and urlextract (< url object >, < option >) functions execute URL operations for data retrieval and destructor functions.

urlfetch.ol:

def olang = (urlfetch("GET","http://o-lang.tk")) def type = (urlextract(olang, "content-type")) def length = (urlextract(olang, "content-length")) def server = (urlextract(olang, "server")) def body = (urlextract(olang, "body"))

show(type) show(length) show(server) show(body)

Output: ....content....

Render Files

The renderf() function is used to combine and render files with parameters. It’s simple to use. Returns the result as a string.

def filerender = (renderf("test.html", { "hello": "World", "title": "Hello Example" })) show(filerender)

Input: <html> <head> <title>{{.title}}!</title> </head> <body> <h1>{{.hello}}!</h1> </body> </html>

Output: <html> <head> <title>Hello Example!</title> </head> <body> <h1>World!</h1> </body> </html>

JSON Parser

The jsonp() function is used to parse the JSON. It is extremely simple to use. Returns the result as a hash.

def json = (jsonp("test.json")) show(json)

Output: { hello: Hello World, title: Hello Example, hello2: [{test: Test}, {test: Test}] }

Ascii Colors

The colorize() function is used to color the terminal. When needed, beautiful prints can be obtained by giving colors.

Color example (colorize.ol):

colorize("red", "Hello Colorize!") colorize("blue", "Hello Colorize!") colorize("green", "Hello Colorize!") colorize("yellow", "Hello Colorize!") colorize("grey", "Hello Colorize!") colorize("black", "Hello Colorize!") colorize("bold", "Hello Colorize!") colorize("magenta", "Hello Colorize!") colorize("white", "Hello Colorize!") colorize("red", "Hello Colorize!", true) colorize("blue", "Hello Colorize!", true) colorize("green", "Hello Colorize!", true) colorize("yellow", "Hello Colorize!", true) colorize("grey", "Hello Colorize!", true) colorize("black", "Hello Colorize!", true) colorize("bold", "Hello Colorize!", true) colorize("magenta", "Hello Colorize!", true) colorize("white", "Hello Colorize!", true);

Output:

colorize-terminal-example

Router Example

The router socket structure was created with the intention of creating an API over the HTTP/S protocol and exchanging data through the socket. In web based projects it is possible to write web server quickly and easily. In addition, the API can be created in micro-services.

hello.ol (as hello module): def hello = fn(name){ return ("Hello, "+name+"! Welcome to Olang") }

router.ol (as router module):

load "hello.ol" def config = { "GET" : { "/" : "Welcome to the O-Lang Router!" }, "POST":{ "/:name" : (hello("{{.name}}")) } } show("Listening 0.0.0.0:8080... Ctrl+C to exit.") router("8080", config);

GET method test:

~> curl -X GET localhost:8080 Welcome to the O-Lang Router!

POST method test (oytun as parameter value for name [ :name => {{.name}} ]):

~> curl -X POST localhost:8080/oytun Hello, oytun! Welcome to Olang

As you can see in the example, we wrote a web micro service using port 8080 via get and post methods.

Render Example

If we are going to do a test to render HTML, we can write the HTML module first so that we can link it to the http socket and render it.

httprenderexample.ol (HTTP socket with HTML module => main):

show("Listening 0.0.0.0:8080... Ctrl+C to exit."); http("/", "8080", "Hello, Olang World from Web!") );

I started a sample http socket by including the jquery script and other plugins in my html parameters. As a result, when I call the socket with curl;

~> curl localhost:8080 .....content....

I gave an HTML output as a conversion. This will be similarly rendered on the Web.