#+title: Parry language design - tags :: [[file:20210307152738-programming_languages.org][programming languages]] [[file:20210411214221-programming_language_implementation.org][programming language implementation]] [[file:20210429105507-my_programming_languages.org][my programming languages]] [[file:20210429133404-language_design.org][language design]] Parry is a programming language I'd like to implement. Parry is inspired by [[https://docs.racket-lang.org/riposte/][Riposte]]. * 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. #+begin_example 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 #+end_example * Types Parry is a loosely typed language and supports many basic types. ** Primitives *** Booleans #+begin_example bool = true || false #+end_example *** Numbers Parry supports integers and floating point numbers. #+begin_example v = 1 + 3.22 - -1 * -3.45 #+end_example *** Strings #+begin_example str = "hello world" strSingle = 'single quotes are okay too' #+end_example String interpolation can occur in any string. #+begin_example strInterp = "${str} foo bar" #+end_example ** Lists Lists can have mixed types and do not require commas. #+begin_example [1 2 "foo" true] #+end_example ** Sets Sets are a simplified kind of JSON. They are also immutable. #+begin_example obj = { foo: 123, bar: 'bar', baz: false, quux: [1 2 3 4], quuz: { foo: 'foo' }, } #+end_example Set properties are accessed with dots. #+begin_example foo = obj.foo bar = obj?.bar # returns `null` if not present #+end_example To derive a new set, you can use the spread operator. #+begin_example obj2 = { ...obj1, foo: 456 # overrides `foo` } #+end_example ** Functions All functions are first class, lambdas, and anonymous. #+begin_example myFunc = (bar, baz) -> bar + baz; #+end_example * 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 | * Control Flow ** let ... in #+begin_example let a = 1 b = 2 c = 3 in a + b + c #+end_example ** Conditionals Conditionals are expressions. #+begin_example a = if isEven(4) then true else false #+end_example ** match #+begin_example a = match b | "foo" -> 1 | "bar" -> 2 | else -> 3 #+end_example ** Loops * File IO Both reading and writing return =null=. ** Reading #+begin_example txt << "~/file.txt" #+end_example ** Writing #+begin_example "foo bar" >> "~/out.txt" #+end_example * 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 #+begin_example get "api.example.com/foo" #+end_example The request made will simply be a =GET= to that URL, with no further information. However, you could also specify a set, as such: #+begin_example get { url: "api.example.com/foo", headers: { Accept: "*/*" } } #+end_example By passing a set you can specify header and body information. ** =get= ** =post= * Standard Library ** Map #+begin_example map([1 2 3], (v) -> "${v}") # => ["1" "2" "3"] #+end_example ** Reduce #+begin_example reduce([1 2 3], (sum, v) -> sum + v, 0) # => 6 #+end_example ** Assert