complete all introductory documentation, except for the Easy Patterns

section
Also, removed some stray debug lines and added a printed newline
inbetween prompt and output
This commit is contained in:
Ava Hahn 2023-03-16 15:14:24 -07:00
parent 67af8bbd47
commit 20821057f2
Signed by untrusted user who does not match committer: affine
GPG key ID: 3A4645B8CF806069
3 changed files with 126 additions and 13 deletions

View file

@ -165,7 +165,38 @@ CURRENT VALUE AND/OR BODY:
<builtin>
#+END_SRC
*** TODO Quote and Eval
*** Quote and Eval
As stated previously: Lisp, and consequently Relish, is homoiconic. This means that code can be passed around (and modified) as data.
This allows us to write self programming programs, or construct entire procedures on the fly. The primary means to do so are with *quote* and *eval*.
The *quote* function allows data (code) to be passed around without evaluating it. It is used to pass unevaluated code around as data that can then be evaluated later.
To be specific, typing ~(a)~ usually results in a symbol lookup for ~a~, and then possibly even a function call. However, if we *quote* ~a~, we can pass around the symbol itself:
#+BEGIN_SRC lisp
(quote a) ;; returns the symbol a
(quote (add 1 2)) ;; returns the following tree: (add 1 2)
#+END_SRC
We can use this to build structures that evaluate into new data:
#+BEGIN_SRC lisp
(let ((mylist (quote (add))) ;; store a list starting with the add function
(myiter 0)) ;; store an iterator starting at 0
(while (lt? myiter 4) ;; loop until the iterator >= 4
(inc myiter) ;; increment the iterator
(def mylist '' (cons mylist myiter)) ;; add to the list
(echo mylist)) ;; print the current state of the list
(echo (eval mylist))) ;; print the eval result
#+END_SRC
Notice the final body in the let form: ~(echo (eval mylist))~
The above procedure outputs the following:
#+BEGIN_EXAMPLE
(add 1)
(add 1 2)
(add 1 2 3)
(add 1 2 3 4)
10
#+END_EXAMPLE
*** Lambda
Another form of homoiconicity is the *anonymous function*.
This is a nameless function being passed around as data.
@ -194,10 +225,96 @@ Here is the lambda bound to a variable inside a let statement:
(adder 1 2)) ;; local var (lambda) called here
#+END_SRC
*** TODO Defining variables and functions
**** TODO Anatomy
**** TODO Naming conventions
**** TODO Undefining variables and functions
*** Defining variables and functions
In Relish, both variables and functions are stored in a table of symbols.
All Symbols defined with ~def~ are *GLOBAL*. The only cases when symbols are local is when they are defined as part of *let* forms or as arguments to functions.
In order to define a symbol, the following arguments are required:
- A name
- A docstring (absolutely required)
- A list of arguments (only needed to define a function)
- A value
Regarding the *value*: A function may be defined with several trees of code to execute.
In this case, the value derived from the final form in the function will be returned.
#+BEGIN_SRC lisp
(def my-iter 'an iterator to use in my while loop' 0) ;; a variable
(def plus-one 'adds 1 to a number' (x) (add 1 x)) ;; a function
(def multi-func 'example of multi form function'
(x y) ;; args
(inc my-iter) ;; an intermediate calculation
(add x y my-iter)) ;; the final form of the function. X+Y+MYITER is returned
#+END_SRC
Make sure to read the *Configuration* section for information on how symbols are linked to environment variables.
**** Naming conventions
- Symbol names are case sensitive
- Symbols may contain alphanumeric characters
- Symbols may contain one or more of the following: - _ ?
- The idiomatic way to name symbols is ~all-single-case-and-hyphenated~
**** Undefining variables and functions
Removing a symbol consists of a call to ~def~ with no additional arguments:
#+BEGIN_SRC lisp
(def my-iter 'an iterator' 0)
(inc my-iter) ;; my-iter = 1
(def my-iter) ;; removes my-iter
(inc my-iter) ;; UNDEFINED SYMBOL ERROR
#+END_SRC
** Builtin functions
As opposed to listing every builtin function here, it is suggested to the user to do one of two things:
- Call ~env~ from a fresh shell: ~(env)~
This will output all variables and functions defined
- Read the std library declaration code:
file:src/stl.rs
** Documentation
*** Tests
Most of the tests evaluate small scripts (single forms) and check their output.
Perusing them may yield answers on all the cases a given builtin can handle.
file:tests/
*** Help function
Relish is self documenting. The *help* function can be used to inspect any variable or function.
It will show the name, current value, docstring, arguments, and definition of any builtin or user defined function or variable.
#+BEGIN_EXAMPLE
> (help my-adder)
NAME: my-adder
ARGS: 2 args of any type
DOCUMENTATION:
adds two numbers
CURRENT VALUE AND/OR BODY:
args: x y
form: ((add x y))
#+END_EXAMPLE
#+BEGIN_EXAMPLE
> (help CFG_RELISH_ENV) <
NAME: CFG_RELISH_ENV
ARGS: (its a variable)
DOCUMENTATION:
my env settings
CURRENT VALUE AND/OR BODY:
true
#+END_EXAMPLE
Every single symbol in Relish can be inspected in this way, unless some third party developer purposefully left a docstring blank.
*** Snippets directory
The *snippets directory* may also yield some interesting examples.
Within it are several examples that the authors and maintainers wanted to keep around but didnt know where.
It is sort of like a lint roller.
It also contains considerably subpar implementations of Relish's internals that are kept around for historical reasons.
** Easy patterns
This section can serve as a sort of cookbook for a user who is new to leveraging LISP languages or unsure of where to start with ~relish~.
@ -225,6 +342,7 @@ The while-let pattern can be used for many purposes. Above it is used to iterate
*** TODO short-circuit guard
- circuit example
- while-not-circuit-do-more-work
*** TODO shell capabilities check
*** let destructuring
~let~ is very useful for destructuring complex return types. If you have a function that may return a whole list of values you can then call it from ~let~ to consume the result data.
In this example a let form is used to destructure a call to ~head~. ~head~ returns a list consisting of ~(first-element rest-of-list)~ (for more information see ~(help head)~).
@ -256,12 +374,7 @@ Alternatively this combination can be used to process flags in a script or appli
(process-flag myflag)
())
#+END_SRC
** TODO Builtin functions
*** TODO Env function
** TODO Documentation
*** TODO Tests
*** TODO Help function
*** TODO Snippets directory
** Configuration
By default Relish will read from ~/.relishrc for configuration, but the default shell will also accept a filename from the RELISH_CFG_FILE environment variable.
@ -363,6 +476,7 @@ This contains any executable target of this project. Notably the main shell file
Note: this section will not show the status of each item unless you are viewing it with a proper orgmode viewer.
Note: this section only tracks the state of incomplete TODO items. Having everything on here would be cluttered.
*** TODO set function
*** TODO list contains via circuit
*** TODO Input function
*** TODO Lex function