Skip to content

Commit fce0654

Browse files
authored
Additional documentation fixes and updates (#925)
Slowly chipping away at #666
1 parent b5d305b commit fce0654

File tree

8 files changed

+204
-49
lines changed

8 files changed

+204
-49
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
* Fix a bug where reader column offset numbering began at 1, rather than 0 (#905)
2323

2424
### Other
25-
* Add REPL documentation module (#205)
25+
* Add REPL documentation module (#205, #925)
2626
* Add documentation module for Basilisp interfaces (#920)
2727
* Add GitHub source links to generated API documentation (#921)
28+
* Update Concepts documentation module with See Also links for most sections (#925)
2829
* Update Sphinx documentation theme (#909)
2930
* Update documentation to directly reference Python documentation and fix many other minor issues and misspellings (#907, #919)
3031

docs/concepts.rst

Lines changed: 155 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,54 +5,23 @@ Concepts
55

66
.. lpy:currentns:: basilisp.core
77
8-
.. _seqs:
8+
.. _data_structures:
99

10-
Seqs
11-
----
10+
Data Structures
11+
---------------
1212

1313
TBD
1414

15-
.. _macros:
16-
17-
Macros
18-
------
19-
20-
Like many Lisps, Basilisp supports extending its syntax using macros.
21-
Macros are created using the :lpy:fn:`defmacro` macro in :lpy:ns:`basilisp.core`.
22-
Syntax for the macro usage generally matches that of the sibling :lpy:fn:`defn` macro, should be a relatively easy transition.
23-
24-
Once a macro is defined, it is immediately available to the compiler.
25-
You may define a macro and then use it in the next form!
26-
27-
The primary difference between a macro and a standard function is that macros are evaluated *at compile* time and they receive unevaluated expressions, whereas functions are evaluated *at runtime* and arguments will be fully evaluated before being passed to the function.
28-
Macros should return the unevaluated replacement code that should be compiled.
29-
Code returned by macros *must be legal code* -- symbols must be resolvable, functions must have the correct number of arguments, maps must have keys and corresponding values, etc.
30-
31-
Macros created with ``defmacro`` automatically have access to two additional parameters (which *should not* be listed in the macro argument list): ``&env`` and ``&form``.
32-
``&form`` contains the original unevaluated form (including the invocation of the macro itself).
33-
``&env`` contains a mapping of all symbols available to the compiler at the time of macro invocation -- the values are maps representing the binding AST node.
34-
35-
.. note::
36-
37-
Being able to extend the syntax of your language using macros is a powerful feature.
38-
However, with great power comes great responsibility.
39-
Introducing new and unusual syntax to a language can make it harder to onboard new developers and can make code harder to reason about.
40-
Before reaching for macros, ask yourself if the problem can be solved using standard functions first.
15+
.. _seqs:
4116

42-
.. warning::
17+
Seqs
18+
----
4319

44-
Macro writers should take care not to emit any references to :ref:`private_vars` in their macros, as these will not resolve for users outside of the namespace they are defined in, causing compile-time errors.
20+
TBD
4521

4622
.. seealso::
4723

48-
:ref:`syntax_quoting`, :lpy:form:`quote`, :lpy:fn:`gensym`, :lpy:fn:`macroexpand`, :lpy:fn:`macroexpand-1`, :lpy:fn:`unquote`, :lpy:fn:`unquote-splicing`
49-
50-
.. _binding_conveyance:
51-
52-
Binding Conveyance
53-
------------------
54-
55-
TBD
24+
:lpy:fn:`lazy-seq`, :lpy:fn:`seq`, :lpy:fn:`first`, :lpy:fn:`rest`, :lpy:fn:`next`, :lpy:fn:`second`, :lpy:fn:`seq?`, :lpy:fn:`nfirst`, :lpy:fn:`fnext`, :lpy:fn:`nnext`, :lpy:fn:`empty?`, :lpy:fn:`seq?`, :py:class:`basilisp.lang.interfaces.ISeq`
5625

5726
.. _destructuring:
5827

@@ -74,6 +43,10 @@ Destructuring is supported everywhere names are bound: :lpy:form:`fn` argument v
7443

7544
Names without a corresponding element in the data structure (typically due to absence) will bind to ``nil``.
7645

46+
.. seealso::
47+
48+
:lpy:fn:`destructure`
49+
7750
.. _sequential_destructuring:
7851

7952
Sequential Destructuring
@@ -209,58 +182,200 @@ Both associative and sequential destructuring binding forms may be nested within
209182
[a b c e f])
210183
;;=> [1 :b :c 4 5]
211184
185+
.. _macros:
186+
187+
Macros
188+
------
189+
190+
Like many Lisps, Basilisp supports extending its syntax using macros.
191+
Macros are created using the :lpy:fn:`defmacro` macro in :lpy:ns:`basilisp.core`.
192+
Syntax for the macro usage generally matches that of the sibling :lpy:fn:`defn` macro, should be a relatively easy transition.
193+
194+
Once a macro is defined, it is immediately available to the compiler.
195+
You may define a macro and then use it in the next form!
196+
197+
The primary difference between a macro and a standard function is that macros are evaluated *at compile* time and they receive unevaluated expressions, whereas functions are evaluated *at runtime* and arguments will be fully evaluated before being passed to the function.
198+
Macros should return the unevaluated replacement code that should be compiled.
199+
Code returned by macros *must be legal code* -- symbols must be resolvable, functions must have the correct number of arguments, maps must have keys and corresponding values, etc.
200+
201+
Macros created with ``defmacro`` automatically have access to two additional parameters (which *should not* be listed in the macro argument list): ``&env`` and ``&form``.
202+
``&form`` contains the original unevaluated form (including the invocation of the macro itself).
203+
``&env`` contains a mapping of all symbols available to the compiler at the time of macro invocation -- the values are maps representing the binding AST node.
204+
205+
.. note::
206+
207+
Being able to extend the syntax of your language using macros is a powerful feature.
208+
However, with great power comes great responsibility.
209+
Introducing new and unusual syntax to a language can make it harder to onboard new developers and can make code harder to reason about.
210+
Before reaching for macros, ask yourself if the problem can be solved using standard functions first.
211+
212+
.. warning::
213+
214+
Macro writers should take care not to emit any references to :ref:`private_vars` in their macros, as these will not resolve for users outside of the namespace they are defined in, causing compile-time errors.
215+
216+
.. seealso::
217+
218+
:ref:`syntax_quoting`, :lpy:form:`quote`, :lpy:fn:`gensym`, :lpy:fn:`macroexpand`, :lpy:fn:`macroexpand-1`, :lpy:fn:`unquote`, :lpy:fn:`unquote-splicing`
219+
220+
.. _metadata:
221+
222+
Metadata
223+
--------
224+
225+
TBD
226+
227+
.. seealso::
228+
229+
:ref:`Reading metadata on literals <reader_metadata>`, :lpy:fn:`meta`, :lpy:fn:`with-meta`, :lpy:fn:`vary-meta`, :lpy:fn:`alter-meta!`, :lpy:fn:`reset-meta!`
230+
231+
.. _delays:
232+
233+
Delays
234+
------
235+
236+
Delays are containers for deferring expensive computations until such time as the result is needed.
237+
Create a new delay with the :lpy:fn:`delay` macro.
238+
Results will not be computed until you attempt to :lpy:fn:`deref` or :lpy:fn:`force` evaluation.
239+
Once a delay has been evaluated, it caches its results and returns the cached results on subsequent accesses.
240+
241+
.. code-block::
242+
243+
basilisp.user=> (def d (delay (println "evaluating") (+ 1 2 3)))
244+
#'basilisp.user/d
245+
246+
basilisp.user=> d
247+
<basilisp.lang.delay.Delay object at 0x1077803a0>
248+
249+
basilisp.user=> (force d)
250+
evaluating
251+
6
252+
253+
basilisp.user=> (force d)
254+
6
255+
256+
.. seealso::
257+
258+
:lpy:fn:`delay`, :lpy:fn:`delay?`, :lpy:fn:`force`, :lpy:fn:`realized?`, :lpy:fn:`deref`
259+
260+
.. _promises:
261+
262+
Promises
263+
--------
264+
265+
Promises are containers for receiving a deferred result, typically from another thread.
266+
The value of a promise can be written exactly once using :lpy:fn:`deliver`.
267+
Threads may await the results of the promise using a blocking :lpy:fn:`deref` call.
268+
269+
.. seealso::
270+
271+
:lpy:fn:`promise`, :lpy:fn:`deliver`, :lpy:fn:`realized?`, :lpy:fn:`deref`
272+
273+
.. _atoms:
274+
275+
Atoms
276+
-----
277+
278+
TBD
279+
280+
.. seealso::
281+
282+
:lpy:fn:`atom`, :lpy:fn:`compare-and-set!`, :lpy:fn:`reset!`, :lpy:fn:`reset-vals!`, :lpy:fn:`swap!`, :lpy:fn:`swap-vals!`, :lpy:fn:`deref`, :ref:`references_and_refs`
283+
212284
.. _references_and_refs:
213285

214286
References and Refs
215287
-------------------
216288

217289
TBD
218290

291+
.. seealso::
292+
293+
:lpy:fn:`alter-meta!`, :lpy:fn:`reset-meta!`, :lpy:fn:`add-watch`, :lpy:fn:`remove-watch`, :lpy:fn:`get-validator`, :lpy:fn:`set-validator!`
294+
295+
.. _transients:
296+
297+
Transients
298+
----------
299+
300+
TBD
301+
302+
.. seealso::
303+
304+
:lpy:fn:`transient`, :lpy:fn:`persistent!`, :lpy:fn:`assoc!`, :lpy:fn:`conj!`, :lpy:fn:`disj!`, :lpy:fn:`dissoc!`, :lpy:fn:`pop!`
305+
219306
.. _volatiles:
220307

221308
Volatiles
222309
---------
223310

224311
TBD
225312

313+
.. seealso::
314+
315+
:lpy:fn:`volatile!`, :lpy:fn:`volatile?`, :lpy:fn:`vreset!`, :lpy:fn:`vswap!`
316+
226317
.. _transducers:
227318

228319
Transducers
229320
-----------
230321

231322
TBD
232323

324+
.. seealso::
325+
326+
:lpy:fn:`eduction`, :lpy:fn:`completing`, :lpy:fn:`halt-when`, :lpy:fn:`sequence`, :lpy:fn:`transduce`, :lpy:fn:`into`, :lpy:fn:`cat`
327+
233328
.. _hierarchies:
234329

235330
Hierarchies
236331
-----------
237332

238333
TBD
239334

335+
.. seealso::
336+
337+
:lpy:fn:`make-hierarchy`, :lpy:fn:`ancestors`, :lpy:fn:`descendents`, :lpy:fn:`parents`, :lpy:fn:`isa?`, :lpy:fn:`derive`, :lpy:fn:`underive`
338+
240339
.. _multimethods:
241340

242341
Multimethods
243342
------------
244343

245344
TBD
246345

346+
.. seealso::
347+
348+
:lpy:fn:`defmulti`, :lpy:fn:`defmethod`, :lpy:fn:`methods`, :lpy:fn:`get-method`, :lpy:fn:`prefer-method`, :lpy:fn:`prefers`, :lpy:fn:`remove-method`, :lpy:fn:`remove-all-methods`
349+
247350
.. _protocols:
248351

249352
Protocols
250353
---------
251354

252355
TBD
253356

357+
.. seealso::
358+
359+
:lpy:fn:`defprotocol`, :lpy:fn:`protocol?`, :lpy:fn:`extend`, :lpy:fn:`extend-protocol`, :lpy:fn:`extend-type`, :lpy:fn:`extenders`, :lpy:fn:`extends?`, :lpy:fn:`satisfies?`
360+
254361
.. _data_types:
255362

256363
Data Types
257364
----------
258365

259366
TBD
260367

368+
.. seealso::
369+
370+
:lpy:fn:`deftype`
371+
261372
.. _records:
262373

263374
Records
264375
-------
265376

266-
TBD
377+
TBD
378+
379+
.. seealso::
380+
381+
:ref:`records` , :lpy:fn:`defrecord` , :lpy:fn:`record?`

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Contents
2525
features
2626
gettingstarted
2727
differencesfromclojure
28+
concepts
2829
reference
2930
releasenotes
3031
contributing

docs/reader.rst

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ The Basilisp reader performs a job which is a combination of the traditional lex
1111
The reader takes a file or string and produces a stream of Basilisp data structures.
1212
Typically the reader streams its results to the compiler, but end-users may also take advantage of the reader directly from within Basilisp.
1313

14-
.. contents:: Reader Literals
15-
:depth: 2
16-
1714
.. _numeric_literals:
1815

1916
Numeric Literals
@@ -356,7 +353,7 @@ All of the text to the end of the line are ignored.
356353

357354
For a convenience in writing shell scripts with Basilisp, the standard \*NIX `shebang <https://en.wikipedia.org/wiki/Shebang_(Unix)>`_ (``#!``) is also treated as a single-line comment.
358355

359-
.. _metadata:
356+
.. _reader_metadata:
360357

361358
Metadata
362359
--------
@@ -380,6 +377,10 @@ Metadata applied to a form must be one of: :ref:`maps`, :ref:`symbols`, :ref:`ke
380377
* Keyword metadata will be normalized to a Map with the keyword as the key with the value of ``true``.
381378
* Map metadata will not be modified when it is read.
382379

380+
.. seealso::
381+
382+
:ref:`metadata`
383+
383384
.. _reader_macros:
384385

385386
Reader Macros
@@ -462,6 +463,10 @@ In nearly all cases, this will be the return value from a macro function, which
462463

463464
Using any of these special syntax quoting characters outside of a syntax quote context will result in a compiler error.
464465

466+
.. seealso::
467+
468+
:ref:`macros`
469+
465470
.. _reader_conditions:
466471

467472
Reader Conditionals

docs/reference.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,5 @@ Reference
1313
specialforms
1414
pyinterop
1515
runtime
16-
concepts
1716
testing
1817
compiler

docs/repl.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,27 @@ This namespace includes some utilities for introspecting the runtime environment
6565

6666
:lpy:fn:`require`, :lpy:fn:`refer`, :lpy:fn:`use`
6767

68+
.. _taps:
69+
70+
Taps
71+
^^^^
72+
73+
Basilisp supports the concept of "taps" as a convenient, non-blocking method of monitoring the operation of some function at runtime.
74+
Taps are implemented as a simple in-process publish/subscribe mechanism.
75+
Users can add tap functions using :lpy:fn:`add-tap` which subscribe to a topic (typically a keyword) or which use the default ``:basilisp.core.tap/default``.
76+
Functions can then emit tap events at runtime into the queue using :lpy:fn:`tap>` with a topic and a background thread will call any tap functions which have subscribed to the topic.
77+
Taps can be removed using :lpy:fn:`remove-tap`.
78+
79+
.. warning::
80+
81+
The background thread uses a :external:py:class:`queue.Queue` to store and process its results.
82+
The queue size is limited to 1024 items by default to avoid excessive memory consumption.
83+
Users can configure the queue size by setting the environment variable ``BASILISP_TAP_QUEUE_SIZE`` to an integer value.
84+
85+
.. seealso::
86+
87+
:lpy:fn:`tap>`, :lpy:fn:`add-tap`, :lpy:fn:`remove-tap`
88+
6889
.. _repl_creature_comforts:
6990

7091
Creature Comforts

docs/runtime.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,20 @@ Note that this functionality already exists as :lpy:fn:`with-out-str`, but it se
152152

153153
.. seealso::
154154

155-
:lpy:fn:`binding`, :lpy:fn:`bound-fn`, :lpy:fn:`bound-fn*`, :lpy:fn:`get-thread-bindings`, :lpy:fn:`pop-thread-bindings`, :lpy:fn:`push-thread-bindings`, :lpy:fn:`with-bindings`, :lpy:fn:`with-bindings*`
155+
:lpy:fn:`binding`
156+
157+
158+
.. _binding_conveyance:
159+
160+
Binding Conveyance
161+
##################
162+
163+
Basilisp supports the concept of "binding conveyance" which allows copying the active set of dynamic Var bindings in the current thread when submitting work to another thread.
164+
Both :lpy:fn:`future` and :lpy:fn:`pmap` support this feature natively.
165+
166+
.. seealso::
167+
168+
:lpy:fn:`bound-fn`, :lpy:fn:`bound-fn*`, :lpy:fn:`get-thread-bindings`, :lpy:fn:`pop-thread-bindings`, :lpy:fn:`push-thread-bindings`, :lpy:fn:`with-bindings`, :lpy:fn:`with-bindings*`
156169

157170
.. _private_vars:
158171

0 commit comments

Comments
 (0)