Kage
Pronunciation – kāge.
Kage is a programming language I would like to write. This is what I want in it.
Goals:
- practical
- fast
- discoverable
- consistent
Describing:
“easy like Python, fast like Go/D”
“batteries included”
“amazing for scripting”
“native on any *nix system”
“Interfacing with C is amazingly easy and straightforward”
“It’s amazing for scripting, network programming, data maniputation.. you name it”
“You will be amazed at what all it can do!”
Fast compilation to a standalone binary
Immutability
Code autoformatting tools
Language server for easy IDE integration
“shebang” integration
Good REPL
Should be able to import “system libraries” (in C, D, C++) with a simple
import
statement
UX considerations
- easy to read
- easy to type (not too many “shift” keys)
- leverage familiarity
Goals
- Reduce the need for frameworks
- Reduce the need for “meta” tools – See Cheng Lou’s “Taming the meta langauge” talks.
- Make it easy to create, share and use libraries
Killer app
While general purpose, Kage will be designed for:
- server side programming
- big data
- data crunching
- scripting
- automation
- multicore programming
- GPU programming
- “End to end programming”.
- Replace Java and JVM.
Everywhere Python is used today, only better.
Make is so, so easy to:
- get started
- deploy
- write, use and share libraries –
import 'https://kagelang.org/lib/web/requests.kage?version=1.0.2'
- the above is similar to how javascript libraries are used on Javascript
- debug
Keeping in mind:
- Jai - game programming
- Java - Toasters
- Go - servers
- Python - learning programming
- Perl - shell scripting
Borrowing from …
D
- Range based programming
foreach
- Fast compilation
- UFCS (uniform function call syntax)
- equivalent of
defer
in D?
Ceylon
- Documentation “attributes”
- Condition lists
- Union types
- Type
alias
Python
- Aesthetics
"""
multi-line stringsyield
Go
- Tooling
- Autoformatting
- Runes / Unicode
- CSP / Channels
- defer
Erlang
- pattern matching?
Javascript
- importing libraries using a URL -
https://www.kagelang.org/lib/web/requests.kage?version=1.0.3
OCaml
- modules
Scala
- ?
Swift
- C FFI
- DSL?
Rust
Nim
- UFCS
Elm
- friendly compiler messages
- semantic versioning
Chapel
Chapel programming language.
config var foo
The four main declaration keywords that have been introduced so far —
var
,const
,param
, andtype
— 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
- borrow how Chapel does parallel programming – data-parallel
forall-loop
- task parallel features to express an explicitly concurrent program that utilizes multiple cores on a single locale (compute node).
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
- i32, i64 etc. –
let x:i64 = 1234
- IP address –
let home = ipv4@192.168.1.1
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
- See OCaml Modules
- See also: Java Jigsaw
- See also: Chapel
// 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
- Always flat structure
- use
module
if you need namespace
Convention over configuration
kage run
will execute amain.kage
filekage build
will try to build amain.kage
file into$directoryname
executablekage clean
will remove$directoryname
executable
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:
- clarify how
import
andinclude
differ - can they coexist together?
Reserved Keywords
if (is Polar that) { ... }
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..
- Level 1 – Use case: scripting, Style: procedural.
- Level 2 – Use case: application, Style: procedural + OOPs + Functional
- Level 3 – Use case: large applications, etc.,
You can generate compilers/interpreters (say kage1
,
kage2
) at build time.
Language references
- Plasma Langauge specification
- D Language specification
- Ceylon Language specification
About implementing langauges
- Five Questions about Language Design by Paul Graham
You Need an Application to Drive the Design of a Language.
IDEAS INBOX
- https://c9x.me/compile/ – use for compiler backend?
- http://angersock.com/blog/2018/01/07/language-features-for-non-programmers/