🔗
Back

Kage

Pronunciation – kāge.

Kage is a programming language I would like to write. This is what I want in it.

Goals:

Describing:

UX considerations

Goals

Killer app

While general purpose, Kage will be designed for:

Everywhere Python is used today, only better.

Make is so, so easy to:

Keeping in mind:

Borrowing from …

D

Ceylon

Python

Go

Erlang

Javascript

OCaml

Scala

Swift

Rust

Nim

Elm

Chapel

Chapel programming language.

The four main declaration keywords that have been introduced so far — var, const, param, and type — support a mode in which their initializing expressions in the source code can be overridden on the command-line. This is achieved by prefixing the declaration with the keyword config

While the idea of using -s in -saBooleanFlag to set the value appears wierd at first, it is quite common. See Java – -DgeneratePom=false -Dpackaging=rpm -DrepositoryId

Other PL ideas

Syntax

Hello world

Easy syntax. Influences - Python, D, Go, Swift, nim, Ceylon, F#

print("Hello, World!")

Variables

let a = 99 # a is immutable
var b = 88 # b is mutable

Data types

Rich Data types

Control Flow

If block

if a > 80 and b < 80 {

}

Loops

foreach(x; a..b) {
    print(x)
}
// with index
foreach(x, i; a..b) {
    print(x, i)
}

Handling Null

No Nulls

Functions

Function signature

//swift-style
func ==(lhs: Expression, rhs: Expression) -> Expression {}

Named arguments

// trying F#/OCamlish syntax here...
let foo bar:String="hello" msg:String="world" => foo + " " + msg
let <fnname> [<var1:type>=<default> ...=> <fnbody>

Data, Data everywhere!

Support many of the common dataformats natively

import json
let j = json.readFile("hello.json").byLines()
for line in j {
    j.parse()
}

Modules

// requests.kage

let version =  1.1.2
let md5sum = "asldjfasjdflajsdlfjklsad"

fn get(page: String) : String {

}

The above should be importable as requests module. Avoid automatic capitalisation like OCaml.

Different ways to use modules:

include – include the contents of the module

// myclient.kage
include requests

This would include the entire contents of requests.kage in myclient.kage. TODO: rework the package definition elsewhere in the document.

Shipping self-contained source code including dependencies

Source File:

// rdemo.kage
include requests

print(get('http://www.btbytes.com'))

Packaging:

$ kage package rdemo.kage
// writes rdemo with +x bits set

module requests {
    // requests module stuff
}

print(get('http://www.btbytes.com'))

Code organization

Convention over configuration

Testing

In built unit testing framework (like D)

//main.kage

fn foo(a: String) : String = {
    "Hello " +  a
}

unittest {
    test numOne = {
        assert(foo("World) == "Hello World")
    }
}

$ kage test
. 1 test passed
OK

Data structures

Struct (on the stack)

struct Soup {
    Base base;
    Ingrediant[] ingredients;
}

Class (on the heap)

class Foo {

}

let f = new Foo();

Traits

trait Loggable {
    let logger = _
}

struct Instrument  extends Loggable {
    Pressure pressure;
    Temperature temperature;
}

Garbage Collection

Implement Automatic Reference Counting ala Swift.

Automatic Resource management

Close sockets, files etc., using an ARM/Context Manager

with (f = open('foo.txt')) {
    f.readline()
}

Prelude

Should come with a very useful Prelude.

Inbuilt documentation format

Borrow from Ceylon.

Support Markdown

"The classic Hello World program"
by ("Trompon the Elephant")
see (`function goodbye`)
throws (`class IOException`)
fn hello() : Unit {
    print("Hello, World!");
}

Strings

String interpolation

let who = "World!"
let message = "Hello, ``who``" // ceylon style
let message = s"Hello, $who" // scala style

Programming considerations

Execution

#!/usr/bin/env kage
print("hello world")

Compiling and running

$ kage build rdemo.kage
// writes a standalone binary

$ kage run rdemo.kage
// executes rdemo.kage

Import libraries

Common import patterns


import foo
import bar.{baz, boop}
import alib._ // has heyo, wassup
import blib.goop
import nomnom as yum

foo.doSomething()
baz()
boop()
heyo()
wassup()
goop()
yum.chomp()

Relative path imports

import stdio
import '.libFoo.so' as foo // from current dir

foo.aFunction("process this!")

Packages and dependency management

Files having the same package requests will belong to the package requests.

In the absense of a module name, main module is assumed.

//package.kage
// much like Package.swift

implicit -- import package
let name = "requests"
let version = Version(1, 2, 0)
let dependencies = [
    Package(git: "https://github.com/foo/bar.git", version: Version(1, 0, 0))
    Package(url: "https://example.com/modx.kage, md5sum: "abcde123abd429737839")
]

Program code:

//main.kage
def main(String[] args) -> Int {
    print("Hello, world!")
}

TODO:

Reserved Keywords

From Ceylon:

As you’ve probably guessed, if (is … ) works just like if (exists … ), testing and narrowing the type of a value. In this case it tests the type of that and narrows to Polar if that is indeed an instance of Polar.

Scripting and shell programming usecase

Piping

Use F#s|> operator


Levels

Langauge Levels.

Implement subset of features in an increasing order in each level..

You can generate compilers/interpreters (say kage1, kage2 ) at build time.

Language references

About implementing langauges

You Need an Application to Drive the Design of a Language.

IDEAS INBOX




Permalink: /n/f6dexodjsr
Last modified: Sun Sep 16 1:00am 2018
860 views
Related: rwtxt about
Write markdown, reload page when you are done!