From 890e919981adc3df084b7c68132aeddc71f8e58e Mon Sep 17 00:00:00 2001 From: Brent Yorgey Date: Fri, 19 Jul 2024 20:59:37 -0400 Subject: [PATCH] write about extensions, and add a bit of info about collections --- docs/reference/bag.rst | 32 +++++++++++++++++- docs/reference/comprehension.rst | 34 +++++++++++++++---- docs/reference/extensions.rst | 56 ++++++++++++++++++++++++++++++++ docs/reference/import.rst | 10 +++--- docs/reference/index.rst | 1 + 5 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 docs/reference/extensions.rst diff --git a/docs/reference/bag.rst b/docs/reference/bag.rst index 4bdaf01f..51fca37b 100644 --- a/docs/reference/bag.rst +++ b/docs/reference/bag.rst @@ -21,7 +21,7 @@ of each element there are. * Notice how single elements are simply listed by themselves, but elements occuring more than once are written with a ``#`` followed - by a natural number. You can write bags this way yourself: + by a natural number (called the *cardinality*). You can write bags this way yourself: :: @@ -100,3 +100,33 @@ Bags support various operations, including :doc:`size `, :doc:`union `, :doc:`intersection `, :doc:`difference `, :doc:`subset `, and :doc:`power set `. +Converting to and from sets +--------------------------- + +Converting a bag to a :doc:`set ` using the ``set`` function +simply discards the cardinalities; converting a set to a bag using +``bag`` results in a bag where every element has cardinality 1. + +However, there is another type of conversion, using the built-in +functions + +* ``bagCounts : Bag(a) -> Set(a * N)`` + +* ``bagFromCounts : Collection(a * N) -> Bag(a)`` + +The ``bagCounts`` function converts a bag into a set of pairs, where +each pair has an element from the bag paired with its cardinality. +For example: + +:: + + Disco> bagCounts(bag "hello world") + {(' ', 1), ('d', 1), ('e', 1), ('h', 1), ('l', 3), ('o', 2), ('r', 1), ('w', 1)} + +The ``bagFromCounts`` function takes any collection of (value, +cardinality) pairs and converts it into a bag. For example: + +:: + + Disco> bagFromCounts [('h', 3), ('i', 2), ('!', 7), ('i',3)] + ⟅'!' # 7, 'h' # 3, 'i' # 5⟆ diff --git a/docs/reference/comprehension.rst b/docs/reference/comprehension.rst index f9ec186d..941bebb4 100644 --- a/docs/reference/comprehension.rst +++ b/docs/reference/comprehension.rst @@ -99,15 +99,35 @@ Specification In case you are curious about the precise definition and are not afraid of the details, the exact way that comprehensions work can be defined by the following three equations, making use of - the standard functions ``each`` and ``join``: + the standard functions :doc:`each ` and ``$join``: * ``{ e | } = e`` - * ``{ e | x in xs, gs } = join(each(\x. {e | gs}, xs))`` + * ``{ e | x in xs, gs } = $join(each(\x. {e | gs}, xs))`` * ``{ e | g, gs } = {? { e | gs } if g, {} otherwise ?}`` - ``join`` is not directly available to users, but: + ``$join`` is not directly available to users, but can be accessed + by enabling the ``Primitives`` :doc:`extension `. In + general, ``$join`` turns a thing-of-things into a thing + (list-of-lists into a list, bag-of-bags into a bag, *etc.*). - - For lists, ``join`` is equivalent to ``concat`` - - For sets, ``join`` is equivalent to ``unions`` - - For bags, ``join`` is equivalent to a straightforward - generalization of ``unions`` to work on bags instead of sets + - For lists, ``$join`` is equivalent to ``concat``. + + :: + + Disco> $join [[1,2,3], [4], [5,6]] + [1, 2, 3, 4, 5, 6] + + - For sets, ``$join`` is equivalent to ``unions``. + + :: + + Disco> $join {{1,2,3}, {2,3,4}, {3,5,6}} + {1, 2, 3, 4, 5, 6} + + - For bags, ``$join`` is equivalent to a straightforward + generalization of ``unions`` to work on bags instead of sets. + + :: + + Disco> $join (bag [bag [1,1,2], bag [1,1,2], bag [2,3,4], bag [2,5,6]]) + ⟅1 # 4, 2 # 4, 3, 4, 5, 6⟆ diff --git a/docs/reference/extensions.rst b/docs/reference/extensions.rst new file mode 100644 index 00000000..cf861aa6 --- /dev/null +++ b/docs/reference/extensions.rst @@ -0,0 +1,56 @@ +Disco language extensions +========================= + +Disco has several *extensions* to the language which enable special +features. These features can be enabled with the syntax + +:: + + using ExtensionName + +where ``ExtensionName`` is the name of the desired extension. Such +``using`` statements must be listed as the *very first thing* in your +``.disco`` file. They can also be entered at the :doc:`REPL `. + +Below is the current list of language extensions and what they do. + +``NoStdLib`` +------------ + +Normally, a standard library of predefined functions is made available +to any Disco module or at the REPL. This extension turns off this +automatic standard library import. + +This is used for technical reasons in a few of the :doc:`library +` modules, but it is not something most users of Disco will +ever need. + +``Primitives`` +-------------- + +Disco has some built-in, primitive functions and operators that are +not normally available to users. These primitives have names that +begin with a ``$``, which would normally be a syntax error: + +:: + + Disco> :type $join + 1:7: + | + 1 | :type $join + | ^^^^^ + unexpected "$join" + +Enabling this extension allows us to access them. + +:: + + Disco> using Primitives + Disco> :type $join + This expression has multiple possible types. Some examples: + $join : List(List(a)) → List(a) + $join : Bag(Bag(a)) → Bag(a) + $join : Set(Set(a)) → Set(a) + +Other primitives include ``$crash``, ``$isPrime``, ``$factor``, +``$unsafeBagFromCounts``, ``$merge``, ``$frac``, and ``$until``. diff --git a/docs/reference/import.rst b/docs/reference/import.rst index 64741c9d..f190c423 100644 --- a/docs/reference/import.rst +++ b/docs/reference/import.rst @@ -15,10 +15,12 @@ Importing a module is done by writing, *e.g.* import num -at the *top* of your ``.disco`` file (or at the :doc:`REPL `). Replace -``num`` with the name of whatever file you want to import (without the -``.disco`` suffix). For example, to import ``myfunctions.disco`` you -could write +at the *very beginning* of your ``.disco`` file (with the exception +that ``import`` must come after any :doc:`using ` +statement). ``import`` can also be used at the :doc:`REPL `. +Replace ``num`` with the name of whatever file you want to import +(without the ``.disco`` suffix). For example, to import +``myfunctions.disco`` you could write :: diff --git a/docs/reference/index.rst b/docs/reference/index.rst index e02fdbaf..8cb5aba9 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -25,5 +25,6 @@ them. combinatorics library REPL + extensions errors symbols