📚 node [[20210429094903 parry_language_design]]

Parry is a programming language I'd like to implement. Parry is inspired by Riposte<button class="pull-url" value="https://docs.racket-lang.org/riposte/][Riposte]]">pull</button>.

Design

Parry programs are centered around making REST requests. The goal of Parry is to make REST requests scriptable. Parry should make it trivial to, say, do a GET request from one resource and then use that information in subsequent requests.

url_root = "api.example.com"

resource = get "${url_root}/foo"
another_resource = get "${url_root}/bar?id=${resource.id}"

let
    url = "${url_root}/baz"
    headers = {
        Content-Type: "application/json",
    }
    body = {
        parent_id: another_resource.id
    }
in
    post url headers body

Types

Parry is a loosely typed language and supports many basic types.

Primitives

Booleans

bool = true || false

Numbers

Parry supports integers and floating point numbers.

v = 1 + 3.22 - -1 * -3.45

Strings

str = "hello world"
strSingle = 'single quotes are okay too'

String interpolation can occur in any string.

strInterp = "${str} foo bar"

Lists

Lists can have mixed types and do not require commas.

[1 2 "foo" true]

Sets

Sets are a simplified kind of JSON. They are also immutable.

obj = {
    foo: 123,
    bar: 'bar',
    baz: false,
    quux: [1 2 3 4],
    quuz: {
        foo: 'foo'
    },
}

Set properties are accessed with dots.

foo = obj.foo
bar = obj?.bar # returns `null` if not present

To derive a new set, you can use the spread operator.

obj2 = {
    ...obj1,
    foo: 456 # overrides `foo`
}

Functions

All functions are first class, lambdas, and anonymous.

myFunc = (bar, baz) -> bar + baz;

Operators

Operator Description
+ Addition
- Subtraction
* Multiplication
=/= Division
< Greater than
<= Greater than or equal
> Less than
>= Less than or equal
. Set access
?. Optional set access
= Assignment
>> Write to file
<< Read file to value

let ... in

let
    a = 1
    b = 2
    c = 3
in
    a + b + c

Conditionals

Conditionals are expressions.

a = if isEven(4) then true else false

match

a = match b
    | "foo" -> 1
    | "bar" -> 2
    | else -> 3

Loops

File IO

Both reading and writing return null.

Reading

txt << "~/file.txt"

Writing

"foo bar" >> "~/out.txt"

REST requests

Making REST requests are at the center of Parry.

All REST requests are functions that either take a single string or a set. If only a string is specified, say

get "api.example.com/foo"

The request made will simply be a GET to that URL, with no further information.

However, you could also specify a set, as such:

get {
    url: "api.example.com/foo",
    headers: {
        Accept: "*/*"
    }
}

By passing a set you can specify header and body information.

get

post

Standard Library

Map

map([1 2 3], (v) -> "${v}") # => ["1" "2" "3"]

Reduce

reduce([1 2 3], (sum, v) -> sum + v, 0) # => 6

Assert

📖 stoas
⥱ context