Skip to content

P-bibs/skiff

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Skiff

A gradually-typed, functional scripting language with a friendly syntax and interpreter written in Rust!

Running

You can run Skiff in the Skiff web editor (powered by wasm!).

If you prefer to use your own text editor, you can install Skiff from crates.io and run it from the command line

cargo install skiff
skiff <filename> # make sure installed crate binaries are in your PATH

About

Skiff started as a personal project for me to learn more about the design and implementation of programming languages. It was a mash-up of ideas and syntaxes from existing languages. As it evolved, however, it became a platform for me to learn about different algorithms like HM type inference and exhaustiveness checking of pattern match expressions.

Next on the road map is an exploration of gradual typing by adding a typed keyword to distinguish fully type functions from partially typed functions. By default, Skiff will have very few static guarantees. However, you can opt into more checks within a given function by fully annotating the arguments and return type or using the typed keyword to tell Skiff to infer a function type. The goal is to have a language that is as easy to use as a dynamically-typed language while offering some of the guarantees and in-code documentation of statically-typed languages. One of the guiding principles to maintain this goal is that all type annotations should be optional (that is, stripping all type from a Skiff program should still leave you with a runnable Skiff program).

What does it look like?

Function definition (types are optional):

def fact(n: Number) -> Number:
    match n:
        | 1 => 1
        | n =>
            let next = fact(n - 1)
            next * n
    end
end

Conditionals:

let cond: Boolean = true
if cond:
    1
elif false:
    2
else:
    3
end

Algebraic datatypes (types are optional):

data Option:
    | some(v: Number)
    | empty()
end

Pattern matching:

match some(1):
    | some(n) => n
    | empty() => 0
end

Anonymous functions:

let increment: Number -> Number = lambda(n): n + 1 end
let add: (Number, Number) -> Number = lambda(a,b): a + b end

Language Reference

Full docs are a work in progress. To get an idea of what the features and syntax look like, you can look at the language tour test file.

Developing

Clone the repo to work on Skiff. You can run a local development version using

cargo run -- <filename>

For example:

cargo run -- tests/files/success/plus_and_times_precedence.boat

Features

Language Features:

Tree Walk Interpreter Bytecode Interpreter
Arithmetic
Equality Operators
Conditionals
Functions
Recursion
Lambdas
Let binding
Improved Error Reporting
Type Annotations
Type Inference
Algebraic Datatypes
Pattern Matching
Exhaustiveness Checking
Call Stack Traces
Parameterized Types
typed keyword
Strings
File Operations
Testing Constructs

Miscellaneous:

  • REPL
  • Language Reference
  • Web Editor (WASM)
  • Continuous Integration
  • Publish crate

Inspiration

Most Heavily

  • Elm
  • Pyret
  • Python

Somewhat

  • Rust
  • Javascript
  • Typescript
  • Haskell
  • OCaml
  • Lua

About

A gradually-typed, functional scripting language with a friendly syntax and interpreter written in Rust!

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages