knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.path = "man/figures/README-", out.width = "100%" ) knitr::knit_engines$set( clojure = llr::knitr_language_engine() )
llr is a small, work in progress and just for fun clojure-like lisp on top of R's abstract syntax trees. Expressions are not interpreted, but are translated to R's AST and then interpreted by the R interpreter.
Most implementation details are sub-optimal, but the focus is on having fun and producing results instead writing perfect code. There are also many bugs and inconsistencies!
remotes::install_github("dirkschumacher/llr")
(-> r/datasets::mtcars (r/dplyr::filter (r/base::`>` hp 100)) (r/dplyr::summarise :count (r/dplyr::n) :mean_mpg (r/mean mpg)) (r/tibble::as_tibble))
Or run it from R
library(llr) interp <- llr_env$new() interp$eval("(+ 1 1)")
Also see some Advent Of Code solutions in llr.
It also has a (limited) REPL
interp <- llr_env$new() interp$repl()
; this is a list '(1 2 3 4 5 6) ; an unquoted list is a function call (+ 1 2 3 4 5 6)
[1 2 3 4]
{:a 1 :b 2}
```{clojure, eval = FALSE} x
```{clojure, eval = FALSE} namespaced.variable/x
```{clojure, eval = FALSE} :keyword
```{clojure, eval = FALSE} "character"
```{clojure, eval = FALSE} 10 ; integer
```{clojure, eval = FALSE} 10.42 ; double
```{clojure, eval = FALSE} (fn [a b] (+ a b))
(fn this ([] 0) ([a] a) ([a b] (+ a b)) ([a b & more] (reduce + (concat [a b] more))))
### def `def` defines a symbol in a namespace and assignes it a name. ```{clojure} (def x 1) (def plus (fn [a b] (+ a b))) (plus x x)
Symbols and values can hold meta-data. That meta-data needs to be a map at the moment.
(def ^{:const true} x ^{:meta "hello"} [ 1 2 3]) (meta x)
Meta-data on symbols is currently only available to the reader.
Macros are also supported. Macros are functions bound to a name with meta data {:macro true}
.
In a macro you can use syntax-quote <backtick>
together with the unquote ~
and unquote-splice ~@
operators.
(defmacro infix [operand1 operator operand2] `(~operator ~operand1 ~operand2)) (infix 1 + 1)
Similar to Clojure llr uses recur
to jump to a recursion point currently only defined by loop
.
(def is-even (fn [number] (loop [cnt number] (if (zero? cnt) true (if (< cnt 0) false (recur (- cnt 2)))))))
(is-even 5001)
(is-even 5000)
Every top level definition is part of a namespace
(ns product.lib) (defn compute [a b] (+ a b)) (ns user) (product.lib/compute 10 32)
The reader switches to a different set of interpretations of the next symbol when reading the character #
.
#_
ignores the next form#_ (r/stop "error") "Yay"
All symbols starting with the namespace r/
are treated slightly differently. You can use that to refer to external R functions and symbols. In addition keywords are interpreted as named arguments.
(r/set.seed 1) (def rand-numbers (r/stats::rnorm :n 10)) (r/mean rand-numbers)
r/
namespace.Please note that the llr project is released with a Contributor Code of Conduct. By contributing to this project, you agree to abide by its terms.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.