Rye takes concepts from REBOL (words, blocks, code is data), adds few unix shell-isms (pipes), some concatenative (Factor lang) ideas, some FP ideas and some of my own stuff.
It's initial "practical" focus is on shell / backend scripts.
It's an work-in-progress experimental *toy* language.
Interpreter in Go. There is also Javascript implementation which will be synced with golang version at 0.01.
I'm making ryk, an awk like tool with Rye language and JSON processing support.
Javascript version is used as an embeded langauage at some of my webapps.
Will be open source.
14.apr.2019 Added experimental support for currying.
02.jun.2019 Added first version of generic functions. Lit-words, genwords ...
27.sep.2019 Started adding a tree based co-language Spruce.
Like Rebol, Rye is basically a data language (think JSON, but more) but this data can also be executed by any number of dialects. Default dialect being the DO dialect or what one would call basic Rye languge.
Rebol-like code works in Rye too
debug: 1 print-if: fn [ cond x ] [ if cond [ print x ] ] print-if positive? debug "debug mode"
both [] and {} denote blocks. {} is default.
print-if: fn { cond x } { if cond [ print x ] }
functions, words and pipewords
add 2 3 // is the same as 2 |add 3 // or in this case 2 .add 3
opwords vs. pipewords
subtract 10 add 2 3 // returns 5 (subtract 10 (add 2 3)) 10 .subtract 2 .add 3 // returns 5 10 .subtract 2 |add 3 // returns 11
hypotethical pipewords example
get-links-to: fn [ url to ] { read url |html->xml |xml-reduce 'o {} [ on <a> 'x { join o x .attr 'href } ] |filter 'x [ found? find x to ] } get-links-to http://www.cebelca.biz "www.ajpes.si"
optional expression guards
a: subtract 10 add 2 3 add a 50 // returns 55 a: subtract 10 add 2 3 , add a 50 // returns 55 a: subtract 10 add 2 , 3 add a 50 // error
function currying
add5: add 5 _ add5 50 // returns 55 second: nth _ 2 , { 11 22 33 } .second // returns 22
clojure inspired recur(-if) - just experimenting
factorial: fn { n a } { positive? n |recur-if-2 n - 1 n * a , a } loop 100000 { factorial 12 1 }
first clumsy version of generic functions
// function "generic" takes a word determining kind, // word to bind to // and a user or a builtin function // function "fn" creates and returns a function generic 'integer 'Add fn { a b } { a + b } // "join" is a builtin function, // get-word "?join" returns the builtin without evaluating it generic 'string 'Add ?join Add 100 11 // returns 111 Add "woof" "woof" // returns "woofwoof" // later it might look more like this gfn 'Add { 'integer a b } { a + b }
The plan is that generic functions will be default and all builtins will be generic functions, so this will change. Ordinary functions will only be used for smaller local utility functions.
.There are many more differences, some are still being thought about.
Rye for example currently doesn't plan on having refinements.
tuples/objects with it's validation dialect, kinds and generic functions dispatching on them.
Not sure if it can be called a programming language. It's main building block is a tree of Rye values.
I think this gives us new oportunities for creating interesting programming, exploration and user experiences.
in ideas stage
Could be interesting way to "script", manipulate code, maybe more accessible to non-programmers and non keyboard devices.
Will be open source.
build spruce { give me five { add 3 2 } your name { capitalize "spruce" } } give me five . returns 5 give me your name . returns Spruce
. this is a builder dialect. It builds / adds to the spruce tree. build spruce { when email is received do {todo:block} [ on-event 'email-received { 'it 'email } todo ] if {cond:boolean} do {todo:block} [ core/if cond todo ] its {key:string} [ core/at It key ] {a:boolean} and {b:boolean} [ core/and a b ] {val:string} includes text {text:string} is from domain {domain:string} } . below is the user dialect when email is received do { if its 'title includes text 'offer do { flag it 'commercial forward it } If its 'sender is from domain 'nlb.si and it's 'title includes text "izpisek" do { add its 'title to log archive it under "nlb izpiski" } }
in development
I love awk. It's used a lot in interactive, ad-hoc manner so I see this as a good practical case with which in mind Rye can be developed in this early stage.
A concrete programming language, but with possible specific dialects. I also plan to add a functionality for stream-processing CSV and JSON files.
Will be open source.
basic example
$ cat > peers.txt 1 SI janko 2 US jim 3 SI luka $ cat peers.txt | ryk '/SI/ { _1 + 100 , _3 .capitalize }' 101 Janko 103 Luka