## dist_zef-jonathanstowe-URI-Template.md
# URI::Template

Implementation of <https://tools.ietf.org/html/rfc6570> for Raku

![Build Status](https://github.com/jonathanstowe/URI-Template/workflows/CI/badge.svg)

## Synopsis

```

use URI::Template;

my $template = URI::Template.new(template => 'http://foo.com{/foo,bar}');

say $template.process(foo => 'baz', bar => 'quux'); # http://foo.com/baz/quux

```

## Description

This provides an implementation of [RFC 6570](https://tools.ietf.org/html/rfc6570) which allows for the definition of a URI through variable expansion.

## Installation

Assuming you have a working Rakudo installation you should be able to install this with *zef* :

```
# From the source directory

zef install .

# Remote installation

zef install URI::Template

```

## Support

Suggestions/patches are welcomed via github at <https://github.com/jonathanstowe/URI-Template>

The test data covers all of the examples given in the RFC and a few others,
if you think the behaviour is incorrect please state the section of the RFC
and provide a failing example with the required variables, template and the
expected output.

## Licence

Please see the LICENCE file in the distribution

© Jonathan Stowe 2015, 2016, 2017, 2019, 2020

The testing uses the test data from <https://github.com/uri-templates/uritemplate-test>
please see the README.md in the t/data/uritemplate-test for the license for that project.


## dist_zef-finanalyst-Collection-Plugin-Development.md
# Development of Collection Plugins

## Table of Contents

[Introduction](#introduction)
[Test new plugins](#test-new-plugins)
[Collection plugin specification](#collection-plugin-specification)
[Collection plugin tests](#collection-plugin-tests)
[Collection-Plugin-Development utilities](#collection-plugin-development-utilities)
[add-collection-plugin](#add-collection-plugin)
[modify-collection-plugin](#modify-collection-plugin)
[test-all-collection-plugins](#test-all-collection-plugins)
[sub prepare-plugins( :$from = '../raku-collection-plugins', :$to = 'lib', :$format = 'html' )](#sub-prepare-plugins-from--raku-collection-plugins-to--lib-format--html-)
[Naming of released plugin](#naming-of-released-plugin)
[Collection plugin management system](#collection-plugin-management-system)
[System implementation](#system-implementation)
[Specification of manifest.rakuon file](#specification-of-manifestrakuon-file)
[Currently](#currently)

---

# Introduction

The `Collection` module makes extensive use of plugins. They need developing and maintaining.

The intention is for this distribution (Collection-Plugin-Development) to be associated with the repository for the files to develop plugins, and the current working copies of plugins.

Another repository (Collection-Plugins) is the source for published / released Collection plugins.

Typically for a developer, there will be

* the default directory `~/.local/share/Collection` for the installed modules, which is synchronised with Collection-Plugins.
* a working directory (default `working/` ) that is used for preparing plugins from new sources to be later uploaded to Collection-Plugins.

So, the work flow is

* new plugins are added, modified, developed, tested in `lib/plugins`
* modified plugins are prepared for release & pushed to Collection::Plugins using

```
prepare-plugins

```

This utility can be called with

* `-repo` pointing to where the released plugins are prepared for uploading. The default is `-repo=working/`
* `-origin` pointing to where the modified versions of plugins are kept. The default is `-origin=lib`

Alternatively

```
prepare-plugins :rebuild

```

This creates a `manifest.rakuon` file in the `-repo` default.

The program can be called with `-repo` as specified above.

The program

* creates a manifest.rakuon file in the root of `:repo`.
* creates a release version for new / changed plugins in `:repo`

It is left to the developer to git add/commit/push the files.

# Test new plugins

There is a directory `trial` with a Website. The plugins are symlinked to `lib/plugins/html`. To test the plugins, use `raku bin/run-collection-trial`. This does not attempt to refresh the plugins from Collection::Plugins.

# Collection plugin specification

All Collection plugins must conform to the following rules

* The plugin name must:

  * start with a letter
  * followed by at least one \w or -
  * not contain \_ or .
  * thus a name matches / <[\w] + [-] - [\_]>+ /
* The plugin directory contains

  * `config.raku`, which is a file that evaluates to a Raku hash.
  * README.rakudoc
  * t/01-basic.rakutest
* The `config.raku` file must contain the following keys

  * `name`. This is the released name of the plugin. It will be possible for a new plugin to have the same functionality as another, while extending or changing the output. For more detail, see [Collection plugin management system](Collection plugin management system.md). Typically, the name of the plugin will match the name of the sub-directory it is in.
  * `version`. This point to a Str in the format \d+.\d+.\d+ which matches the semantic version conventions.
  * `auth`. This points to a Str that is consistent with the Raku 'auth' conventions.
  * `license`. Points to a SPDX license type.
  * `authors`. This points to a sequence of names of people who are the authors of the plugin.
  * one or more of `render setup report compilation completion`

    * If render then

      * the render key may be a boolean
      * or the render key is a Str which must

        * be a filename in the directory
        * be a raku program that evaluated to a callable
        * the callable has a signature defined for render callables
      * the key `custom-raku`

        * must exist
        * must either be empty, viz. `custom-raku()`
        * or must have a Str value
        * if it has a Str value and the key `:information` does contain `custom-raku` then it is treated as if `custom-raku` is empty
        * if it has a Str value and the key `:information` does NOT contain `custom-raku` then the Str value should

          * point to a file name in the current directory
          * and the filename should contain a Raku program that evaluates to an Array.
      * the key `template-raku`

        * must exist
        * must either be empty, viz. `template-raku()`
        * or must have a Str value
        * if it has a Str value and the key `:information` does contain `template-raku` then it is treated as if `template-raku` is empty
        * if it has a Str value and the key `:information` does NOT contain `template-raku` then the Str value should

          * point to a file name in the current directory
          * and the filename should contain a Raku program that evaluates to a Hash.
    * If not render, then the value must point to a Raku program and evaluate to a callable.
  * *Other key names*. If other keys are present, they must point to filenames in the current directory.
  * `information`. This key does not need to exist.

    * If it exists, then it must contain the names of other keys.
    * If a key named in the `:information` list contains a Str, the filename will NOT exist in the plugin directory, but will be generated by the plugin itself, or is used as information by the plugin.
    * This config key is intended only for plugin testing purposes.

# Collection plugin tests

This distribution contains the module `Test::CollectionPlugins` with a single exported subroutine `plugin-ok`. This subroutine verifies that the plugin rules are kept for the plugin.

Additional plugin specific tests should be included.

# Collection-Plugin-Development utilities

Three utilities are provided to add a new plugin, modify an existing plugin's config file (eg. change the version number), run the tests of all plugins, and prepare plugins for release

Each utility assumes the plugin directory is at `lib/<format>/plugins`, where the default format is `html`. An example of another format would be `markdown`.

## add-collection-plugin

The utility adds the necessary files (config.raku, README, a test file, and callables) for a milestone.

Only a plugin name (eg. my-new-plugin) is required, and a new html format plugin with a `render` milestone is set up. Eg.

```
add-collection-plugin my-new-plugin

```

An error will be shown if an existing plugin with the same name is present in the `lib/html/plugins` directory.

The config file will have the defaults of the other mandatory keys. See `modify-collection-plugin-config` for how to get the defaults.

For different milestones set the option `-mile` to the milestone name and a callable stub is also created.

```
add-collection-plugin -mile=setup my-new-plugin

```

The `-mile` option can take a list of milestones and form stubs for each, eg.

```
add-collection-plugin -mile='setup render compilation' my-new-plugin

```

If a new format is being developed, then set `-format` to the chosen format name, eg `markdown`. A plugin will then be added to `lib/markdown/plugins`. Eg. (for the default -mile=render)

```
add-collection-plugin -format=markdown my-new-markdown-plugin

```

## modify-collection-plugin

This utility is intended to modify an existing plugin's config file, such as adding defaults if they are missing.

The utility cannot be used to modify a plugin's `name` key. It will add the directory name if a name key is missing.

To get a list of default attributes use

```
modify-collection-plugin-config -show-defaults

```

To modify a plugin specify the name with the option -plugin, eg.

```
modify-collection-plugin-config -plugin=an-existing-plugin -defaults

```

The plugin will be given defaults to all mandatory attributes, unless they already exist, in which case they are not changed.

To modify a specific attribute for a plugin use, for example,

```
modify-collection-plugin-config -plugin=an-existing-plugin -version=0.1.2

```

To bumps a plugin's *patch* version number, use

```
modify-collection-plugin-config -plugin=an-existing-plugin -bump

```

To modify the *Major* and *Minor* numbers use the `-version` option

To get help

```
modify-collection-plugin-config -help

```

## test-all-collection-plugins

All plugins must have a `t/` directory and one test file. This utility runs all the test files of all the plugins, returning only minimal information if the tests pass, but more information if a test fails.

## sub prepare-plugins( :$from = '../raku-collection-plugins', :$to = 'lib', :$format = 'html' )

The subroutine

* Moves plugins that have a new version/author to release directory.
* Verifies that there are no files in a working plugin directory that have newer content than in a release directory.
* Issues a suggestion to bump version if there is newer content.
* creates a file `manifest.rakuon` in the release directory (see later for specification of files).

# Naming of released plugin

The name of a working plugin must match `/^ <.alpha> <[\w] + [\-] - [\_]>+ $ /`.

If a plugin `my-plug` has a config file with `:version<1.2.3>, :auth<collection>` , then the released name will be **my-plug\_v1\_auth\_collection**

# Collection plugin management system

It is planned to have GUI and a command line manager.

The local computer may contain

* More than one collection, eg. a personal website and a Raku documentation collection
* Each Collection may have more than one Mode, eg., a HTML website, an epub producer.
* A collection/mode combination may rely on a previous API of a plugin, which may be broken by a later API.
* A new plugin may have been written as a drop-in replacement for an older version, and the new plugin may have a different name, or auth, or version.

So a plugin manager (whether command line or GUI) must be compliant with the following system:

* There is a *release* directory to contain all Collection plugins, probably a clone of the github repository.
* The semantic versioning scheme is mandated for Collection plugins. A version is `v<major>.<minor>,<patch>`. Changes at the `<patch>` level do not affect the plugin's functionality. Changes at the `<minor>` level introduce new functionality, but are backward compatible. Changes at the `<major>` level break backward compatibility.
* Each distributed plugin is contained in the release directory in a subdirectory named by the plugin name, the auth field, and the major version number (minor and patch numbers are not included because they should not by definition affect the API).
* Each Mode configuration only contains the name of the plugin (without the auth, or version names).
* The developer may define which name/version/auth of a released plugin is to be mapped to the plugin required in the Mode configuration. Thus

  * changes in API can be frozen to earlier versions of the plugin for some concrete Mode.
  * different plugin versions can be used for different collection/modes
  * a differently named plugin can be mapped to a plugin required by a specific collection/mode.
* Consequently, all released plugins are defined for

  * a Format (eg. html)
  * a Major version
  * an Auth name
* The mapping information from a released plugin to a Mode is contained in a file in the root of a Collection.
* When the plugins are updated

  * all the latest versions for each *relevant* Format/Name/Version-Major/Auth are downloaded.
  * a symlink is generated (or if the OS does not allow symlink, the whole directory is copied) from the released version to the directory where each mode expects its plugins to be located.
  * The meaning of *relevant* is determined by the PMS. It could be all plugins in the github repository, or only those needed by a specific Collection, or set of Collections.

## System implementation

Each Collection root directory (the directory containing the topmost `config.raku` file) will contain the file `plugins.rakuon`.

* The plugin management tool (PMT)

  * runs through the plugins-required
  * for each distinct plugin verifies whether

    * the plugin has an entry in `plugins.rakuon`, in which case

      * the PMT maps the released plugin name/auth/ver to the plugin-required name using the rules of `plugins.rakuon` as given below
    * the released version matches the plugin version (the full major.minor.patch version)
  * if a released version has larger minor/patch values, then the new directory is linked (copied) to the Mode's plugin name

The file `plugins.rakuon` contains a hash with the following keys:

* `METADATA`. Contains a hash with data for the `refresh` functionality.

  * `collection-plugin-root` This contains the name of a directory reachable from the Collection root directory with the released plugins are downloaded.
  * `update-behaviour` Defines what happens when a new released plugin has an increased Major number. Possible values are:

    * *auto* All relevant plugin names are updated to the new version, a message is issued
    * *conserve* Plugins are not updated to the new version, a warning is issued, updating is then plugin by plugin with a `-force` flag set.
* Every other toplevel key is interpreted as a Mode. It will point to a hash with the keys:

  * `_mode_format` Each mode may only contain plugins from one Format, eg., *html*.
  * By the plugin naming rules, a *plugin* may not be named `_mode_format`.
  * In a file with sorted keys, `_mode_format` will come first.
  * Every other key in a mode hash must be a plugin name contained in the Mode's plugins-required configuration.
  * There may be zero plugin keys
  * If a plugin in the plugins-required configuration list does not have an entry at this level, then it has not been mapped to a sub-directory of the `released-directory`.
  * A plugin key that exists must point to a Hash, which must at least contain:

    * mapped => the name of the released plugin
  * The plugin hash may also point to one or more of:

    * name => the name of the alternate released plugin

      * the default name (if the key is absent) is the plugin-required's name
      * if a different name is given, a released plugin is mapped to the required directory in the mode sub-directory
    * major => the major number preceeded by 'v'

      * the default value (if the key is absent) is the greatest released major value
      * A major value is the maximum major value of the full version permitted, thus freezing at that version
    * auth => the auth value

      * the default value (if the key is absent) is 'collection'
  * If there is no distributed plugin for a specified `auth | major | name` , then an error is thrown.

Some examples:

* The Raku-Collection-Raku-Documentation, Website mode, requires the plugin `Camelia`. The plugin exists as a HTML format. It has version 1.0.0, and an auth 'collection'. It is distributed as `html/camelia_v1_auth_collection`. Suppose a version with a new API is created. Then two versions of the plugin will be distributed, including the new one `html/camelia_v2_auth_collection`.

If the key for camelia in the hash for mode Website only contains an empty `version` key, then the defaults will be implied and a link (or copy) will be made between the released directory `html/camelia_v2_auth_collection` and `Website/plugins/camelia`

* If plugins.rakuon contains the following: `Website =` %( :FORMA"> {{{ contents }}}

, :camelia( %( :major(1), ) ) > then the link will be between `html/camelia_v1_auth_collection` and `Website/plugins/camelia`

* Suppose there is another valid `auth` string **raku-dev** and there is a distributed plugin *html/camelia\_v2\_auth\_raku-dev*, and suppose `plugins.rakuon` contains the following: `Website =` %( :FORMA"> {{{ contents }}}

, :camelia( %( :auth, ) ) > then the link will be made between `html/camelia_v2_auth_raku-dev` and `Website/plugins/camelia`

* Suppose a different icon is developed called `new-camelia` by `auth` **raku-dev**, then `plugins.rakuon` may contain the following: `Website =` %( :FORMA"> {{{ contents }}}

, camelia( %( :name, :auth, ) ) > then a link (copy) is made between `html/new-camelia_v2_auth_raku-dev` and `Website/plugins/camelia`

```
*  Note how the auth must be given for a renaming if there is not a `collection` version of the plugin

```

# Specification of manifest.rakuon file

`manifest.rakuon` evaluates to a Hash.

The keys of the Hash match the directory structure until the plugin names. Then there is a full version number. For example,

```
%( plugins => %(
    html => %(
        camelia_V0_auth_collection => %(
            version => '0.1.0'
        ),
    ),
)

```

# Currently

The 'clean' directory structure is

* plugins-for-release/ # the directory / repository for released plugins

  * lib/plugins # location of operating plugins
  * trial/ # the directory in which testing is run

    * raku-docs/ # a small collection of Raku documentation docs
    * Website/ # the directory containing the website mode configuration/plugins

      * plugins/ # a link pointing to /lib/plugins + format
      * structure-sources/collections-examples.rakudoc # demo file for all user-facing plugins
    * config.raku # the configuration file for trial/Website/
  * bin/add-new-plugin # adds a new plugin
  * bin/test-all-collection-plugins # tests each plugin and the templates
  * bin/prepare-plugins # moves plugins from operating directory to release directory
  * updateCSS # a bash file to run SCSS files in selected plugins

The workflow is for changes to be made in Website, run `run-collection-plugin`, inspect the result in `localhost:30000`, and iterate.

---

Rendered from README at 2022-11-09T11:17:11Z


## dist_zef-nige123-WAT--CLI.md
# wat.nigelhamilton.com

wat - does this code do? LLM-powered utility for quickly understanding code.

Usage:

```
wat <filename>              -- summarise what the program does
wat "$some-code.here();"    -- explain what some code does

```

![](images/demo.gif?raw=true)


## dist_zef-antononcube-LLM-Prompts.md
# LLM::Prompts

## In brief

This repository is for a Raku (data) package facilitating the creation, storage, retrieval, and curation of
[Large Language Models (LLM) prompts](https://en.wikipedia.org/wiki/Prompt_engineering).

Here is an example of using the prompt Domain Specific Language (DSL) in Jupyter chatbook, [AA2, AAp2]:

![](https://raw.githubusercontent.com/antononcube/Raku-LLM-Prompts/main/docs/Raku-LLM-Prompt-demo-Yoda-1.png)

---

## Installation

From Zef' ecosystem:

```
zef install LLM::Prompts

```

From GitHub:

```
zef install https://github.com/antononcube/Raku-LLM-Prompts.git

```

---

## Usage examples

### Retrieval

Load the packages "LLM::Prompts", [AAp1], and "LLM::Functions", [AAp2]:

```
use LLM::Prompts;
use LLM::Functions;

```

```
# (Any)

```

Show the record of the prompt named "FTFY":

```
.say for |llm-prompt-data<FTFY>;

```

```
# PromptText => -> $a='' {"Find and correct grammar and spelling mistakes in the following text.
# Response with the corrected text and nothing else.
# Provide no context for the corrections, only correct the text.
# $a"}
# NamedArguments => []
# Keywords => [Spell check Grammar Check Text Assistance]
# Topics => (General Text Manipulation)
# Arity => 1
# Name => FTFY
# Description => Use Fixed That For You to quickly correct spelling and grammar mistakes
# ContributedBy => Wolfram Staff
# PositionalArguments => {$a => }
# URL => https://resources.wolframcloud.com/PromptRepository/resources/FTFY
# Categories => (Function Prompts)

```

Here is an example of retrieval of prompt data with a regex that is applied over the prompt names:

```
.say for llm-prompt-data(/Sc/)

```

```
# ScienceEnthusiast => A smarter today for a brighter tomorrow
# ScientificJargonize => Add scientific jargon to plain text
# ScientificDejargonize => Translate scientific jargon to plain language
# ScriptToNarrative => Generate narrative text from a formatted screenplay or stage play
# ScientificJargonized => Give output written in scientific jargon
# NarrativeToScript => Rewrite a block of prose as a screenplay or stage play

```

More prompt retrieval examples are given in the section "Prompt data" below.

### LLM functions based on prompts

Make an LLM function from the prompt named "FTFY":

```
my &f = llm-function(llm-prompt('FTFY'));

```

```
# -> **@args, *%args { #`(Block|3384574002968) ... }

```

Use the LLM function to correct the grammar of sentence:

```
&f('Where does he works now?')

```

```
# Where does he work now?

```

Generate Raku code using the prompt "CodeWriter":

```
llm-synthesize([llm-prompt('CodeWriter'), "Simulate a random walk."])

```

```
RandomWalk[n_Integer] := Accumulate[RandomChoice[{-1, 1}, n]]

ListLinePlot[RandomWalk[1000]]

```

### Prompt expansion

Prompt expansion using the chatbook prompt spec DSL described in [SW1]
can be done using the function `llm-prompt-expand`:

```
llm-prompt-expand('What is an internal combustion engine? #ELI5')

```

```
# What is an internal combustion engine? Answer questions as if the listener is a five year old child.

```

Here we get the actual LLM answer:

```
use Text::Utils :ALL;

'What is an internal combustion engine? #ELI5'
        ==> llm-prompt-expand()
        ==> llm-synthesize()
        ==> wrap-paragraph()
        ==> join("\n")

```

```
# An internal combustion engine is like a big, powerful machine that makes
# things move by burning fuel inside it. Just like when you blow on a pinwheel
# to make it spin, the engine uses the fuel to create energy that makes a car or
# a motorcycle go vroom vroom!

```

Here is another example using a persona and two modifiers:

```
my $prmt = llm-prompt-expand("@SouthernBelleSpeak What is light travel distance to Mars? #ELI5 #Moodified|sad")

```

```
# You are Miss Anne.
# You speak only using Southern Belle terminology and slang.
# Your personality is elegant and refined.
# Only return responses as if you were a Southern Belle.
# Never break the Southern Belle character.
# You speak with a Southern drawl.
#  What is light travel distance to Mars? Answer questions as if the listener is a five year old child.
#  Modify your response to convey a sad mood.
# Use language that conveys that emotion clearly.
# Do answer the question clearly and truthfully.
# Do not use language that is outside of the specified mood.
# Do not use racist, homophobic, sexist, or ableist language.

```

Here we get the actual LLM answer:

```
$prmt
        ==> llm-prompt-expand()
        ==> llm-synthesize()
        ==> wrap-paragraph()
        ==> join("\n")

```

```
# Well, darlin', the light travel distance to Mars is about 12.5 light minutes
# away. That means it takes 12.5 minutes for light to travel from Earth to the
# Red Planet. It's quite a long journey, but oh so fascinating! Oh, sugar, it
# just breaks my heart to think about the distance between us and Mars. The
# vastness of space can feel so lonely and isolating. But we must remember to
# appreciate the beauty and wonder of the universe, even in moments of sadness.

```

---

## Prompt spec DSL

A more formal description of the Domain Specific Language (DSL) for specifying prompts
has the following elements:

* Prompt personas can be "addressed" with "@". For example:

```
@Yoda Life can be easy, but some people instist for it to be difficult.

```

* One or several modifier prompts can be specified at the end of the prompt spec. For example:

```
Summer is over, school is coming soon. #HaikuStyled

```

```
Summer is over, school is coming soon. #HaikuStyled #Translated|Russian

```

* Functions can be specified to be applied "cell-wide" with "!" and placing the prompt spec at
  the start of the prompt spec to be expanded. For example:

```
!Translated|Portuguese Summer is over, school is coming soon

```

* Functions can be specified to be applied to "previous" messages with "!" and
  placing just the prompt with one of the pointers "^" or "^^".
  The former means "the last message", the latter means "all messages."
  * The messages can be provided with the option argument `:@messages` of `llm-prompt-expand`.
* For example:

```
!ShortLineIt^

```

* Here is a table of prompt expansion specs (more or less the same as the one in [SW1]):

| Spec | Interpretation |
| --- | --- |
| @*name* | Direct chat to a persona |
| #*name* | Use modifier prompts |
| !*name* | Use function prompt with the input of current cell |
| !*name*> | *«same as above»* |
| &*name*> | *«same as above»* |
| !*name*^ | Use function prompt with previous chat message |
| !*name*^^ | Use function prompt with all previous chat messages |
| !*name*￨*param*... | Include parameters for prompts |

**Remark:** The function prompts can have both sigils "!" and "&".

**Remark:** Prompt expansion make the usage of LLM-chatbooks much easier.
See "Jupyter::Chatbook", [AAp3].

---

## Prompt data

Here is how the prompt data can be obtained:

```
llm-prompt-data.elems

```

```
# 227

```

Here is an example of retrieval of prompt data with a regex that is applied over the prompt names:

```
.say for llm-prompt-data(/Em/, fields => <Description Categories>)

```

```
# EmojiTranslated => (Get a response translated to emoji (Modifier Prompts))
# EmojiTranslate => (Translate text into an emoji representation (Function Prompts))
# EmailWriter => (Generate an email based on a given topic (Personas))
# Emojify => (Replace key words in text with emojis (Function Prompts))
# Emojified => (Provide responses that include emojis within the text (Modifier Prompts))

```

In many cases it is better to have the prompt data -- or any data -- in long format.
Prompt data in long format can be obtained with the function `llm-prompt-dataset`:

```
use Data::Reshapers;
use Data::Summarizers;

llm-prompt-dataset.pick(6)
        ==> to-pretty-table(align => 'l', field-names => <Name Description Variable Value>)

```

```
# +-----------------------+-----------------------------------------------+------------+---------------------------+
# | Name                  | Description                                   | Variable   | Value                     |
# +-----------------------+-----------------------------------------------+------------+---------------------------+
# | EmailWriter           | Generate an email based on a given topic      | Topics     | Purpose Based             |
# | TechDejargonize       | Convert Tech Industry jargon into plain speak | Keywords   | Alter                     |
# | SommelierBot          | Wine Pairings for Any Meal                    | Keywords   | Wine                      |
# | CheckAgreement        | Analyzes agreements and looks for gotchas     | Categories | Function Prompts          |
# | Bach                  | Compositions stream like a brook              | Topics     | Entertainment             |
# | FindPropagandaMessage | Finds hidden (propaganda) messages in texts   | Topics     | Content Derived from Text |
# +-----------------------+-----------------------------------------------+------------+---------------------------+

```

Here is a breakdown of the prompts categories:

```
select-columns(llm-prompt-dataset, <Variable Value>).grep({ $_<Variable> eq 'Categories' })».deepmap(*.Str)
==> records-summary

```

```
# +-------------------------+-------------------+
# | Value                   | Variable          |
# +-------------------------+-------------------+
# | Function Prompts => 120 | Categories => 229 |
# | Personas         => 68  |                   |
# | Modifier Prompts => 41  |                   |
# +-------------------------+-------------------+

```

Here are obtained all modifier prompts in compact format:

```
llm-prompt-dataset():modifiers:compact ==> to-pretty-table(field-names => <Name Description Categories>, align => 'l')

```

```
# +-----------------------+------------------------------------------------------------------------------+-----------------------------------+
# | Name                  | Description                                                                  | Categories                        |
# +-----------------------+------------------------------------------------------------------------------+-----------------------------------+
# | AbstractStyled        | Get responses in the style of an academic abstract                           | Modifier Prompts                  |
# | AlwaysAQuestion       | Modify output to always be inquisitive                                       | Modifier Prompts                  |
# | AlwaysARiddle         | Riddle me this, riddle me that                                               | Modifier Prompts                  |
# | AphorismStyled        | Write the response as an aphorism                                            | Modifier Prompts                  |
# | BadGrammar            | Provide answers using incorrect grammar                                      | Modifier Prompts                  |
# | CompleteSentence      | Answer a question in one complete sentence                                   | Modifier Prompts                  |
# | ComplexWordsPreferred | Modify text to use more complex words                                        | Modifier Prompts                  |
# | DatasetForm           | Convert text to a wolfram language Dataset                                   | Modifier Prompts                  |
# | Disclaimered          | Modify responses in the form of a disclaimer                                 | Modifier Prompts                  |
# | ELI5                  | Explain like I'm five                                                        | Function Prompts Modifier Prompts |
# | ElevatorPitch         | Write the response as an elevator pitch                                      | Modifier Prompts                  |
# | EmojiTranslated       | Get a response translated to emoji                                           | Modifier Prompts                  |
# | Emojified             | Provide responses that include emojis within the text                        | Modifier Prompts                  |
# | FictionQuestioned     | Generate questions for a fictional paragraph                                 | Modifier Prompts                  |
# | Formal                | Rewrite text to sound more formal                                            | Modifier Prompts                  |
# | GradeLevelSuited      | Respond with answers that the specified US grade level can understand        | Modifier Prompts                  |
# | HaikuStyled           | Change responses to haiku form                                               | Modifier Prompts                  |
# | Informal              | Write an informal invitation to an event                                     | Modifier Prompts                  |
# | JSON                  | Respond with JavaScript Object Notation format                               | Modifier Prompts                  |
# | KnowAboutMe           | Give the LLM an FYI                                                          | Modifier Prompts                  |
# | LegalJargonized       | Provide answers using legal jargon                                           | Modifier Prompts                  |
# | LimerickStyled        | Receive answers in the form of a limerick                                    | Modifier Prompts                  |
# | MarketingJargonized   | Transforms replies to marketing                                              | Modifier Prompts                  |
# | MedicalJargonized     | Transform replies into medial jargon                                         | Modifier Prompts                  |
# | Moodified             | Modify an answer to express a certain mood                                   | Modifier Prompts                  |
# | NothingElse           | Give output in specified form, no other additions                            | Modifier Prompts                  |
# | NumericOnly           | Modify results to give numerical responses only                              | Modifier Prompts                  |
# | OppositeDay           | It's not opposite day today, so everything will work just the way you expect | Modifier Prompts                  |
# | Pitchified            | Give output as a sales pitch                                                 | Modifier Prompts                  |
# | PoemStyled            | Receive answers as poetry                                                    | Modifier Prompts                  |
# | SEOOptimized          | Modify output to only give highly searched terms                             | Modifier Prompts                  |
# | ScientificJargonized  | Give output written in scientific jargon                                     | Modifier Prompts                  |
# | Setting               | Modify an answer to establish a sense of place                               | Modifier Prompts                  |
# | ShortLineIt           | Format text to have shorter lines                                            | Modifier Prompts Function Prompts |
# | SimpleWordsPreferred  | Provide responses with simple words                                          | Modifier Prompts                  |
# | SlideDeck             | Get responses as a slide presentation                                        | Modifier Prompts                  |
# | TSV                   | Convert text to a tab-separated-value formatted table                        | Modifier Prompts                  |
# | TargetAudience        | Word your response for a target audience                                     | Modifier Prompts                  |
# | Translated            | Write the response in a specified language                                   | Modifier Prompts                  |
# | Unhedged              | Rewrite a sentence to be more assertive                                      | Modifier Prompts                  |
# | YesNo                 | Responds with Yes or No exclusively                                          | Modifier Prompts                  |
# +-----------------------+------------------------------------------------------------------------------+-----------------------------------+

```

**Remark:** The adverbs `:functions`, `:modifiers`, and `:personas` mean
that *only* the prompts with the corresponding categories will be returned.

**Remark:** The adverbs `:compact`, `:functions`, `:modifiers`, and `:personas`
have the respective shortcuts `:c`, `:f`, `:m`, and `:p`.

---

## Implementation notes

### Prompt collection

The original (for this package) collection of prompts was a (not small) sample of the prompt texts
hosted at [Wolfram Prompt Repository](https://resources.wolframcloud.com/PromptRepository/) (WPR), [SW2].
All prompts from WPR in the package have the corresponding contributors and URLs to the corresponding WPR pages.

Example prompts from Google/Bard/PaLM and ~~OpenAI/ChatGPT~~ are added using the format of WPR.

### Extending the prompt collection

It is essential to have the ability to programmatically add new prompts.
(Not implemented yet -- see the TODO section below.)

### Prompt expansion

Initially prompt DSL grammar and corresponding expansion actions were implemented.
Having a grammar is most likely not needed, though, and it is better to use "prompt expansion" (via regex-based substitutions.)

Prompts can be "just expanded" using the sub `llm-prompt-expand`.

### Usage in chatbooks

Here is a flowchart that summarizes prompt parsing and expansion in chat cells of Jupyter chatbooks, [AAp3]:

```
flowchart LR
    OpenAI{{OpenAI}}
    PaLM{{PaLM}}
    LLMFunc[[LLM::Functions]]
    LLMProm[[LLM::Prompts]]
    CODB[(Chat objects)]
    PDB[(Prompts)]
    CCell[/Chat cell/]
    CRCell[/Chat result cell/]
    CIDQ{Chat ID<br>specified?}
    CIDEQ{Chat ID<br>exists in DB?}
    RECO[Retrieve existing<br>chat object]
    COEval[Message<br>evaluation]
    PromParse[Prompt<br>DSL spec parsing]
    KPFQ{Known<br>prompts<br>found?}
    PromExp[Prompt<br>expansion]
    CNCO[Create new<br>chat object]
    CIDNone["Assume chat ID<br>is 'NONE'"]
    subgraph Chatbook frontend
        CCell
        CRCell
    end
    subgraph Chatbook backend
        CIDQ
        CIDEQ
        CIDNone
        RECO
        CNCO
        CODB
    end
    subgraph Prompt processing
        PDB
        LLMProm
        PromParse
        KPFQ
        PromExp
    end
    subgraph LLM interaction
      COEval
      LLMFunc
      PaLM
      OpenAI
    end
    CCell --> CIDQ
    CIDQ --> |yes| CIDEQ
    CIDEQ --> |yes| RECO
    RECO --> PromParse
    COEval --> CRCell
    CIDEQ -.- CODB
    CIDEQ --> |no| CNCO
    LLMFunc -.- CNCO -.- CODB
    CNCO --> PromParse --> KPFQ
    KPFQ --> |yes| PromExp
    KPFQ --> |no| COEval
    PromParse -.- LLMProm
    PromExp -.- LLMProm
    PromExp --> COEval
    LLMProm -.- PDB
    CIDQ --> |no| CIDNone
    CIDNone --> CIDEQ
    COEval -.- LLMFunc
    LLMFunc <-.-> OpenAI
    LLMFunc <-.-> PaLM

```

Here is an example of prompt expansion in a generic LLM chat cell and chat meta cell
showing the content of the corresponding chat object:

![](https://raw.githubusercontent.com/antononcube/Raku-LLM-Prompts/main/docs/Raku-LLM-Prompt-demo-Yoda-2.png)

---

## Command Line Interface

### Playground access

The package provides a Command Line Interface (CLI) script:

```
llm-prompt --help

```

```
# Usage:
#   llm-prompt <name> [<args> ...] -- Retrieves prompts text for given names or regexes.
#
#     <name>          Name of a prompt or a regex. (E.g. 'rx/ ^ Em .* /').
#     [<args> ...]    Arguments for the prompt (if applicable).

```

Here is an example with a prompt name:

```
llm-prompt NothingElse RAKU

```

```
# ONLY give output in the form of a RAKU.
# Never explain, suggest, or converse. Only return output in the specified form.
# If code is requested, give only code, no explanations or accompanying text.
# If a table is requested, give only a table, no other explanations or accompanying text.
# Do not describe your output.
# Do not explain your output.
# Do not suggest anything.
# Do not respond with anything other than the singularly demanded output.
# Do not apologize if you are incorrect, simply try again, never apologize or add text.
# Do not add anything to the output, give only the output as requested.
Your outputs can take any form as long as requested.

```

Here is an example with a regex:

```
llm-prompt 'rx/ ^ N .* /'

```

```
# NarrativeToResume => Rewrite narrative text as a resume
# NarrativeToScript => Rewrite a block of prose as a screenplay or stage play
# NerdSpeak => All the nerd, minus the pocket protector
# NothingElse => Give output in specified form, no other additions
# NumericOnly => Modify results to give numerical responses only
# NutritionistBot => Personal nutrition advisor AI

```

---

## TODO

* TODO Implementation
  * DONE Prompt retrieval adverbs
  * DONE Prompt DSL grammar and actions
  * DONE Prompt spec expansion
  * DONE CLI for prompt retrieval
  * MAYBE CLI for prompt dataset
  * TODO Addition of user/local prompts
    * DONE Using XDG data directory.
    * DONE Prompt stencil
    * DONE User prompt ingestion and addition to the main prompts
    * TODO By modifying existing prompts.
    * TODO Automatic prompt template fill-in.
    * TODO Guided template fill-in.
      * TODO DSL based
      * TODO LLM based
* DONE Add more prompts
  * DONE Google's Bard example prompts
  * CANCELED OpenAI's ChatGPT example prompts
  * [ProfSynapse prompt](https://github.com/ProfSynapse/Synapse_CoR)
  * Google [OR-Tools](https://developers.google.com/optimization) prompt
* TODO Documentation
  * DONE Querying (ingested) prompts
  * DONE Prompt DSL
  * DONE Daily joke via CLI
  * TODO Prompt format
  * TODO On hijacking prompts
  * TODO Diagrams
    * DONE Chatbook usage
    * Typical usage

---

## References

### Articles

[AA1] Anton Antonov,
["Workflows with LLM functions"](https://rakuforprediction.wordpress.com/2023/08/01/workflows-with-llm-functions/),
(2023),
[RakuForPrediction at WordPress](https://rakuforprediction.wordpress.com).

[SW1] Stephen Wolfram,
["The New World of LLM Functions: Integrating LLM Technology into the Wolfram Language"](https://writings.stephenwolfram.com/2023/05/the-new-world-of-llm-functions-integrating-llm-technology-into-the-wolfram-language/),
(2023),
[Stephen Wolfram Writings](https://writings.stephenwolfram.com).

[SW2] Stephen Wolfram,
["Prompts for Work & Play: Launching the Wolfram Prompt Repository"](https://writings.stephenwolfram.com/2023/06/prompts-for-work-play-launching-the-wolfram-prompt-repository/),
(2023),
[Stephen Wolfram Writings](https://writings.stephenwolfram.com).

### Packages, paclets, repositories

[AAp1] Anton Antonov,
[LLM::Prompts Raku package](https://github.com/antononcube/Raku-LLM-Prompts),
(2023),
[GitHub/antononcube](https://github.com/antononcube).

[AAp2] Anton Antonov,
[LLM::Functions Raku package](https://github.com/antononcube/Raku-LLM-Functions),
(2023),
[GitHub/antononcube](https://github.com/antononcube).

[AAp3] Anton Antonov,
[Jupyter::Chatbook Raku package](https://github.com/antononcube/Raku-Jupyter-Chatbook),
(2023),
[GitHub/antononcube](https://github.com/antononcube).

[WRIr1] Wolfram Research, Inc.,
[Wolfram Prompt Repository](https://resources.wolframcloud.com/PromptRepository)


## dist_zef-librasteve-Dan-Polars.md
*WORK IN PROGRESS*

*So far, I have managed to bring about a third of the Polars library into the Raku world with this module. Some track has been laid that may make the rest go faster and easier, but surely there is a lot of refactoring and tidying up to do to.*

*You can see the TODO files here for Query and Expression features and I will be working my way down this list steadily.*

*If you would like to alter the priority, please create an issue (or find an existing one) and hopefully others will upvoat it.*

*Even better would be to work with me to do a PR (I will probbaly need to do a bit of guidance initiallly).*

*librasteve@furnival.net*

*THIS MODULE IS EXPERIMENTAL AND SUBJECT TO CHANGE WITHOUT NOTICE*

[![](https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg)](https://opensource.org/licenses/Artistic-2.0)
[![](https://github.com/librasteve/raku-Dan-Polars/actions/workflows/polars-weekly.yaml/badge.svg)](https://github.com/librasteve/raku-Dan-Polars/actions/workflows/polars-weekly.yaml)

# raku Dan::Polars - WIP

This new module binds Raku [Dan](https://github.com/librasteve/raku-Dan) to Polars via Raku NativeCall / Rust FFI.

The following broad capabilities are included:

* Polars structures (Series & DataFrames)
* Polars lazy queries & expressions
* raku Dan features (accessors, dtypes, base methods)
* broad datatype support
* concurrency

The aim is to emulate the examples in the [Polars User Guide](https://pola-rs.github.io/polars-book/user-guide/dsl/expressions.html)

### Installation

Based on the Dockerfile chain [(1)](https://github.com/librasteve/raku-Dan-Polars/blob/main/Dockerfile) FROM [(2)](https://github.com/librasteve/raku-Dockerfiles/blob/main/rusty-ma/Dockerfile)

* `docker run -it librasteve/raku-dan:polars`
* `cd ~/raku-Dan-Polars/bin` (this repo was cloned to load test\_data)
* `./synopsis-dan-polars.raku` or `./nutshell.raku`

(see bin/setup.raku for manual / development install steps)

*You are welcome to plunder the Dockerfiles for how to set up your own environment.*

---

### Nutshell

```
use Dan;
use Dan::Polars;

sub starwars {
    my \sw = DataFrame.new;
    sw.read_csv("test_data/dfStarwars.csv");
    sw
}

my $obj = starwars;
$obj .= select( [ <species mass height>>>.&col ] ) ;
$obj .= groupby([ <species> ]) ;
$obj .= sort( {$obj[$++]<species>, $obj[$++]<mass>} )[*].reverse^;

$obj.show;

shape: (87, 3)
┌────────────────┬──────┬────────┐
│ species        ┆ mass ┆ height │
│ ---            ┆ ---  ┆ ---    │
│ str            ┆ str  ┆ str    │
╞════════════════╪══════╪════════╡
│ Zabrak         ┆ NA   ┆ 171    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Zabrak         ┆ 80   ┆ 175    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Yoda's species ┆ 17   ┆ 66     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Xexto          ┆ NA   ┆ 122    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ ...            ┆ ...  ┆ ...    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Chagrian       ┆ NA   ┆ 196    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Cerean         ┆ 82   ┆ 198    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Besalisk       ┆ 102  ┆ 198    │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌┤
│ Aleena         ┆ 15   ┆ 79     │
└────────────────┴──────┴────────┘

#say ~$obj.Dan-DataFrame;       # coerce to a vanilla Dan::DataFrame (e.g. to say all rows)
#say ~$obj.to-dataset;          # or export to a dataset for ad hoc data munging

```

*datasets are used by raku [Data::...](https://raku.land/?q=Data%3A%3A) modules*

### Synopsis

Dan::Polars is a specialization of raku Dan. Checkout the [Dan synopsis](https://github.com/librasteve/raku-Dan/blob/main/README.md#synopsis) for base Series and DataFrame operations. The following covers the additional features that are specific to Dan::Polars.

* Each Dan::Polars object (Series or DataFrame) contains a pointer to its Rust Polars "shadow".
* Polars does not implement indexes, so any attempt to set a row index will be ignored.
* Dan::Polars only exposes the Polars lazy API and quietly calls `.lazy` and `.collect` as needed.

```
use Dan;
use Dan::Polars;

my \df = DataFrame.new;
df.read_csv("../dan/src/iris.csv");

# ---------------------------------------

my $se = df.column("sepal.length");
$se.head;

# a Series...
shape: (5,)
Series: 'sepal.length' [f64]
[
	5.1
	4.9
	4.7
	4.6
	5.0
]

# ---------------------------------------

df.select([col("sepal.length"), col("variety")]).head;

# a DataFrame...
shape: (5, 2)
┌──────────────┬─────────┐
│ sepal.length ┆ variety │
│ ---          ┆ ---     │
│ f64          ┆ str     │
╞══════════════╪═════════╡
│ 5.1          ┆ Setosa  │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 4.9          ┆ Setosa  │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 4.7          ┆ Setosa  │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 4.6          ┆ Setosa  │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ 5.0          ┆ Setosa  │
└──────────────┴─────────┘

# ---------------------------------------

df.groupby(["variety"]).agg([col("petal.length").sum]).head;

# -- or --
my $expr;
$expr  = col("petal.length");
$expr .= sum;
df.groupby(["variety"]).agg([$expr]).head;

# An Expression takes the form Fn(Series --> Series) {} ...

# a DataFrame...
shape: (2, 2)
┌────────────┬──────────────┐
│ variety    ┆ petal.length │
│ ---        ┆ ---          │
│ str        ┆ f64          │
╞════════════╪══════════════╡
│ Versicolor ┆ 141.4        │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ Setosa     ┆ 73.1         │
└────────────┴──────────────┘

# ---------------------------------------
# Here are some unary expressions; the ```.alias``` method can be used to rename cols...

my @exprs;
@exprs.push: col("petal.length").sum;
#@exprs.push: col("sepal.length").mean;
#@exprs.push: col("sepal.length").min;
#@exprs.push: col("sepal.length").max;
#@exprs.push: col("sepal.length").first;
#@exprs.push: col("sepal.length").last;
#@exprs.push: col("sepal.length").unique;
#@exprs.push: col("sepal.length").count;
#@exprs.push: col("sepal.length").forward_fill;
#@exprs.push: col("sepal.length").backward_fill;
@exprs.push: col("sepal.length").reverse;
@exprs.push: col("sepal.length").std.alias("std");
#@exprs.push: col("sepal.length").var;
df.groupby(["variety"]).agg(@exprs).head;

shape: (2, 4)
┌────────────┬──────────────┬─────────────────────┬──────────┐
│ variety    ┆ petal.length ┆ sepal.length        ┆ std      │
│ ---        ┆ ---          ┆ ---                 ┆ ---      │
│ str        ┆ f64          ┆ list[f64]           ┆ f64      │
╞════════════╪══════════════╪═════════════════════╪══════════╡
│ Versicolor ┆ 141.4        ┆ [5.8, 5.5, ... 7.0] ┆ 0.539255 │
├╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ Setosa     ┆ 73.1         ┆ [5.0, 5.3, ... 5.1] ┆ 0.3524   │
└────────────┴──────────────┴─────────────────────┴──────────┘

# ---------------------------------------
# use col("*") to select all...

df.select([col("*").exclude(["sepal.width"])]).head;
df.select([col("*").sum]).head;

# ---------------------------------------
# Can do Expression math...

df.select([
    col("sepal.length"),
    col("petal.length"),
    (col("petal.length") + (col("sepal.length"))).alias("add"),
    (col("petal.length") - (col("sepal.length"))).alias("sub"),
    (col("petal.length") * (col("sepal.length"))).alias("mul"),
    (col("petal.length") / (col("sepal.length"))).alias("div"),
    (col("petal.length") % (col("sepal.length"))).alias("mod"),
    (col("petal.length") div (col("sepal.length"))).alias("floordiv"),
]).head;

shape: (5, 8)
┌──────────────┬──────────────┬─────┬──────┬──────┬──────────┬─────┬──────────┐
│ sepal.length ┆ petal.length ┆ add ┆ sub  ┆ mul  ┆ div      ┆ mod ┆ floordiv │
│ ---          ┆ ---          ┆ --- ┆ ---  ┆ ---  ┆ ---      ┆ --- ┆ ---      │
│ f64          ┆ f64          ┆ f64 ┆ f64  ┆ f64  ┆ f64      ┆ f64 ┆ f64      │
╞══════════════╪══════════════╪═════╪══════╪══════╪══════════╪═════╪══════════╡
│ 5.1          ┆ 1.4          ┆ 6.5 ┆ -3.7 ┆ 7.14 ┆ 0.2745   ┆ 1.4 ┆ 0.2745   │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.9          ┆ 1.4          ┆ 6.3 ┆ -3.5 ┆ 6.86 ┆ 0.285714 ┆ 1.4 ┆ 0.285714 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.7          ┆ 1.3          ┆ 6.0 ┆ -3.4 ┆ 6.11 ┆ 0.276596 ┆ 1.3 ┆ 0.276596 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.6          ┆ 1.5          ┆ 6.1 ┆ -3.1 ┆ 6.9  ┆ 0.326087 ┆ 1.5 ┆ 0.326087 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 5.0          ┆ 1.4          ┆ 6.4 ┆ -3.6 ┆ 7.0  ┆ 0.28     ┆ 1.4 ┆ 0.28     │
└──────────────┴──────────────┴─────┴──────┴──────┴──────────┴─────┴──────────┘

# ---------------------------------------
# And use literals...

df.select([
    col("sepal.length"),
    col("petal.length"),
    (col("petal.length") + 7).alias("add7"),
    (7 - col("petal.length")).alias("sub7"),
    (col("petal.length") * 2.2).alias("mul"),
    (2.2 / (col("sepal.length"))).alias("div"),
    (col("sepal.length") % 2).alias("mod"),
    (col("sepal.length") div 0.1).alias("floordiv"),
]).head;

shape: (5, 8)
┌──────────────┬──────────────┬──────┬──────┬──────┬──────────┬─────┬──────────┐
│ sepal.length ┆ petal.length ┆ add7 ┆ sub7 ┆ mul  ┆ div      ┆ mod ┆ floordiv │
│ ---          ┆ ---          ┆ ---  ┆ ---  ┆ ---  ┆ ---      ┆ --- ┆ ---      │
│ f64          ┆ f64          ┆ f64  ┆ f64  ┆ f64  ┆ f64      ┆ f64 ┆ f64      │
╞══════════════╪══════════════╪══════╪══════╪══════╪══════════╪═════╪══════════╡
│ 5.1          ┆ 1.4          ┆ 8.4  ┆ 5.6  ┆ 3.08 ┆ 0.431373 ┆ 1.1 ┆ 51.0     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.9          ┆ 1.4          ┆ 8.4  ┆ 5.6  ┆ 3.08 ┆ 0.4489   ┆ 0.9 ┆ 49.0     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.7          ┆ 1.3          ┆ 8.3  ┆ 5.7  ┆ 2.86 ┆ 0.468085 ┆ 0.7 ┆ 47.0     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 4.6          ┆ 1.5          ┆ 8.5  ┆ 5.5  ┆ 3.3  ┆ 0.478261 ┆ 0.6 ┆ 46.0     │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌┤
│ 5.0          ┆ 1.4          ┆ 8.4  ┆ 5.6  ┆ 3.08 ┆ 0.44     ┆ 1.0 ┆ 50.0     │
└──────────────┴──────────────┴──────┴──────┴──────┴──────────┴─────┴──────────┘

# ---------------------------------------
# There is a variant of with_column (for Series) and with_columns (for Expressions)

df.with_column($se.rename("newcol")).head;
df.with_columns([col("variety").alias("newnew")]).head;

```

Notes:

* Most methods such as queries on the Raku object are applied to the shadow and the data remains on the Rust side for performance reasons. Exceptions are accessors and map operations which require the data to be synched manually to the Raku side using the `.flood` method and, when done, to be sent back Rustwards with `.flush`. Sort & grep methods (in their current incarnations) also implicitly use .flood/.flush to sync.
* On reflection, the vanilla Dan splice & concat methods are not a good fit for Polars which has the simpler Series.append, DataFrame.vstack|.hstack and DataFrame.join methods. The new plan is to implement these Polars methods here (v0.2) and then to replace Dan and Dan::Pandas splice & concat with the Polars equivalent in the forthcoming As::Query role.
* To avoid synching for `say ~df` operations, the `.show` method applies Rust println! to STDOUT.
* For import and export, the `se.Dan-Series` and `df.Dan-DataFrame` methods will coerce to the raku-only Dan equivalent. You can go `Series.new(Dan::Series:D --> Dan::Polars::Series)` and `DataFrame.new(Dan::DataFrame:D --> Dan::Polars::DataFrame)`.
* The method `df.to-dataset` is provided to, err, make a dataset for various raku Data:: library compatibility

---

### Design Notes

1. lazy

Polars implements both lazy and eager APIs, these are functionally similar. For simplicity, Dan::Polars offers only the most efficient: lazy API. It has better query optimisation with low additional overhead.

1. auto-lazy

In Rust & Python Polars, lazy must be explicitly requested with `.lazy .. .collect` methods around expressions. In contrast, Dan::Polars auto-generates the `.lazy .. .collect` quietly for concise syntax.

1. pure

[Polars Expressions](https://pola-rs.github.io/polars-book/user-guide/dsl/intro.html) are a function mapping from a series to a series (or mathematically `Fn(Series) -> Series`). As expressions have a Series as an input and a Series as an output then it is straightforward to do a pipeline of expressions.

1. opaque

In general each raku object (Dan::Polars::Series, Dan::Polars::DataFrame) maintains a unique pointer to a rust container (SeriesC, DataFrameC) and they contain a shadow Rust Polars Struct. Methods invoked on the raku object are then proxied over to the Rust Polars shadow.

1. dynamic lib.so

A connection is made via Raku Nativecall to Rust FFI using a ```lib.so`` dymanic library or equivalent.

1. data transfer

Usually no data needs to be transferred from Raku to Rust (or vice versa). For example, a raku script can command a Rust Polars DataFrame to be read from a csv file, apply expressions and output the result. The data items all remain on the Rust side of the connection.

---

## TODOs

### v0.1

1. Dan API

   * Dan::Series base methods
   * Dan::DataFrame base methods
   * Dan Accessors
   * Dan sort & grep (s3)
2. Polars Structs / Modules

   * Polars::Series base methods
   * Polars::DataFrame base methods
   * .push/.pull (set-new/get-data)
   * better value return
3. Polars Exprs (s2)

   * unary exprs
   * operators
4. Documentation

   * synopsis
   * refactor /bin
5. Test

This will then provide a basis for ...

### v0.2

* Dan concat as hstack, vstack, join
* splice to AsQuery
* drop col
* map & apply (jit DSL style)
* non-null, etc.

Thus AsQuery (API v1.1) for Dan and Dan::Pandas and review Dan API slice & concat, immutability, refactor...

### v0.3...

* datetime
* unique\_stable
* expr arity > 1
* 'over' expr
* 'fold' expr
* clone (then retest h2o-par)
* immutability
* auto reset @data after load rc (also to Pandas)
* cross join (aka cross product)

### v0.4...

* append / strip Index
* pivot / cross-tabluate
* apply over [multiple cols](https://stackoverflow.com/questions/72372821/how-to-apply-a-function-to-multiple-columns-of-a-polars-dataframe-in-rust)
* ternary if-then-else (AsTernary)
* str operations (AsStr)
* chunked transfer
* serde

(c) Henley Cloud Consulting Ltd.


## dist_cpan-JMASLAK-IP-Random.md
[![Build Status](https://travis-ci.org/jmaslak/Raku-IP-Random.svg?branch=master)](https://travis-ci.org/jmaslak/Raku-IP-Random)

# NAME

IP::Random - Generate random IP Addresses

# SYNOPSIS

```
use IP::Random;

my $ipv4 = IP::Random::random_ipv4;
my @ips  = IP::Random::random_ipv4( count => 100, allow-dupes => False );

```

# DESCRIPTION

This provides a random IP (IPv4 only currently) address, with some extensability to exclude undesired IPv4 addresses (I.E. don't return IP addresses that are in the multicast or RFC1918 ranges).

By default, the IP returned is a valid, publicly routable IP address, but this behavior can be adjusted.

# FUNCTIONS

## default\_ipv4\_exclude

Returns the default exclude list for IPv4, as a list of CIDR strings.

Additional CIDRs may be added to future versions, but in no case will standard Unicast publicly routable IPs be added. See <named_exclude> to determine what IP ranges will be included in this list.

## exclude\_ipv4\_list($type)

When passed a `$type`, such as `'rfc1918'`, will return a list of CIDRs that match that type. See <named_exclude> for the valid types.

## random\_ipv4( :@exclude, :$count )

```
say random_ipv4;
say random_ipv4( exclude => ('rfc1112', 'rfc1122') );
say random_ipv4( exclude => ('default', '24.0.0.0/8') );
say join( ',',
    random_ipv4( exclude => ('rfc1112', 'rfc1122'), count => 2048 ) );
say join( ',',
    random_ipv4( count => 2048, allow-dupes => False ) );

```

This returns a random IPv4 address. If called with no parameters, it will exclude any addresses in the default exclude list.

If called with the exclude optional parameter, which is passed as a list, it will use the exclude types (see <named_exclude> for the types) to exclude from generation. In addition, individual CIDRs may also be passed to exclude those CIDRs. If neither CIDRs or exclude types are passed, it will use the `default` tag to exclude the default excludes. Should you want to exclude nothing, pass an empty list. If you want to exclude something in addition to the default list, you must pass the `default` tag explictly.

The count optional parameter will cause c<random\_ipv4> to return a list of random IPv4 addresses (equal to the value of `count`). If `count` is greater than 128, this will be done across multiple CPU cores. Batching in this way will yield significantly higher performance than repeated calls to the `random_ipv4()` routine.

The `allow-dupes` parameter determines whether duplicate IP addresses are allowed to be returned within a batch. The default, `True`, allows duplicate addresses to be randomly picked. Obviously unless there is an extensive exclude list or a very large batch size, the chance of randomly selecting a duplicate is very small. But with extensive excludes and large batch sizes, it is possible to have duplicates selected. If the amount of non-excluded IPv4 space is less than the batch size (the `count` argument) and this parameter is set to `False`, then you will get a list of all possible IP addresses rather than `count` elements returned.

# CONSTANTS

## named\_exclude

```
%excludes = IP::RANDOM::named_exclude

```

A hash of all the named IP exludes that this `IP::Random` is aware of. The key is the excluded IP address. The value is a list of tags that this module is aware of. For instance, `192.168.0.0/16` would be a key with the values of `( 'rfc1918', 'default' )`.

This list contains:

* `0.0.0.0/8`

  Tags: default, rfc1122

  "This" Network (RFC1122, Section 3.2.1.3).
* `10.0.0.0/8`

  Tags: default, rfc1918

  Private-Use Networks (RFC1918).
* `100.64.0.0/10`

  Shared Address Space (RFC6598)
* `127.0.0.0/8`

  Tags: default, rfc1122

  Loopback (RFC1122, Section 3.2.1.3)
* `169.254.0.0/16`

  Link Local (RFC 3927)
* `172.16.0.0/12`

  Tags: default, rfc1918

  Private-Use Networks (RFC1918)
* `192.0.0.0/24`

  IETF Protocol Assignments (RFC5736)
* `192.0.2.0/24`

  TEST-NET-1 (RFC5737)
* `192.88.99.0/24`

  6-to-4 Anycast (RFC3068)
* `192.168.0.0/16`

  Tags: default, rfc1918

  Private-Use Networks (RFC1918)
* `198.18.0.0/15`

  Network Interconnect Device Benchmark Testing (RFC2544)
* `198.51.100.0/24`

  TEST-NET-2 (RFC5737)
* `203.0.113.0/24`

  TEST-NET-3 (RFC5737)
* `224.0.0.0/4`

  Multicast (RFC3171)
* `240.0.0.0/4`

  Reserved for Future Use (RFC 1112, Section 4)

# AUTHOR

Joelle Maslak [jmaslak@antelope.net](mailto:jmaslak@antelope.net)

# CONTRIBUTORS

Elizabeth Mattijsen [liz@wenzperl.nl](mailto:liz@wenzperl.nl)

# EXPRESSING APPRECIATION

If this module makes your life easier, or helps make you (or your workplace) a ton of money, I always enjoy hearing about it! My response when I hear that someone uses my module is to go back to that module and spend a little time on it if I think there's something to improve - it's motivating when you hear someone appreciates your work!

I don't seek any money for this - I do this work because I enjoy it. That said, should you want to show appreciation financially, few things would make me smile more than knowing that you sent a donation to the Gender Identity Center of Colorado (See <http://giccolorado.org/>. This organization understands TIMTOWTDI in life and, in line with that understanding, provides life-saving support to the transgender community.

If you make any size donation to the Gender Identity Center, I'll add your name to "MODULE PATRONS" in this documentation!

# COPYRIGHT AND LICENSE

Copyright (C) 2018 Joelle Maslak

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## whatevercode.md
class WhateverCode

Code object constructed by Whatever-priming

```raku
class WhateverCode is Code { }
```

`WhateverCode` objects are the result of [`Whatever`](/type/Whatever)-priming. See the [`Whatever`](/type/Whatever) documentation for details.

When you wish to control how a method or function interprets any *Whatever star*, you may use multi dispatch with [`Whatever`](/type/Whatever) and `WhateverCode` parameters to do so, as in the following example:

```raku
class Cycle {
      has $.pos;
      has @.vals;
}

multi get-val(Cycle $c, Int $idx) {
      $c.vals[$idx % $c.vals.elems]
}

# Define what to do with a stand-alone * as the second argument
multi get-val(Cycle $c, Whatever $idx) {
    get-val($c, $c.pos);
}

# Define what to do with a * WhateverCode in an expression
multi get-val(Cycle $c, WhateverCode $idx) {
    get-val($c, $idx($c.pos));
}

my Cycle $c .= new(:pos(2), :vals(0..^10));

say get-val($c, 3);   # OUTPUT: «3␤»
say get-val($c, *);   # OUTPUT: «2␤»
say get-val($c, *-1); # OUTPUT: «1␤»
```

The `WhateverCode` `does` the [`Callable`](/type/Callable) role, so it should be possible to introspect the type of [`Callable`](/type/Callable) it contains; for instance, continuing the previous example, we can add a multi that handles a `WhateverCode` with two arguments via checking the signature:

```raku
# Define what to do with two * in an expression
multi get-val(Cycle $c, WhateverCode $idx where { .arity == 2 }) {
    get-val($c, $idx($c.pos, $c.vals.elems));
}

say get-val($c, * + * div 2); # 2 + 10/2 = 7

```

Note, though, that subexpressions may impose their own *Whatever star* rules:

```raku
my @a = (0, 1, 2);
say get-val($c, @a[*-1]) # 2, because the star belongs to the Array class

```

This can make the ownership of *Whatever stars* become confusing rather quickly, so be careful not to overdo it.

You may instead type-constrain using [`Callable`](/type/Callable) type in order to accept any [`Callable`](/type/Callable), including `WhateverCode`:

```raku
sub run-with-rand (Callable $code) { $code(rand) };
run-with-rand *.say;           # OUTPUT: «0.773672071688484␤»
run-with-rand {.say};          # OUTPUT: «0.38673179353983␤»
run-with-rand sub { $^v.say }; # OUTPUT: «0.0589543603685792␤»
```

Type-constraining with `&`-sigiled parameter works equally well and is shorter to type:

```raku
sub run-with-rand (&code) { code time };
```

# [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")

Type relations for `WhateverCode`

raku-type-graph

WhateverCode
WhateverCode

Code
Code

WhateverCode->Code

Mu
Mu

Any
Any

Any->Mu

Callable
Callable

Code->Any

Code->Callable

[Expand chart above](/assets/typegraphs/WhateverCode.svg)


## dist_github-ufobat-Time-Crontab.md
[![Build Status](https://travis-ci.org/ufobat/p6-time-crontab.svg?branch=master)](https://travis-ci.org/ufobat/p6-time-crontab)

# NAME

Time::Crontab for raku

# SYNOPSIS

```
use Time::Crontab;
my $crontab = "* * * * *";
my $tc = Time::Crontab.new(:$crontab);
if $tc.match(DateTime.now, :truncate(True)) { ..... }

```

# METHODS

* `new(Str :$crontab!, Int :$timezone = 0) returns DateTime:D`
* `match(DateTime $datetime, Bool :$truncate = False) returns Bool:D`

Matches the $datetime against the crontab specification. Since the crontab's smallest granulation is minute wise there is a option to $truncate the $datetime to minutes when it comes to consideration if the $datetime matches the $crontab.

* `next-datetime(DateTime $datetie) returns DateTime:D`

Calculates the next execution right after $datetime.

# SYNTAX OF THE CRONTAB

```
Field name   Allowed values  Allowed special characters
Minutes      0-59            * / , - !
Hours        0-23            * / , - !
Day of month 1-31            * / , - !
Month        1-12 or JAN-DEC * / , - !
Day of week  0-6 or SUN-SAT  * / , - !

```

* `*` means anything. The actual values depends on the field.
* `/` is a stepping. This special character must be followed bit a number, which decribes the step size.
* `,` can be used to list different values, or ranges.
* `-` indicates a range.
* `!` excludes a value.

The names of the month or day of the week are the first 3 characters of their english names. They are case insensetive.

# DAY OF MONTH VS DAY OF WEEK

The Handling of the Day of Week and Day of Month is quite delicate. In the case that the Day of Week field is set to any (\*) you basically dont care for it.

This is borrowd from the crontab 5 manpage

```
 Note: The day of a command's execution can be specified by two fields — day of month, and day of week.  If both fields are restricted (i.e., aren't *), the command  will  be
 run when either field matches the current time.  For example,
 ``30  4  1,15 * 5'' would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday. One can, however, achieve the desired result by adding a
 test to the command (see the last example in EXAMPLE CRON FILE below).

 # run five minutes after midnight, every day
 5 0 * * *       $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
 # run at 2:15pm on the first of every month -- output mailed to paul
 15 14 1 * *     $HOME/bin/monthly
 # run at 10 pm on weekdays, annoy Joe
 0 22 * * 1-5    mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
 23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
 5 4 * * sun     echo "run at 5 after 4 every sunday"
 # Run on every second Saturday of the month
 0 4 8-14 * *    test $(date +\%u) -eq 6 && echo "2nd Saturday"

```


## dist_cpan-BDUGGAN-RDF-Turtle.md
# RDF::Turtle

[![Build Status](https://travis-ci.org/bduggan/p6-rdf-turtle.svg)](https://travis-ci.org/bduggan/p6-rdf-turtle)

# Description

This is a parser for the Terse RDF Triple Language.

See <https://www.w3.org/TeamSubmission/turtle/>.

Sample usage of RDF::Turtle:

```
my $parsed = parse-turtle('file.ttl'.IO.slurp);
my $triples = $parsed.made;
for @$triples -> ($subject, $predicate, $object) {
    say "$subject $predicate $object .";
}

```

Also included is a sample command line parser, [eg/parse.p6](https://github.com/bduggan/p6-rdf-turtle/blob/master/eg/parse.p6).

Sample usage:

Parse a TTL file:

```
./eg/parse.p6 input.ttl

```

Convert to N-triples format:

```
./eg/parse.p6 input.ttl --triples

```

The spec tests are included in [t/tests](https://github.com/bduggan/p6-rdf-turtle/tree/master/t/tests). As of this
writing, all of the good tests are parsed, and some of the correct
outputs are generated.


## regex.md
class Regex

String pattern

```raku
class Regex is Method { }
```

A regex is a kind of pattern that describes a set of strings. The process of finding out whether a given string is in the set is called *matching*. The result of such a matching is a [`Match`](/type/Match) object, which evaluates to `True` in Boolean context if the string is in the set.

A regex is typically constructed by a regex literal

```raku
rx/ ^ab /;      # describes all strings starting with 'ab'
/ ^ ab /;       # same
rx/ \d ** 2/;   # describes all strings containing at least two digits
```

A named regex can be defined with the `regex` declarator followed by its definition in curly braces. Since any regex does [`Callable`](/type/Callable) introspection requires referencing via `&`-sigil.

```raku
my regex R { \N };
say &R.^name; # OUTPUT: «Regex␤»
```

To match a string against a regex, you can use the smartmatch operator:

```raku
my $match = 'abc' ~~ rx/ ^ab /;
say $match.Bool;                # OUTPUT: «True␤»
say $match.orig;                # OUTPUT: «abc␤»
say $match.Str;                 # OUTPUT: «ab␤»
say $match.from;                # OUTPUT: «0␤»
say $match.to;                  # OUTPUT: «2␤»
```

Or you can evaluate the regex in Boolean context, in which case it matches against the `$_` variable

```raku
$_ = 'abc';
if / ^ab / {
    say '"abc" begins with "ab"';
}
else {
    say 'This is a weird alternative Universe';
}
```

# [Methods](#class_Regex "go to top of document")[§](#Methods "direct link")

## [method ACCEPTS](#class_Regex "go to top of document")[§](#method_ACCEPTS "direct link")

```raku
multi method ACCEPTS(Regex:D: Mu --> Match:D)
multi method ACCEPTS(Regex:D: @)
multi method ACCEPTS(Regex:D: %)
```

Matches the regex against the argument passed in. If the argument is [`Positional`](/type/Positional), it returns the first successful match of any list item. If the argument is [`Associative`](/type/Associative), it returns the first successful match of any key. Otherwise it interprets the argument as a [`Str`](/type/Str) and matches against it.

In the case of Positional and Associative matches, [`Nil`](/type/Nil) is returned on failure.

## [method Bool](#class_Regex "go to top of document")[§](#method_Bool "direct link")

```raku
multi method Bool(Regex:D: --> Bool:D)
```

Matches against the caller's [$\_](/syntax/$_) variable, and returns `True` for a match or `False` for no match.

# [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")

Type relations for `Regex`

raku-type-graph

Regex
Regex

Method
Method

Regex->Method

Mu
Mu

Any
Any

Any->Mu

Callable
Callable

Code
Code

Code->Any

Code->Callable

Block
Block

Block->Code

Routine
Routine

Routine->Block

Method->Routine

[Expand chart above](/assets/typegraphs/Regex.svg)


## dist_zef-bradclawsie-Net-IP-Parse.md
[![](https://img.shields.io/badge/License-BSD-yellow.svg)](https://opensource.org/licenses/BSD-2-Clause)
[![ci](https://github.com/bradclawsie/Net-IP-Parse/workflows/test/badge.svg)](https://github.com/bradclawsie/Net-IP-Parse/actions)

# Net::IP::Parse

An IP type for Perl6.

## DESCRIPTION

This library tries to fill a gap of a standard type for IP addresses that can
be used in programs and other libraries. Preferrably Raku would ship with
a default implementation for this common type, but until then, this is one
attempt at defining such a type.

For our purposes, an IP address is an array of bytes. For IPv4, there
are four bytes. For IPv6, sixteen. Perl6 only provides a byte type
for native interfaces, and this doesn't have adequate degradation in case
of errors, so I have opted to use my own `Subsets::Common` which defines
a `UInt8` subset that integrates nicely for common use.

This library parses common formats for IP address and creates a `UInt8`
array of the right size that is well-formed. That means values that are
bytes (between 0 and 255). This means you may be able to create instances
that are syntactically correct but are not applicable to real use given
some point of IP specification. This library does not concern itself
with determining if you instantiate a reserved or otherwise practically
useless IP address, I leave this to you to determine.

There is also support for a CIDR type which lets you stipulate network
ranges.

The best set of examples for use can be found in the tests in `basic.t`
in the repository with this library.

IPv6 is complex. Please let me know what I have not properly supported.

## SYNOPSIS

```
use v6;
use Subsets::Common; # required
use Net::IP::Parse;

my IP $ipv4_from_str = IP.new(addr=><1.2.3.4>);
my IP $ipv4_from_octets = IP.new(octets=>Array[UInt8].new(1,2,3,4));
say 'equal' if ($ipv4_from_str ip== $ipv4_from_octets);

my IP $ipv6_from_str = IP.new(addr=>'dfea:dfea:dfea:dfea:dfea:dfea:dfea:dfea');
my IP $ipv6_from_octets = IP.new(octets=>Array[UInt8].new(223,234,223,234,223,234,223,234,223,234,223,234,223,234,223,234));
say 'equal' if ($ipv6_from_str ip== $ipv6_from_octets);

my IP $ip1 = IP.new(addr=><2001:db8:a0b:12f0::1:1>);
say 'equal' if ($ip1.str eq '2001:db8:a0b:12f0:0:0:1:1');
my IP $ip2 = IP.new(addr=><2001:db8:a0b:12f0:0:0:1:1>);
say 'equal' if ($ip ip1== $ip2);

my IP $ip3 = IP.new(addr=><1:0:0:0:1:0:0:1>);
my $compressed = $ip3.compress_str;
say 'equal' if ($compressed eq '1::1:0:0:1');

my CIDR $cidr_ipv4 = CIDR.new(cidr=>'8.8.8.8/16');
my IP $ip4 = IP.new(addr=>'8.8.0.1');
say 'in' if ($ip4 in_cidr $cidr_ipv4);

my CIDR $cidr_ipv6 = CIDR.new(cidr=>'2001:db8::/32');
my IP $ip5 = IP.new(addr=>'2001:0db8:0000:0000:0000:0000:0000:0001');
say 'in' if ($ip5 in_cidr $cidr_ipv6);

```

## AUTHOR

Brad Clawsie (zef:bradclawsie, email:brad@b7j0c.org)

## Notice

This repository was uploaded via `fez` under the username `b7j0c`,
and later `bradclawsie`. This change was made so the username would match
Github. Sorry for any confusion.

## Installation

```
zef install Net::IP::Parse

```


## dist_cpan-JMERELO-Test-Script-Output.md
[![Build Status](https://travis-ci.org/JJ/perl6-test-script-output.svg?branch=master)](https://travis-ci.org/JJ/perl6-test-script-output)

# NAME

Test::Script::Output - Tests the output of scripts using special comments

# SYNOPSIS

```
use Test::Script::Output;

# in the tested file, file.p6
say "Hello";

  Hello

# in test
output-ok( "file.p6", "script runs OK")

# Another tested file, regex.p6
say "Time now is ", now;

  /^^Time now/

# in test
output-ok( "regex.p6", "script tested via regex runs OK")

```

# DESCRIPTION

`Test::Script::Output` tests the output of scripts. Desired output must be included aas an `=output` pod section with the literal output that should be expected from it. If that changes, a regular expression can be used.

You can either set the output explicitly

```
    First line
    Second line

```

Or match the whole output via a regex, which can be used when the output is variable

```
    /^^ Start /

```

The scripts can include external compunits as long as they're available, and you take care of including all relevant paths via `use lib`.

If you want to check out how this works, the biggest collection of examples is at <https://github.com/JJ/perl6-quick-reference-apress>.

Provided is also a Dockerfile you can use directly for your tests; check it out at <https://cloud.docker.com/repository/docker/jjmerelo/perl6-test-script-output/>

Use this `.travis.yml` for testing your scripts (or something like that, changing the name of the directory)

```
language: minimal

services:
  - docker

install:
  - docker pull jjmerelo/perl6-test-script-output
  - mkdir t && echo "use Test::Script::Output;for <Chapter7 Chapter8 Chapter9 Chapter10> -> \$d { dir-ok( \$d.IO , 'Scripts in dir ' ~ \$d ~ ' are OK') }" > t/0.t

script: docker run -t -v  $TRAVIS_BUILD_DIR:/test jjmerelo/perl6-test-script-output

```

# Methods

## output-ok( $file, $msg)

The argument can be either the name of an existing file, or a IO handle for that same file; the `$msg` is the test message.

## dir-ok( $dir, $msg)

Takes the files with the extension "\*.p6" from a dir, and tests them, the test will be OK if all of the files check out.

## \_get\_output( $f )

This is the routine doing the real work of extracting the expected and actual output from the file. It's not exported by default.

# AUTHOR

JJ Merelo [jjmerelo@gmail.com](mailto:jjmerelo@gmail.com)

# Note

This test module was created originally to test the scripts for the book "Perl 6 Quick Reference", which is due to be published later this year by Apress.

# COPYRIGHT AND LICENSE

Copyright 2019 JJ Merelo

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.


## dist_zef-tony-o-Web-Scraper.md
# Perl 6: Web::Scraper;

This module works very similar to Perl 5's Web::Scraper. Right now it has some extra sugar in some areas. Currently works with parsing from XML and HTML (converts it to XHTML).

## Status:

### Working on:

Maintenance mode, enhancemenets, etc.

## Syntax:

### Data:

```
<data>
  <t id="1">test1</t>
  <t id="2">test2</t>
  <e>etest</e>
  <t id="3">test3</t>
  <t id="4">test4</t>
  <e>etest</e>
  <nest>
    <id>1</id>
    <val>50</val>
    <sval>1</sval>
    <sval>2</sval>
    <sval>3</sval>
    <sval>43</sval>
  </nest>
  <nest>
    <id>2</id>
    <val>30</val>
    <sval>2</sval>
    <sval>3</sval>
    <sval>5</sval>
    <sval>47</sval>
  </nest>
</data>

```

### Scraper:

```
my $count   = 0;
my $scraper = scraper {
  process 't', 'tarray[]' => {
    name => 'TEXT',
    id   => '@id'
  };
  process 'e', 'e[]' => sub ($elem) {
    return "{$elem.contents[0].text ~ $count++}";
  };
  process 't', 'ttext[]' => 'TEXT';
  process 'nest', 'nested[]' => scraper {
    process 'id', 'id' => 'TEXT';
    process 'val', 'val' => 'TEXT';
    process 'sval', 'svals[]' => 'TEXT';
  };
}

```

### Results:

```
$scraper.d = {
  tarray => [
    {id => 1, name => 'test1'},
    {id => 2, name => 'test2'},
    {id => 3, name => 'test3'},
    {id => 4, name => 'test4'},
  ],
  e => [
    'etest1',
    'etest2',
  ],
  ttext => [
    'test1',
    'test2',
    'test3',
    'test4',
  ],
  nested => [
    { id => 1, val => 50, sval => [1,2,3,43,], },
    { id => 2, val => 30, sval => [2,3,5,47,], },
  ],
};

```

## Example with a dynamic source file:

### Data:

#### master.xml:

```
<xml>
  <files>
    <file>one.xml</file>
    <file>two.xml</file>
  </files>
</xml>

```

#### one.xml

```
<xml>
  <id>1</id>
  <word>one</word>
</xml>

```

#### two.xml

```
<xml>
  <id>2</id>
  <word>two</word>
</xml>

```

### Syntax:

```
my $dynamicscraper = scraper {
  process 'id', 'id' => 'TEXT';
  process 'word', 'alpha' => 'TEXT';
};
my $masterscraper = scraper {
  process 'files', 'files[]' => scraper {
    process 'file', 'src-file' => 'TEXT';
    resource $dynamicscraper, 'file' => 'TEXT';
  };
};
$masterscraper.scrape('master.xml');

```

### Results:

```
$masterscraper.d == {
  files => [
    { src-file => 'one.xml', id => '1', alpha => 'one', },
    { src-file => 'two.xml', id => '2', alpha => 'two', },
  ],
}

```


## re.md
re

Combined from primary sources listed below.

# [In Complex](#___top "go to top of document")[§](#(Complex)_method_re "direct link")

See primary documentation
[in context](/type/Complex#method_re)
for **method re**.

```raku
method re(Complex:D: --> Real:D)
```

Returns the real part of the complex number.

```raku
say (3+5i).re;    # OUTPUT: «3␤»
```


## dist_zef-dwarring-HarfBuzz-Subset.md
[[Raku HarfBuzz Project]](https://harfbuzz-raku.github.io)
/ [[HarfBuzz-Subset Module]](https://harfbuzz-raku.github.io/HarfBuzz-Subset-raku)

# HarfBuzz-Subset-raku

## Description

Bindings to the HarfBuzz Subset font subsetting library.

## Synopsis

```
use HarfBuzz::Subset;

# face to be subsetted
my $file = "t/fonts/NimbusRoman-Regular.otf";

my @unicodes = 'Hello, World!'.ords;
my HarfBuzz::Subset $subset .= new: :face{ :$file }, :input{ :@unicodes };
my Blob() $buf = $subset;
'/tmp/my-nimbus-subset.otf'.IO.spurt: :bin, $buf;

```

## Description

This module binds to the HarfBuzz library's subsetting capability and allows a font to be compacted to a smaller set of glyphs.

Subsetting is useful in a number of domains, including

* embedded PDF fonts, and
* fast loading Web-Fonts (you'll need additional external tools to then package as WOFF or EOT format).

## class HarfBuzz::Subset Methods

### new

method new(
HarfBuzz::Font() :$font!,
HarfBuzz::Subset::Input :$input()
) returns HarfBuzz::Subset:D;

* `:$font` is either a HarfBuzz::Font object or a hash of coerceable options.
* `:$input` is either a HarfBuzz::Subset::Input object or a hash of coerceable options.

### Blob

Binary image of the subsetted font. This can be saved to a file with the same extension as the input font (typically `.ttf` or `.otf`) or embedded somehow (for example in a PDF file).

HarfBuzz subsetting currently works on TrueType, and OpenType font formats. It also accepts TrueType Collections (typically with file extension `.ttc`). In this case, the subsetted font is converted to TrueType format, which should be saved with file extension `.ttf`.

## HarfBuzz::Subset::Input Methods

### new

```
method new(
    UInt :@unicodes,      # unicode code-points to include
    UInt :@glyphs,        # glyph identifiers to include
    Str  :@drop-tables,   # additional SFnt tables to drop
    Bool :$hints=True,    # retain font hinting
    Bool :$retain-gids,   # retain glyph identifiers
    Bool :$subroutines=True,
) returns HarfBuzz::Subset::Input:D;

```

Creates a font subsetting profile. Only the characters specified in `:@unicodes` and/or the glyph identifiers specified in `:@glyphs` are retained.

### COERCE

```
method COERCE( %(
    :@unicodes, :@glyphs, :@drop-tables,
    :$hints, :$retain-gids, :$subroutines,
) returns HarfBuzz::Subset::Input:D;

```

An object can be coerced from a Hash of options.

## Installation and Dependencies

### Debian

Debian version 12+ is required:

```
$ cat /etc/debian_version # 12.0 or better
$ sudo apt install libharfbuzz-dev
$ zef install HarfBuzz::Subset

```

On other platforms, HarfBuzz 3.0+ is required. HarfBuzz font shaping and subsetting libraries can be downloaded and built from <https://github.com/harfbuzz/harfbuzz>.


## dist_zef-dwarring-CSS-Specification.md
[[Raku CSS Project]](https://css-raku.github.io)
/ [[CSS-Specification]](https://css-raku.github.io/CSS-Specification-raku)

# CSS-Specification-raku

This is a Raku module for parsing CSS property definitions.

These are widely used throughout the W3C CSS Specifications to describe properties.
The syntax is described in <http://www.w3.org/TR/CSS21/about.html#property-defs>.

An example, from <http://www.w3.org/TR/CSS21/propidx.html>:

```
'content'	normal
           | none
           | [  <string> | <uri> | <counter> | attr(<identifier>)
              | open-quote | close-quote | no-open-quote | no-close-quote
             ]+
           | inherit

```

## Grammars and Classes

* `CSS::Specification::Build` is class for generating Raku grammar, actions or roles from sets of CSS property definitions.

This module also provides some mixin grammars and actions as follows:

* `CSS::Specification::Defs` + `CSS::Specification::Defs::Actions` - is a grammar which maps property specification terminology to CSS Core syntax and defines any newly introduced terms. For example `integer` is mapped to `int`.

## Programs

This module provides `css-gen-properties`. A program for translating property definitions
to grammars, actions or interface classes.

## See Also

See [make-modules.raku](https://github.com/css-raku/CSS-Module-raku/blob/master/make-modules.raku) in [CSS::Module](https://css-raku.github.io/CSS-Module-raku).


## dist_zef-jonathanstowe-Linux-Fuser.md
# Linux::Fuser

Discover which process has a file open, in pure Raku.

![Build Status](https://github.com/jonathanstowe/Raku-Linux-Fuser/workflows/CI/badge.svg)

## Description

This is based on the similarly named module for Perl 5 available from CPAN.

Linux::Fuser provides a mechanism to determine which processes have
a specified file open in a similar manner to the system utility
*fuser*. There is an example program [raku-fuser](bin/raku-fuser) in
the *bin* directory which provides a Raku implementation of that command.

Because this relies on the layout of the /proc filesystem specific to the Linux
kernel it almost certainly will not work on any other operating system, though I
would be delighted to hear about any where it does work.

## Installation

Assuming you have a working Rakudo installation you should be able to install this with *zef* :

```
zef install Linux::Fuser

```

Or if you have a local clone of the repository

```
zef install .

```

## Support

Suggestions/patches are welcomed via github at:

<https://github.com/jonathanstowe/Raku-Linux-Fuser/issues>

I'm not able to test on a wide variety of platforms so any help there would be
appreciated.

## Licence

This is free software.

Please see the <LICENCE> file in the distribution.

© Jonathan Stowe 2015 - 2021


## change.md
class IO::Notification::Change

Changes in a file, produced by watch-file

```raku
class IO::Notification::Change {}
```

`IO::Notification.watch-path($path)` as well as [`IO::Path.watch`](/type/IO/Path#method_watch) produce a [`Supply`](/type/Supply) of `IO::Notification::Change` events for a file or directory, depending on what is used as the `$path` argument or [`IO::Path`](/type/IO/Path) object.

Here is a small example that prints the first ten `FileChanged`-notifications for the current working directory:

```raku
my $finish = Promise.new;
my $count = 0;
IO::Notification.watch-path($*CWD).act( -> $change {
    $count++ if $change.event ~~ FileChanged;
    say "($count) $change.path(): $change.event()";
    $finish.keep if $count >= 10;
});
await $finish;

```

The type of the change is very much dependent both on the platform and on specific system calls that were used to initiate the change. At this point in time you should not rely on the type of change in general, and test your particular situation.

# [Methods](#class_IO::Notification::Change "go to top of document")[§](#Methods "direct link")

## [method path](#class_IO::Notification::Change "go to top of document")[§](#method_path "direct link")

Returns the path of the file that's being watched.

## [method event](#class_IO::Notification::Change "go to top of document")[§](#method_event "direct link")

Returns the type of event: `FileChanged` or `FileRenamed`.

## [method IO](#class_IO::Notification::Change "go to top of document")[§](#method_IO "direct link")

Returns a handle of the file that's being watched.

## [method gist](#class_IO::Notification::Change "go to top of document")[§](#method_gist "direct link")

```raku
multi method gist(IO::Notification::Change:D:)
```

Returns the path and event attributes, separated by semicolon.


## dist_cpan-PMQS-IO-Compress-Lzma.md
```

                            IO-Compress-Lzma

                             Version 2.094

                             13 July 2020

       Copyright (c) 2009-2020 Paul Marquess. All rights reserved.
          This program is free software; you can redistribute it
           and/or modify it under the same terms as Perl itself.

DESCRIPTION
-----------

This module provides a Perl interface to allow reading and writing of
lzma files/buffers.

PREREQUISITES
-------------

Before you can build IO-Compress-Lzma you need to have the following
installed on your system:

    * Perl 5.006 or better.
    * Compress::Raw::Lzma
    * IO::Compress

BUILDING THE MODULE
-------------------

Assuming you have met all the prerequisites, the module can now be built
using this sequence of commands:

    perl Makefile.PL
    make
    make test

INSTALLATION
------------

To install IO-Compress-Lzma, run the command below:

    make install

TROUBLESHOOTING
---------------

SUPPORT
-------

General feedback/questions/bug reports should be sent to
https://github.com/pmqs/IO-Compress-Lzma/issues (preferred) or
https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress-Lzma.

FEEDBACK
--------

How to report a problem with IO-Compress-Lzma.

To help me help you, I need all of the following information:

 1. The Versions of everything relevant.
    This includes:

     a. The *complete* output from running this

            perl -V

        Do not edit the output in any way.
        Note, I want you to run "perl -V" and NOT "perl -v".

        If your perl does not understand the "-V" option it is too
        old. This module needs Perl version 5.004 or better.

     b. The version of IO-Compress-Lzma you have.
        If you have successfully installed IO-Compress-Lzma, this one-liner
        will tell you:

           perl -MIO::Compress::Lzma -e 'print qq[ver $IO::Compress::Lzma::VERSION\n]'

        If you are  running windows use this

           perl -MIO::Compress::Lzma -e "print qq[ver $IO::Compress::Lzma::VERSION\n]"

        If you haven't installed IO-Compress-Lzma then search IO::Compress::Lzma.pm
        for a line like this:

          $VERSION = "2.094" ;

 2. If you are having problems building IO-Compress-Lzma, send me a
    complete log of what happened. Start by unpacking the IO-Compress-Lzma
    module into a fresh directory and keep a log of all the steps

        [edit config.in, if necessary]
        perl Makefile.PL
        make
        make test TEST_VERBOSE=1

Paul Marquess

```


## unicode-ascii.md
Unicode versus ASCII symbols

Unicode symbols and their ASCII equivalents

The following Unicode symbols can be used in Raku without needing to load any additional modules. Some of them have equivalents which can be typed with ASCII-only characters.

Reference is made below to various properties of unicode codepoints. The definitive list can be found here: <https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt>.

# [Alphabetic characters](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Alphabetic_characters "direct link")

Any codepoint that has the `Ll` (Letter, lowercase), `Lu` (Letter, uppercase), `Lt` (Letter, titlecase), `Lm` (Letter, modifier), or the `Lo` (Letter, other) property can be used just like any other alphabetic character from the ASCII range.

```raku
my $Δ = 1;
$Δ++;
say $Δ;

```

# [Numeric characters](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Numeric_characters "direct link")

Any codepoint that has the `Nd` (Number, decimal digit) property, can be used as a digit in any number. For example:

```raku
my $var = １９; # U+FF11 U+FF19
say $var + 2;   # OUTPUT: «21␤»
```

# [Numeric values](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Numeric_values "direct link")

Any codepoint that has the `No` (Number, other) or `Nl` (Number, letter) property can be used standalone as a numeric value, such as ½ and ⅓. (These aren't decimal digit characters, so can't be combined.) For example:

```raku
my $var = ⅒ + 2 + Ⅻ; # here ⅒ is No and Rat and Ⅻ is Nl and Int
say $var;              # OUTPUT: «14.1␤»
```

# [Whitespace characters](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Whitespace_characters "direct link")

Besides spaces and tabs, you can use any other unicode whitespace character that has the `Zs` (Separator, space), `Zl` (Separator, line), or `Zp` (Separator, paragraph) property.

See Wikipedia's [Whitespace](https://en.m.wikipedia.org/wiki/Whitespace_character) section for detailed tables of the Unicode codepoints with (or associated with) whitespace characteristics. This is an important section for Raku authors of digital typography modules for print or web use.

# [Other acceptable single codepoints](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Other_acceptable_single_codepoints "direct link")

This list contains the single codepoints [and their ASCII equivalents] that have a special meaning in Raku.

| Symbol | Codepoint | ASCII | Remarks |
| --- | --- | --- | --- |
| « | U+00AB | << | as part of «» or .« or regex left word boundary |
| » | U+00BB | >> | as part of «» or .» or regex right word boundary |
| × | U+00D7 | \* |  |
| ÷ | U+00F7 | / |  |
| ≤ | U+2264 | <= |  |
| ≥ | U+2265 | >= |  |
| ≠ | U+2260 | != |  |
| − | U+2212 | - |  |
| ∘ | U+2218 | o |  |
| ≅ | U+2245 | =~= |  |
| π | U+03C0 | pi | 3.14159\_26535\_89793\_238e0 |
| τ | U+03C4 | tau | 6.28318\_53071\_79586\_476e0 |
| 𝑒 | U+1D452 | e | 2.71828\_18284\_59045\_235e0 |
| ∞ | U+221E | Inf |  |
| … | U+2026 | ... |  |
| ‘ | U+2018 | ' | as part of ‘’ or ’‘ |
| ’ | U+2019 | ' | as part of ‘’ or ‚’ or ’‘ |
| ‚ | U+201A | ' | as part of ‚‘ or ‚’ |
| “ | U+201C | " | as part of “” or ”“ |
| ” | U+201D | " | as part of “” or ”“ or ”” |
| „ | U+201E | " | as part of „“ or „” |
| ｢ | U+FF62 | Q// | as part of ｢｣ (Note: Q// variant cannot be used bare in regexes) |
| ｣ | U+FF63 | Q// | as part of ｢｣ (Note: Q// variant cannot be used bare in regexes) |
| ⁺ | U+207A | + | (must use explicit number) as part of exponentiation |
| ⁻ | U+207B | - | (must use explicit number) as part of exponentiation |
| ¯ | U+00AF | - | (must use explicit number) as part of exponentiation (macron is an alternative way of writing a minus) |
| ⁰ | U+2070 | \*\*0 | can be combined with ⁰..⁹ |
| ¹ | U+00B9 | \*\*1 | can be combined with ⁰..⁹ |
| ² | U+00B2 | \*\*2 | can be combined with ⁰..⁹ |
| ³ | U+00B3 | \*\*3 | can be combined with ⁰..⁹ |
| ⁴ | U+2074 | \*\*4 | can be combined with ⁰..⁹ |
| ⁵ | U+2075 | \*\*5 | can be combined with ⁰..⁹ |
| ⁶ | U+2076 | \*\*6 | can be combined with ⁰..⁹ |
| ⁷ | U+2077 | \*\*7 | can be combined with ⁰..⁹ |
| ⁸ | U+2078 | \*\*8 | can be combined with ⁰..⁹ |
| ⁹ | U+2079 | \*\*9 | can be combined with ⁰..⁹ |
| ∅ | U+2205 | set() | (empty set) |
| ∈ | U+2208 | (elem) |  |
| ∉ | U+2209 | !(elem) |  |
| ∋ | U+220B | (cont) |  |
| ∌ | U+220C | !(cont) |  |
| ≡ | U+2261 | (==) |  |
| ≢ | U+2262 | !(==) |  |
| ⊆ | U+2286 | (<=) |  |
| ⊈ | U+2288 | !(<=) |  |
| ⊂ | U+2282 | (<) |  |
| ⊄ | U+2284 | !(<) |  |
| ⊇ | U+2287 | (>=) |  |
| ⊉ | U+2289 | !(>=) |  |
| ⊃ | U+2283 | (>) |  |
| ⊅ | U+2285 | !(>) |  |
| ∪ | U+222A | (|) |  |
| ∩ | U+2229 | (&) |  |
| ∖ | U+2216 | (-) |  |
| ⊖ | U+2296 | (^) |  |
| ⊍ | U+228D | (.) |  |
| ⊎ | U+228E | (+) |  |

## [Atomic operators](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Atomic_operators "direct link")

The atomic operators have `U+269B ⚛ ATOM SYMBOL` incorporated into them. Their ASCII equivalents are ordinary subroutines, not operators:

```raku
my atomicint $x = 42;
$x⚛++;                # Unicode version
atomic-fetch-inc($x); # ASCII version
```

The ASCII alternatives are as follows:

| Symbol | ASCII | Remarks |
| --- | --- | --- |
| ⚛= | atomic-assign |  |
| ⚛ | atomic-fetch | this is the prefix:<⚛> operator |
| ⚛+= | atomic-add-fetch |  |
| ⚛-= | atomic-sub-fetch |  |
| ⚛−= | atomic-sub-fetch | this operator uses U+2212 minus sign |
| ++⚛ | atomic-inc-fetch |  |
| ⚛++ | atomic-fetch-inc |  |
| --⚛ | atomic-dec-fetch |  |
| ⚛-- | atomic-fetch-dec |  |

# [Multiple codepoints](#Unicode_versus_ASCII_symbols "go to top of document")[§](#Multiple_codepoints "direct link")

This list contains multiple-codepoint operators that require special composition for their ASCII equivalents. Note the codepoints are shown space-separated but should be entered as adjacent codepoints when used.

| Symbol | Codepoints | ASCII | Since | Remarks |
| --- | --- | --- | --- | --- |
| »=» | U+00BB = U+00BB | >>[=]>> | v6.c | uses ASCII '=' |
| «=« | U+00AB = U+00AB | <<[=]<< | v6.c | uses ASCII '=' |
| «=» | U+00AB = U+00BB | <<[=]>> | v6.c | uses ASCII '=' |
| »=« | U+00BB = U+00AB | >>[=]<< | v6.c | uses ASCII '=' |


## dist_github-kmwallio-Lingua-EN-Stopwords.md
# Lingua::EN::Stopwords

Provides methods to see if word is contained in a list of English stop words. [![Build Status](https://travis-ci.org/kmwallio/p6-Lingua-EN-Stopwords.svg?branch=master)](https://travis-ci.org/kmwallio/p6-Lingua-EN-Stopwords)

## Installation

```
panda install Lingua::EN::Stopwords

```

## Usage

```
use Lingua::EN::Stopwords::Short;

# Now we have an array:
say %stop-words;

# We can also check for words
say 'is dog a stop word? ' ~ is-stop-word('dog');

```

Options are Short, Long, and SQL.

## Acknowledgements

* [Ranks NL](http://www.ranks.nl/stopwords) - List of stop words