Rye Language

What’s Rye? A programming language focused on fluid expressions, still in development.

What’s it for? Interactive use, backend, servers, information exploration and processing.

About Rye

Rye is a high level, homoiconic dynamic programming language based on ideas from Rebol, flavored by Factor, Linux shell and Go. It's still in development, but we are focused on making it useful as soon as possible.

It's written in Go and could also be seen as Go's scripting companion as Go's libraries are very easy to integrate, and Rye can be embedded into Go programs as a scripting or a config language.

I believe that as a language becomes higher level it starts bridging the gap towards user interfaces. Rye has great emphasis on interactive use (Rye console) where we intend to also explore that.

Short Rye examples

Change Hello World to Hello Mars and print it.
"Hello World" .replace "World" "Mars" |print
; prints "Hello Mars"
Find the Sum of unique numbers in a string.
"12 8 12 16 8 6" .load .unique .sum
; returns 42
Use switch function to get the sound of the animal.
switch 'cow { dog { "woof" } cow { "mooo" } cat { "meow" } }
; returns mooo
Extract combination of one number and one letter from string.
regexp "([0-9][a-z])" |submatch? "-7--x3--0k-r--"
; returns 0k
Print out names starting with A.
{ "Anne" "Joan" "Adam" } |filter { .first = "A" }
|for { .print } 

IO, Spreadsheet, HTTP client

Read a file, print the number of lines and the last 5 lines.
read\lines %data.txt |with
{ .length? .print , .tail 5 |print }
Load a CSV, get average score of all players of level 7.
load\csv %ryebots.csv |where-equal 'level 7
|column? 'score |avg
Load a webpage, save it to a file, print out all the links.
get https://ryelang.org |write* %page.html
|reader |parse-html { <a> [ .attr? 'href |print ] }

HTTP, SMTP server

Serve folder over HTTP
new-server ":8082"
|handle "/" new-static-handler %public_html
|serve
Web server that responds with current time.
new-server ":8081"
|handle "/time" fn { w r } { .write to-string now }
|serve
Start smtp server and print notification on new email.
handler: fn { mail from to origin } {
printv from "new mail from {}" }
new-smtpd ":25" |serve ?handler "demo"
      

Dialects

Validation dialect
dict { name: "anakin" } |validate { 
   name: required calc { .capitalize } 
   score: optional 0 integer }
; returns { name: "Anakin" score: 0 }	  
Math dialect.
; Rye like Rebol or Lisp has no operator precedence.
; But it has Math dialect which has it and more.
math { 2 + 2 * sqrt ( 12 + ( 24 / 3 ) ) }
; returns 42
SQL dialect.
rye .args .first :id
open sqlite://data.db
|query { select * from operator where id = ?id }

Delve deeper

To learn how Rye works and can be used check (work in progress) Meet Rye. Our unit tests also produce a function reference with examples you can check.

Where

Rye can currently run on your Linux or Mac OS desktop. Rye also runs in your web-browser (Wasm) and Docker. Rye could be compiled for mobile (Android and OSx) and Windows.

Focus is on command-line / backend use, but we are experimenting with a multiplatform GUI Fyne in Rye-front project.

You can try a (work in progress) Rye console right now by clicking a button on top-right of this page.

Downloads

x86 64arm 64arm v6
Linuxv0.0.16 v0.0.16 v0.0.16
Mac OSv0.0.16 v0.0.16-

Wasm: v0.0.16

Docker: docker pull ghcr.io/refaktor/rye:latest

Development

Rye's Github repository is where everything happens. Please visit it, read it, star it, post issues, contribute ...

Since Rye uses Go, building it from source is very simple. Instructions are on the README.

Rye integration with frontent (GUI) toolkit Fyne happens in Rye-front repository.

Related web

Github Blog Reddit Old blog Asciinema Youtube

Rye concepts

  • Expressions not statements
    Everything in Rye is an expression, returns a value. In general, Rye always returns vs. changes values in-place.
  • Code is data / data is code
    Rye is fully runtime homoiconic. Rye code consists of Rye data. Rye data can be interpreted.
  • First class everything
    All language constructs in Rye, from literals to functions and contexts, are treated as values.
  • Everything a function
    Every active component in Rye is a function (if, loop, for, fn, return, extends, context). No keywords, no special forms.
  • Separation of state and functionality
    Rye is not an object-oriented language, it's also not purely functional, call it practically functional.
  • Code flow = information flow
    Rye code tries to reduce the use of state and emphasize the flow of information, fewer variables - more flows!
  • Strict about effects
    Rye has no syntax to directly change a value in its parent or child context (scope), all communication between contexts requires function calls. Furthermore, by convention, a limited number of functions, that change state in-place, end with an exclamation mark (append!, set!, change!, ...).
  • No nil, null, none
    Rye functions return a result or failure. There is no third state, no so called 'billion dollar mistake'.
  • Failure can be handled, code error can only be fixed
    Rye distinguishes between a failure of a function to produce a result, which can be handled, or a code Error, which means an unknown state, so the program should stop and Error should be fixed in code. An unhandled failure is also a code Error.
  • Explicit value validation
    Rye has a validation dialect that makes validation declarative, visible and explicit instead of sprinkled around your business logic. Same with conversion.
  • Spreadsheet datatype
    You can't achieve a higher level language with the same old value types. Many human data is tabular and a list of dictionaries doesn't cut it. Rye's Spreadsheet datatype and declarative approach can absurdly cut the code amount.
  • Words-in-context oriented
    Rye tries to avoid too computer-specific or computational paradigms (procedural, OO, functional) terminology. Its vocabulary tries to focus more on information manipulation itself and the end-users, people. Programs are organized around contexts and words (which are bound to functions or other values), not classes, objects, modules, ...

Thank you

Thank you for visiting this site and reading to the end. If you see any potential here, don't be a stranger, join, star or subscribe us on github, reddit, youtube, ... or just send me an email!

Especially github is usually updated every few days! If you want to contribute in any way, even better, there are always open tasks to complete, from docs, tests, to Go coding.