Skip to content
EricGebhart edited this page Sep 27, 2021 · 8 revisions

Welcome to the Simple_Process_REPL wiki!

The Simple Process Repl is a glue tool to create highly configurable, application process' that are are self documenting, easy to create and maintain. All while tapping into python modules available in the world.

It is a list processor with logging, error handling, integrated help, an extensible configuration in YAML. It has namespaces and can import any python module. Function parameters are automatically found and bound if not provided at call time. A final application might consist entirely of a YAML configuration file and a pip installable python module.

Code is data, data is code. SPR has no real syntax other YAML and white space. There is the use of /, .'s for paths which is technically syntax, even if very common. ~ will expand values in place, ` will protect them.

Data is specified in the code using YAML, just like in the configuration files.

There are a million snippets of python code out there that do just about anything. SPR allows you to easily, use, create, and re-use those things, Every problem you solve with SPR increases it's capabilities for your next solution. It allows you to grow a composable programming application, which can wear many hats, and appear in different ways.

What is it ?

It's like glue. Easy configuration, a multitude of ways to execute, and what it actually executes could be almost anything. It has built in logging and error handling, and the idea of a failed process is just part of a regular day. It's easily extensible in every way, Data definitions and use are easy to write.

Configuration is at the foundation, as such, it's super easy to create data structures and use them.

The configuration file has the ability of defining new SPR symbol/functions. It also has a section for Exec which defines a value for autoexec. This is what SPR will do, if not told to do something else.

The full conglomerated configuration, The config part of the data store, can be fully explored with ls /config and show /config it can also be saved to a file at any time with save-config Note that it is only necessary to keep the parts that you wish to change or add.

There is also the ability to load YAML and spr files which can extend SPR beyond the configuration. SPR can also import python modules, those modules can contain yaml and spr code that will extend spr as well.

The way I think of SPR as a manager of two trees. Essentially think of a folder hierarchy in your favorite computer system. There are two here. One was born from config files written in YAML. The other is simply a dictionary of names which hold other names, - The imported python modules, and any SPR definitions. These two trees are the SPR datastore located at / and the SPR Namespaces which are just here. Currently namespaces are only one level deep.

The Data Store

The datastore is created from a conglomeration of YAML defined by each of the pieces of SPR. Each extension defining it's default values, followed by the core SPR-defaults yaml, followed by SPR-config.YAML if found. A final configuration file can be specified on the cli.

Variables in the data store are accessed like Unix directories.

set mymsg /config/dialogs/finished

Additionally, any inline YAML found in SPR code will be merged into the data store. If a python module has a .yaml file, that will also be merged upon import.

The with stack

The with stack is a manual stack of paths which point at different paths in the datastore. When python functions are called, variables which match their argument bindings are resolved as used as needed. Use nice parameter names!!

The depth of the resolution can be controlled or turned off. It is also possible to run a one-shot function in another place using with.

   with /my/place/over/there do-some-fn

Namespaces

Namespaces are created with the SPR command namespaces and their core purpose is to import python libraries. There is a one to one correspondence between namespaces and python libraries. Although additional python libraries can be imported into any namespace with the import command.

Additionally, symbols defined in SPR code, using def, def-path or partial are also held in their namespaces.

Python Libraries

Any python library can be imported as you would think. Additionally, SPR will look for spr and yaml files to load. If that A python library being imported has a .yaml or .spr file, those files will be loaded.

User interface

Python dialog, and python input are included. Messages, yes/no, etc.

If you program particle.io boards, then there are a bunch things that make life easier than using the particle-cli directly on the shell commandline. Working with a particle board in the SPR REPL is a pleasure.

The REPL has persistent history, a dot file, that is configured to be in your home directory. It also has tab completion. Completion might be borked by namespaces at the moment. Basically, ls, show and help are your keys to the kingdom.

I like to tail -f spr.log in terminal.

Introspection

I really don't like having to dig for stuff, so SPR is really easy to look around in. ls, show, help and pyhelp, everything there is to see.

ls lists the namespaces which are any path not beginning with / and also will list the contents of datastore paths which do begin with /. Show only understands the datastore and the two helps only understand namespaces and the symbols in them.

Data store paths start with /. Paths which do not start with / are relative to current path on the With stack. Symbols - ie. do lists, partials, paths, and python functions also start without a /. But appear in different contexts.

Helpful commands that are informational.

  • ns Where am I in the namespaces.
  • ls list the contents of namespaces and datastore paths, (beginning with /).
  • with Display the current With path and listing. or push a new path on the with stack, or with a third argument, push a with, evaluate a command, then pop.
  • _ls-with list the with stack.
  • show Display a YAML tree of the current with node in the datastore or datastore path.
  • show-with Display a list of YAML trees which are the with stack.
  • help SPR help for namespaces and functions.
  • pyhelp Python help for namespaces and functions.
  • log/level debug -- This changes the SPR logging level to debug, it will show you lots of things.
  • log/level info -- to return to normal.

The SPR internals are also explorable if you look. Everything is in the datastore.

Help

Help is automatic, and built-in.

Everything in SPR requires documentation when defined. SPR help has context that python does not know. But Python help is awesome too, so both are availble in SPR via help and pyhelp commands.

SPR help, is for the SPR constructs, namespaces, do lists, partials, and paths, and to a degree, python functions. pyhelp, is for SPR namespaces, and any SPR symbols which ultimately resolve to python functions. For the most part it is an invocation of the normal python help system.

A real simple, example

Here is a sample of SPR code. This uses with in conjunction with the barcode extension to generate a barcode and place it in a file.

  • Point at some path in the application data store using with.
  • Set codetype and msg in that location using YAML syntax.
  • Call input-string to give an input dialog with the message.
  • Pop the result into value.
  • Call the bar code generation function bq/gen which wants value.
  • Pop the last result from the results stack and put it in code.
  • Save the code in an appropriately named file.

The trick is the with.

  • The defined YAML just merges into there.
  • The python functions pick up their parameters there.

We could specify them, but that is like hardcoding. We can specify some values in a place, point there, use them, fill them up, point somewhere else... pop back to where we were... we get a results stack everywhere we go.

Msg is for ui/input-string, Which we could just as easily coded as

ui/input-string "Input a value to encode" "My title"

But since we need other stuff, might as well just put it in the data. pop result moves the generated code from the results stack to value.

In this case it doesn't matter where value comes from, it's just what bq/gen wants, and bq/save wants both value and code.

Using SPR will certainly make you think harder about function and parameter names, their default values, their order, and your docstrings mastery.

with /mystuff/barcode

'
value : null
codetype : barcode
# codetype : QR-code
msg: Input a value to encode.
title: ui input string needs a title. 


ui/input-string

pop results value

bq/gen

pop results code

bq/save

pop-with
Clone this wiki locally