<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://halfgeek.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Graut%2FStandard_library</id>
	<title>Graut/Standard library - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://halfgeek.org/wiki/index.php?action=history&amp;feed=atom&amp;title=Graut%2FStandard_library"/>
	<link rel="alternate" type="text/html" href="https://halfgeek.org/wiki/index.php?title=Graut/Standard_library&amp;action=history"/>
	<updated>2026-05-28T12:05:24Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.0</generator>
	<entry>
		<id>https://halfgeek.org/wiki/index.php?title=Graut/Standard_library&amp;diff=2261&amp;oldid=prev</id>
		<title>Psmay: /* Namespace SYSTEM */</title>
		<link rel="alternate" type="text/html" href="https://halfgeek.org/wiki/index.php?title=Graut/Standard_library&amp;diff=2261&amp;oldid=prev"/>
		<updated>2015-03-23T16:11:52Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Namespace SYSTEM&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Built-in functions==&lt;br /&gt;
&lt;br /&gt;
===Namespace &amp;lt;code&amp;gt;SYSTEM&amp;lt;/code&amp;gt;===&lt;br /&gt;
&lt;br /&gt;
Each of these exists in the &amp;lt;code&amp;gt;SYSTEM&amp;lt;/code&amp;gt; namespace, such that a builtin named &amp;lt;code&amp;gt;&amp;#039;&amp;#039;name&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; could be called using &amp;lt;code&amp;gt;$(SYSTEM &amp;#039;&amp;#039;name&amp;#039;&amp;#039;)&amp;lt;/code&amp;gt;. This namespace is normally implicit, but can be explicitly referenced if necessary. This documentation presumes that this namespace is still implicit for all names.&lt;br /&gt;
&lt;br /&gt;
====cat====&lt;br /&gt;
&lt;br /&gt;
 #(cat &amp;#039;&amp;#039;expr&amp;#039;&amp;#039; &amp;#039;&amp;#039;expr&amp;#039;&amp;#039; ...)&lt;br /&gt;
&lt;br /&gt;
Coerces each &amp;#039;&amp;#039;expr&amp;#039;&amp;#039; to a string value, then returns the results concatenated as a string.&lt;br /&gt;
&lt;br /&gt;
====choose====&lt;br /&gt;
&lt;br /&gt;
 #(choose (&amp;#039;&amp;#039;cond&amp;#039;&amp;#039; &amp;#039;&amp;#039;exprt&amp;#039;&amp;#039;)+ &amp;#039;&amp;#039;exprf?&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Evaluates each of the supplied &amp;#039;&amp;#039;cond&amp;#039;&amp;#039; until the first that returns true, then returns that condition&amp;#039;s &amp;#039;&amp;#039;exprt&amp;#039;&amp;#039;. If no condition evaluates to true, returns &amp;#039;&amp;#039;exprf&amp;#039;&amp;#039; (which defaults to &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
====def====&lt;br /&gt;
&lt;br /&gt;
 #(def &amp;#039;&amp;#039;key&amp;#039;&amp;#039; &amp;#039;&amp;#039;value&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Bind &amp;lt;code&amp;gt;$&amp;#039;&amp;#039;key&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;, for the extent of the current scope, to resolve to &amp;lt;code&amp;gt;&amp;#039;&amp;#039;value&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;. Return empty string.&lt;br /&gt;
&lt;br /&gt;
Error if the same key has already been set for this scope (not for an enclosing scope).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Note:&amp;#039;&amp;#039;&amp;#039; In early drafts this is sometimes called &amp;lt;code&amp;gt;#(= ...)&amp;lt;/code&amp;gt;. That function is now used exclusively for numeric comparisons.&lt;br /&gt;
&lt;br /&gt;
====element====&lt;br /&gt;
&lt;br /&gt;
 #(element &amp;#039;&amp;#039;index&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;) -&amp;gt; #(head #(skip &amp;#039;&amp;#039;index&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
====extract====&lt;br /&gt;
&lt;br /&gt;
 #(extract &amp;#039;&amp;#039;extractspec&amp;#039;&amp;#039; &amp;#039;&amp;#039;value&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Similar to &amp;lt;code&amp;gt;def&amp;lt;/code&amp;gt;, but performs a destructuring assignment. An &amp;#039;&amp;#039;&amp;#039;extract spec&amp;#039;&amp;#039;&amp;#039; is either an atom or a list of zero or more extract specs. Each atom indicates a name in the current scope. For example, the result of&lt;br /&gt;
&lt;br /&gt;
 #(extract (alpha (bravo (charlie))) (1 (2 (3))))&lt;br /&gt;
&lt;br /&gt;
is equivalent to the result of&lt;br /&gt;
&lt;br /&gt;
 #(def alpha 1)#(def bravo 2)#(def charlie 3)&lt;br /&gt;
&lt;br /&gt;
=====Discard by assigning to empty=====&lt;br /&gt;
&lt;br /&gt;
The empty atom may be specified multiple times and any values assigned to the empty atom is discarded; this can be used for partial destructuring. For example, the result of&lt;br /&gt;
&lt;br /&gt;
 #(extract (&amp;quot;&amp;quot; (bravo (&amp;quot;&amp;quot;))) (1 (2 (3))))&lt;br /&gt;
&lt;br /&gt;
is equivalent to the result of&lt;br /&gt;
&lt;br /&gt;
 #(def bravo 2)&lt;br /&gt;
&lt;br /&gt;
=====No non-atom keys can be assigned=====&lt;br /&gt;
&lt;br /&gt;
Only atoms indicate values that can be assigned, so a definition of a list-like key such as&lt;br /&gt;
&lt;br /&gt;
 #(def (mike november) 123)&lt;br /&gt;
&lt;br /&gt;
has no equivalent extract spec.&lt;br /&gt;
&lt;br /&gt;
====false====&lt;br /&gt;
&lt;br /&gt;
 #(false) -&amp;gt; #( $((SYSTEM boolean) parse-canonical) false )&lt;br /&gt;
&lt;br /&gt;
Returns a false value.&lt;br /&gt;
&lt;br /&gt;
====filter====&lt;br /&gt;
&lt;br /&gt;
 #(filter &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;function&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns a new list collected by including only elements for which &amp;lt;code&amp;gt;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; returns true.&lt;br /&gt;
&lt;br /&gt;
====flat-for====&lt;br /&gt;
&lt;br /&gt;
 #(flat-for &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;function&amp;#039;&amp;#039;) -&amp;gt; #(flatten #(for &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;function&amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
====flatten====&lt;br /&gt;
&lt;br /&gt;
 #(flatten &amp;#039;&amp;#039;lists&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns a single list containing the immediate top-level elements of all parameters. Error if any parameter is not resolvable to a list.&lt;br /&gt;
&lt;br /&gt;
Similar to &amp;lt;code&amp;gt;#(stream ...)&amp;lt;/code&amp;gt;, but all expressions are evaluated immediately. However, expressions that resolve to streams will not be strictly evaluated; the result of this function is itself a stream if one of the lists is a stream.&lt;br /&gt;
&lt;br /&gt;
====for====&lt;br /&gt;
&lt;br /&gt;
 #(for &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;function&amp;#039;&amp;#039;)&lt;br /&gt;
 // i.e.&lt;br /&gt;
 #(for &amp;#039;&amp;#039;list&amp;#039;&amp;#039; #(func (&amp;#039;&amp;#039;paramname&amp;#039;&amp;#039;) &amp;#039;&amp;#039;expr-using-param&amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
Map function; returns a new list collected by applying &amp;lt;code&amp;gt;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; to each element of &amp;lt;code&amp;gt;&amp;#039;&amp;#039;list&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If &amp;#039;&amp;#039;list&amp;#039;&amp;#039; is a stream, then the result is a stream as well.&lt;br /&gt;
&lt;br /&gt;
====force====&lt;br /&gt;
&lt;br /&gt;
 #(force &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns, as a list, the elements of &amp;#039;&amp;#039;list&amp;#039;&amp;#039; after having been strictly evaluated. If &amp;#039;&amp;#039;list&amp;#039;&amp;#039; is already a plain list, then it is returned. If &amp;#039;&amp;#039;list&amp;#039;&amp;#039; is a stream, a list is returned containing each of its elements as strictly evaluated.&lt;br /&gt;
&lt;br /&gt;
Note that an infinitely-long stream will cause this never to return. To force the first &amp;#039;&amp;#039;n&amp;#039;&amp;#039; elements of a stream, call &amp;lt;code&amp;gt;#(force #(take &amp;#039;&amp;#039;n&amp;#039;&amp;#039; &amp;#039;&amp;#039;stream&amp;#039;&amp;#039;))&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====func====&lt;br /&gt;
&lt;br /&gt;
 #(func (&amp;#039;&amp;#039;paramspec&amp;#039;&amp;#039;) &amp;#039;&amp;#039;preexpr&amp;#039;&amp;#039;* &amp;#039;&amp;#039;expr&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns an anonymous function that can be used as the first element of a function call list. The produced function accepts the parameters named by &amp;lt;code&amp;gt;&amp;#039;&amp;#039;paramspec&amp;#039;&amp;#039;&amp;lt;/code&amp;gt;, and returns the result of evaluating &amp;lt;code&amp;gt;&amp;#039;&amp;#039;expr&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; with the parameters in lexical scope.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;paramspec&amp;#039;&amp;#039; is an extract spec. When the function is called, the parameters given are assigned as if by &amp;lt;code&amp;gt;#(extract ...)&amp;lt;/code&amp;gt;. For example, after defining examplefn as&lt;br /&gt;
&lt;br /&gt;
 #(def examplefn #(func (alpha (bravo &amp;quot;&amp;quot;) charlie) #(do-something-with $alpha $bravo $charlie)))&lt;br /&gt;
&lt;br /&gt;
calling&lt;br /&gt;
&lt;br /&gt;
 #(examplefn 10 (20 30) 40)&lt;br /&gt;
&lt;br /&gt;
would produce the same result as&lt;br /&gt;
&lt;br /&gt;
 #(do-something-with 10 20 40)&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;preexpr&amp;#039;&amp;#039; are expressions evaluated before &amp;#039;&amp;#039;expr&amp;#039;&amp;#039;. Their results are discarded, so it is only really meaningful to use expressions with side effect here (in particular, local definitions such as &amp;lt;code&amp;gt;#(def ...)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;#(extract ...)&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Values returned by this function are (objects) in the namespace &amp;lt;code&amp;gt;(SYSTEM function)&amp;lt;/code&amp;gt;. They cannot be serialized as keys.&lt;br /&gt;
&lt;br /&gt;
====head====&lt;br /&gt;
&lt;br /&gt;
 #(head &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns the first element of &amp;#039;&amp;#039;list&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
If &amp;#039;&amp;#039;list&amp;#039;&amp;#039; is empty, this produces an error.&lt;br /&gt;
&lt;br /&gt;
====if====&lt;br /&gt;
&lt;br /&gt;
 #(if &amp;#039;&amp;#039;cond&amp;#039;&amp;#039; &amp;#039;&amp;#039;exprt&amp;#039;&amp;#039; &amp;#039;&amp;#039;exprf?&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns &amp;#039;&amp;#039;exprt&amp;#039;&amp;#039; if &amp;#039;&amp;#039;cond&amp;#039;&amp;#039; evaluates true or &amp;#039;&amp;#039;exprf&amp;#039;&amp;#039; otherwise.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;exprf&amp;#039;&amp;#039; is optional and defaults to &amp;lt;code&amp;gt;()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====import====&lt;br /&gt;
&lt;br /&gt;
 #(import &amp;#039;&amp;#039;namespace&amp;#039;&amp;#039;)&lt;br /&gt;
 #(import &amp;#039;&amp;#039;namespace&amp;#039;&amp;#039; &amp;#039;&amp;#039;name+&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
====int====&lt;br /&gt;
&lt;br /&gt;
 #(int 10) -&amp;gt; #($((SYSTEM number) parse-canonical) 10 1)&lt;br /&gt;
 #(int &amp;#039;&amp;#039;atom&amp;#039;&amp;#039;) -&amp;gt; #(int &amp;#039;&amp;#039;atom&amp;#039;&amp;#039; #(int 10))&lt;br /&gt;
 #(int &amp;#039;&amp;#039;atom&amp;#039;&amp;#039; &amp;#039;&amp;#039;radix&amp;#039;&amp;#039;)&lt;br /&gt;
   -&amp;gt; #(int &amp;#039;&amp;#039;atom&amp;#039;&amp;#039; #(int &amp;#039;&amp;#039;radix&amp;#039;&amp;#039; #(int 10))) if &amp;#039;&amp;#039;radix&amp;#039;&amp;#039; is not already an integer&lt;br /&gt;
 #(int &amp;#039;&amp;#039;number&amp;#039;&amp;#039;) -&amp;gt; &amp;#039;&amp;#039;number&amp;#039;&amp;#039; iff its denominator value is 1&lt;br /&gt;
&lt;br /&gt;
Parses &amp;#039;&amp;#039;atom&amp;#039;&amp;#039; to an integer value, failing if the value does not look like an integer.&lt;br /&gt;
&lt;br /&gt;
In this discussion, an &amp;#039;&amp;#039;integer value&amp;#039;&amp;#039; refers to any number value whose denominator part is 1.&lt;br /&gt;
&lt;br /&gt;
* Whitespace is allowed at the start, at the end, and/or between the sign and the digits.&lt;br /&gt;
* Zero may have a negative sign (the sign is ignored).&lt;br /&gt;
* After the first digit, the first non-digit and all following characters, if any, are truncated.&lt;br /&gt;
* Digits are matched case-insensitively (for radix &amp;amp;gt; 10, e.g. &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;a&amp;lt;/code&amp;gt; have the same value).&lt;br /&gt;
&lt;br /&gt;
This corresponds with the pattern:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=Perl&amp;gt;&lt;br /&gt;
/^\s*(-\s*)?([$digits]+)/i&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;radix&amp;#039;&amp;#039; parameter, if not already an integer value, is converted to one using &amp;lt;code&amp;gt;#(int ...)&amp;lt;/code&amp;gt;. Its value must be in 2 .. 36. The digit class consists of the first &amp;#039;&amp;#039;radix&amp;#039;&amp;#039; characters of the string:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=JavaScript&amp;gt;&lt;br /&gt;
&amp;quot;0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of each digit is equal to its zero-based index in that string (matched case-insensitively).&lt;br /&gt;
&lt;br /&gt;
If a number is passed instead of an atom, the result is either the number itself (if already an integer) or the quotient of its numerator to its denominator truncated toward zero (e.g. 2.9 would round to 2.0 while -2.9 would round to -2.0).&lt;br /&gt;
&lt;br /&gt;
====is-function====&lt;br /&gt;
&lt;br /&gt;
 #(is-function &amp;#039;&amp;#039;expr&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns true iff the expression looks enough like a function that it could be called as one.&lt;br /&gt;
&lt;br /&gt;
This returns true for all return values of &amp;lt;code&amp;gt;#(func ...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
This function does not perform any lookup; for example, even though these are normally equivalent:&lt;br /&gt;
&lt;br /&gt;
 #(nop sometext)&lt;br /&gt;
 #($(SYSTEM nop) sometext)&lt;br /&gt;
&lt;br /&gt;
The following are not:&lt;br /&gt;
&lt;br /&gt;
 #(is-function nop) -&amp;gt; false (&amp;quot;nop&amp;quot; is a string value)&lt;br /&gt;
 #(is-function $(SYSTEM nop)) -&amp;gt; true ($(SYSTEM nop) resolves to a function)&lt;br /&gt;
&lt;br /&gt;
====length====&lt;br /&gt;
&lt;br /&gt;
 #(length &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns, as if via &amp;lt;code&amp;gt;#(int...)&amp;lt;/code&amp;gt;, the number of elements in the given list.&lt;br /&gt;
&lt;br /&gt;
Note that it is possible for a list to be of infinite length; this function should only be used on finite lists.&lt;br /&gt;
&lt;br /&gt;
====lookup====&lt;br /&gt;
&lt;br /&gt;
 #(lookup &amp;#039;&amp;#039;name&amp;#039;&amp;#039;)&lt;br /&gt;
 #(lookup &amp;#039;&amp;#039;name&amp;#039;&amp;#039; &amp;#039;&amp;#039;test-function&amp;#039;&amp;#039;)&lt;br /&gt;
 // i.e.&lt;br /&gt;
 #(lookup &amp;#039;&amp;#039;name&amp;#039;&amp;#039; #(func (&amp;#039;&amp;#039;fullname&amp;#039;&amp;#039;) &amp;#039;&amp;#039;boolean-expr-using-fullname&amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
Determines whether the given name is available in the lookup path; if so, a list containing the qualified name is returned; otherwise, the empty list is returned instead.&lt;br /&gt;
&lt;br /&gt;
If &amp;#039;&amp;#039;test-function&amp;#039;&amp;#039; is provided, a found name will not be returned unless the function, passed the qualified name, returns true. This can be used, for example, to test the next match if the first match is not of the right type.&lt;br /&gt;
&lt;br /&gt;
The namespaces searched by this operation are determined by &amp;lt;code&amp;gt;#(import ...)&amp;lt;/code&amp;gt;. The lookup path begins as containing only the namespace &amp;lt;code&amp;gt;SYSTEM&amp;lt;/code&amp;gt;; for example, if no &amp;lt;code&amp;gt;#(import ...)&amp;lt;/code&amp;gt; has been run, the call &amp;lt;code&amp;gt;#(lookup nop)&amp;lt;/code&amp;gt; would return &amp;lt;code&amp;gt;(SYSTEM nop)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====nonces====&lt;br /&gt;
&lt;br /&gt;
 #(nonces &amp;#039;&amp;#039;nonce&amp;#039;&amp;#039;)&lt;br /&gt;
 // e.g.&lt;br /&gt;
 #(nonces $)&lt;br /&gt;
&lt;br /&gt;
Using a nonce as a basis, returns a stream (an arbitrarily long list) of nonce values. The sequence of values in the stream is always the same for a given input nonce.&lt;br /&gt;
&lt;br /&gt;
====nop====&lt;br /&gt;
&lt;br /&gt;
 #(nop &amp;#039;&amp;#039;comments&amp;#039;&amp;#039;)&lt;br /&gt;
 #()&lt;br /&gt;
&lt;br /&gt;
Returns the empty string without attempting to resolve any of the arguments. To be used for comments (e.g. in a triple-quoted string).&lt;br /&gt;
&lt;br /&gt;
====not====&lt;br /&gt;
&lt;br /&gt;
 #(not &amp;#039;&amp;#039;cond&amp;#039;&amp;#039;) -&amp;gt; #(if &amp;#039;&amp;#039;cond&amp;#039;&amp;#039; #(false) #(true))&lt;br /&gt;
&lt;br /&gt;
Returns the boolean inverse of &amp;#039;&amp;#039;cond&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
====num====&lt;br /&gt;
&lt;br /&gt;
 #(num &amp;#039;&amp;#039;atom&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Converts a string in a traditional/JSON-like floating-point format to a rational number.&lt;br /&gt;
&lt;br /&gt;
If the string contains a single &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, the string is split at that character and each side is parsed individually, and the result is the rational whose numerator is the left-side result and whose denominator is the right-side result. This fails if the right side evaluates to 0.&lt;br /&gt;
&lt;br /&gt;
If the string contains multiple &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, this fails.&lt;br /&gt;
&lt;br /&gt;
If the string contains no &amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt;, the expected format, after ignoring leading and trailing whitespace, is that of JSON&amp;#039;s &amp;quot;number&amp;quot; rule or a superset thereof.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=perl&amp;gt;&lt;br /&gt;
# JSON number format&lt;br /&gt;
/^&lt;br /&gt;
	( - )?			# sign (opt)&lt;br /&gt;
	( (0 | [1-9][0-9]*) )	# int part (req)&lt;br /&gt;
	( \. [0-9]+ )?		# frac part (opt)&lt;br /&gt;
	( [Ee][+-]? [0-9]+ )?	# exp part (opt)&lt;br /&gt;
$/x&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After separating a floating-point value into the component parts:&lt;br /&gt;
&lt;br /&gt;
* Let &amp;#039;&amp;#039;s&amp;#039;&amp;#039; = the sign coefficient, being -1 if a negative sign is present or 1 otherwise&lt;br /&gt;
* Let &amp;#039;&amp;#039;m&amp;#039;&amp;#039; = the string of digits before the fractional point (or all digits of the significand, if there is no fractional point)&lt;br /&gt;
* Let &amp;#039;&amp;#039;n&amp;#039;&amp;#039; = the string of digits after the fractional point (or the empty string, if there is no fractional point)&lt;br /&gt;
* Let &amp;#039;&amp;#039;e&amp;#039;&amp;#039; = the integer value of the exponent (or 0, if there is no exponent)&lt;br /&gt;
&lt;br /&gt;
and noting the environment:&lt;br /&gt;
&lt;br /&gt;
* Let &amp;#039;&amp;#039;b&amp;#039;&amp;#039; be the base (radix) in which &amp;#039;&amp;#039;m&amp;#039;&amp;#039; and &amp;#039;&amp;#039;n&amp;#039;&amp;#039; are defined.&lt;br /&gt;
&lt;br /&gt;
find &amp;#039;&amp;#039;num&amp;#039;&amp;#039; and &amp;#039;&amp;#039;den&amp;#039;&amp;#039;:&lt;br /&gt;
&lt;br /&gt;
* Let &amp;#039;&amp;#039;e&amp;#039;&amp;#039;&amp;amp;#x2032; = &amp;#039;&amp;#039;e&amp;#039;&amp;#039; ‌- length(&amp;#039;&amp;#039;n&amp;#039;&amp;#039;), where length(&amp;#039;&amp;#039;n&amp;#039;&amp;#039;) = number of digits in &amp;#039;&amp;#039;n&amp;#039;&amp;#039;. (This is the exponent after the point is shifted off the right.)&lt;br /&gt;
* Let &amp;#039;&amp;#039;z&amp;#039;&amp;#039; = A string of max(0, &amp;#039;&amp;#039;e&amp;#039;&amp;#039;&amp;amp;#x2032;‌) zeroes.&lt;br /&gt;
* Let &amp;#039;&amp;#039;e&amp;amp;#x2033;&amp;#039;&amp;#039; = min(0, &amp;#039;&amp;#039;e&amp;#039;&amp;#039;&amp;amp;#x2032;‌). (This is the exponent after the zero padding.)&lt;br /&gt;
* Then &amp;#039;&amp;#039;num&amp;#039;&amp;#039; = (&amp;#039;&amp;#039;s&amp;#039;&amp;#039;)(|&amp;#039;&amp;#039;num&amp;#039;&amp;#039;|), where |&amp;#039;&amp;#039;num&amp;#039;&amp;#039;| = (&amp;#039;&amp;#039;m&amp;#039;&amp;#039; ⋅ &amp;#039;&amp;#039;n&amp;#039;&amp;#039; ⋅ &amp;#039;&amp;#039;z&amp;#039;&amp;#039;) (i.e., concatenated) as interpreted as an integer in base-&amp;#039;&amp;#039;b&amp;#039;&amp;#039;.&lt;br /&gt;
* Then &amp;#039;&amp;#039;den&amp;#039;&amp;#039; = &amp;#039;&amp;#039;b&amp;#039;&amp;#039;&amp;lt;sup&amp;gt;&amp;#039;&amp;#039;e&amp;#039;&amp;#039;&amp;amp;#x2033;&amp;lt;/sup&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The resulting number is then the ratio of &amp;#039;&amp;#039;num&amp;#039;&amp;#039; to &amp;#039;&amp;#039;den&amp;#039;&amp;#039; (which is sign-corrected but not necessarily in lowest terms).&lt;br /&gt;
&lt;br /&gt;
The adjustments in this computation first ensure that the significand is an integer by shifting the fractional point off the right, then ensure that the exponent is no greater than zero (i.e., that the denominator will not be a fraction) by zero-padding the significand on the right if the exponent is positive. After these steps, the candidate numerator and denominator are both integers.&lt;br /&gt;
&lt;br /&gt;
====set-and====&lt;br /&gt;
&lt;br /&gt;
 #(set-and &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ...)&lt;br /&gt;
&lt;br /&gt;
Produces a new list containing each distinct element that appears in all given lists. The resulting list is in [[#set-normal|set-normal]] form.&lt;br /&gt;
&lt;br /&gt;
====set-normal====&lt;br /&gt;
&lt;br /&gt;
 #(set-normal &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Produces a new list containing each distinct element in &amp;#039;&amp;#039;list&amp;#039;&amp;#039; exactly once and in a deterministic order. The elements of the list are normalized to keys for ordering, and the resulting list contains the elements in their normalized forms.&lt;br /&gt;
&lt;br /&gt;
Implementation note: It might be wise to have a bit on the resulting list structure specifying that this list is set-normal, so that repeat calls on the same list become no-ops.&lt;br /&gt;
&lt;br /&gt;
====set-or====&lt;br /&gt;
&lt;br /&gt;
 #(set-or &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ...)&lt;br /&gt;
&lt;br /&gt;
Produces a new list containing each distinct element that appears in any given list. The resulting list is in [[#set-normal|set-normal]] form.&lt;br /&gt;
&lt;br /&gt;
====skip====&lt;br /&gt;
&lt;br /&gt;
 #(skip &amp;#039;&amp;#039;count&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Return the list consisting of all items after the first &amp;#039;&amp;#039;count&amp;#039;&amp;#039; of &amp;#039;&amp;#039;list&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;count&amp;#039;&amp;#039; is converted as if by &amp;lt;code&amp;gt;#(int ...)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A negative count produces an error.&lt;br /&gt;
&lt;br /&gt;
A count greater than the length of the list produces an empty list.&lt;br /&gt;
&lt;br /&gt;
A count of 0 produces &amp;#039;&amp;#039;list&amp;#039;&amp;#039; itself.&lt;br /&gt;
&lt;br /&gt;
====skip-while====&lt;br /&gt;
&lt;br /&gt;
 #(skip-while &amp;#039;&amp;#039;testfunc&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Return the sequence consisting of all elements at or after the first element for which &amp;lt;code&amp;gt;#(&amp;#039;&amp;#039;testfunc&amp;#039;&amp;#039; &amp;#039;&amp;#039;element&amp;#039;&amp;#039;)&amp;lt;/code&amp;gt; has a false result. The returned sequence is a stream. Note that strictly evaluating this stream results in an infinite loop if &amp;#039;&amp;#039;list&amp;#039;&amp;#039; is itself an infinite stream containing only values for which the test returns true.&lt;br /&gt;
&lt;br /&gt;
====stream====&lt;br /&gt;
&lt;br /&gt;
 #(stream &amp;#039;&amp;#039;list-expressions&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Returns a stream, which is a lazily evaluated list. The result is similar to &amp;lt;code&amp;gt;#(flatten ...)&amp;lt;/code&amp;gt;, except the expressions themselves are not evaluated until needed.&lt;br /&gt;
&lt;br /&gt;
For example, in the following, &amp;lt;code&amp;gt;#(zip-with ...)&amp;lt;/code&amp;gt; is not called at all unless some element of index 2 or higher is strictly evaluated. (And &amp;lt;code&amp;gt;#(zip-with ...)&amp;lt;/code&amp;gt; itself produces a stream.)&lt;br /&gt;
&lt;br /&gt;
 #(def fib&lt;br /&gt;
   #( stream (1 1) #(zip-with $fib #(tail $fib) #(func (a b) #(+ $a $b))) )&lt;br /&gt;
 )&lt;br /&gt;
&lt;br /&gt;
====tail====&lt;br /&gt;
&lt;br /&gt;
 #(tail &amp;#039;&amp;#039;list&amp;#039;&amp;#039;) -&amp;gt; #(skip 1 &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
====take====&lt;br /&gt;
&lt;br /&gt;
 #(take &amp;#039;&amp;#039;count&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Return the list consisting of the first &amp;#039;&amp;#039;count&amp;#039;&amp;#039; items of &amp;#039;&amp;#039;list&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
A negative count produces an error.&lt;br /&gt;
&lt;br /&gt;
A count greater than the length of the list produces &amp;#039;&amp;#039;list&amp;#039;&amp;#039; itself.&lt;br /&gt;
&lt;br /&gt;
A count of 0 produces an empty list.&lt;br /&gt;
&lt;br /&gt;
====take-while====&lt;br /&gt;
&lt;br /&gt;
 #(take-while &amp;#039;&amp;#039;testfunc&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
Return the sequence consisting of all leading elements for which &amp;lt;code&amp;gt;#(&amp;#039;&amp;#039;testfunc&amp;#039;&amp;#039; &amp;#039;&amp;#039;element&amp;#039;&amp;#039;)&amp;lt;/code&amp;gt; has a true result, ending either immediately before the first element for which the function returns false or at the end of the source, whichever comes first. The returned sequence is a stream.&lt;br /&gt;
&lt;br /&gt;
====true====&lt;br /&gt;
&lt;br /&gt;
 #(true) -&amp;gt; #( $((SYSTEM boolean) parse-canonical) true )&lt;br /&gt;
&lt;br /&gt;
Returns a true value.&lt;br /&gt;
&lt;br /&gt;
====zip====&lt;br /&gt;
&lt;br /&gt;
 #(zip &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ...) -&amp;gt; // If zip is in terms of zip-with&lt;br /&gt;
   #(zip-with &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ... #(func (&amp;#039;&amp;#039;elem&amp;#039;&amp;#039; &amp;#039;&amp;#039;elem&amp;#039;&amp;#039; ...) ($&amp;#039;&amp;#039;elem&amp;#039;&amp;#039; $&amp;#039;&amp;#039;elem&amp;#039;&amp;#039; ...)))&lt;br /&gt;
&lt;br /&gt;
Returns a new list collected by traversing all given lists in parallel and collecting the cross-section into a list at each element. Traversal ends at the end of the shortest list.&lt;br /&gt;
&lt;br /&gt;
====zip-with====&lt;br /&gt;
&lt;br /&gt;
 #(zip-with &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ... &amp;#039;&amp;#039;function&amp;#039;&amp;#039;) -&amp;gt; // If zip-with is in terms of zip&lt;br /&gt;
   #(for #(zip &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ...) #(func (&amp;#039;&amp;#039;cross&amp;#039;&amp;#039;) #(&amp;#039;&amp;#039;function&amp;#039;&amp;#039; @$&amp;#039;&amp;#039;cross&amp;#039;&amp;#039;)))&lt;br /&gt;
 // i.e.&lt;br /&gt;
 #(zip-with &amp;#039;&amp;#039;list&amp;#039;&amp;#039; &amp;#039;&amp;#039;list&amp;#039;&amp;#039; ... #(func (&amp;#039;&amp;#039;elem&amp;#039;&amp;#039; &amp;#039;&amp;#039;elem&amp;#039;&amp;#039; ...) ...))&lt;br /&gt;
&lt;br /&gt;
Returns a new list collected by traversing all given lists in parallel and applying &amp;lt;code&amp;gt;&amp;#039;&amp;#039;function&amp;#039;&amp;#039;&amp;lt;/code&amp;gt; to the cross-section at each element. Traversal ends at the end of the shortest list.&lt;br /&gt;
&lt;br /&gt;
===Minimal subset of functions===&lt;br /&gt;
&lt;br /&gt;
The [[Cifl/Protocifl/Tags and unions]] spec, the initial application for graut, requires only the following functions in the &amp;lt;code&amp;gt;SYSTEM&amp;lt;/code&amp;gt; namespace:&lt;br /&gt;
&lt;br /&gt;
* nop&lt;br /&gt;
* def&lt;br /&gt;
* func&lt;br /&gt;
* for&lt;br /&gt;
* if&lt;br /&gt;
* not&lt;br /&gt;
* true&lt;br /&gt;
* false&lt;br /&gt;
* set-and&lt;br /&gt;
&lt;br /&gt;
It also specifies several functions specific to tags and unions, which would be in another namespace.&lt;br /&gt;
&lt;br /&gt;
==Built-in type constructors==&lt;br /&gt;
&lt;br /&gt;
===number===&lt;br /&gt;
&lt;br /&gt;
 #( $((SYSTEM number) parse-canonical) &amp;#039;&amp;#039;numerator&amp;#039;&amp;#039; &amp;#039;&amp;#039;denominator&amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
Returns a numeric value corresponding to the given string values. In Graut, a numeric value is always a finite rational; concepts such as infinity and NaN do not apply.&lt;br /&gt;
&lt;br /&gt;
The canonical value space is defined thus:&lt;br /&gt;
&lt;br /&gt;
* The value is defined as the ratio of &amp;#039;&amp;#039;numerator&amp;#039;&amp;#039; to &amp;#039;&amp;#039;denominator&amp;#039;&amp;#039;.&lt;br /&gt;
* &amp;#039;&amp;#039;numerator&amp;#039;&amp;#039; conforms to the pattern &amp;lt;code&amp;gt;0|(-?[1-9][0-9]*)&amp;lt;/code&amp;gt;, describing a base-10 integer.&lt;br /&gt;
** Zero is represented only by &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; (no additional digits or negative sign).&lt;br /&gt;
** A non-zero value must not have &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; as its first digit.&lt;br /&gt;
* &amp;#039;&amp;#039;denominator&amp;#039;&amp;#039; conforms to the pattern &amp;lt;code&amp;gt;[1-9][0-9]*&amp;lt;/code&amp;gt;, describing a base-10 integer.&lt;br /&gt;
** The value is never less than 1.&lt;br /&gt;
** The first digit is never &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt;.&lt;br /&gt;
* The ratio is in &amp;#039;&amp;#039;lowest terms&amp;#039;&amp;#039;; i.e. the greatest common divisor of the denominator and the (absolute value of the) numerator is 1.&lt;br /&gt;
** If &amp;#039;&amp;#039;numerator&amp;#039;&amp;#039; is 0, &amp;#039;&amp;#039;denominator&amp;#039;&amp;#039; must be 1. (This follows from gcd(0,&amp;#039;&amp;#039;a&amp;#039;&amp;#039;) = &amp;#039;&amp;#039;a&amp;#039;&amp;#039; for &amp;#039;&amp;#039;a&amp;#039;&amp;#039; &amp;amp;gt; 0.)&lt;br /&gt;
&lt;br /&gt;
This value space is a superset of both integers and (finite, non-negative-zero) floating-point numbers.&lt;br /&gt;
&lt;br /&gt;
Arbitrary-length integers should be used for the internal representation.&lt;br /&gt;
&lt;br /&gt;
 Integers:&lt;br /&gt;
 0		-&amp;gt; #( $((SYSTEM number) parse-canonical) 0 1 )&lt;br /&gt;
 123		-&amp;gt; #( $((SYSTEM number) parse-canonical) 123 1 )&lt;br /&gt;
 -1		-&amp;gt; #( $((SYSTEM number) parse-canonical) -1 1 )&lt;br /&gt;
 &lt;br /&gt;
 Floats in base-10:&lt;br /&gt;
 1.234e-5 = 1234e-8 = 1234 / 10^8 = 617 / 50000000&lt;br /&gt;
 		-&amp;gt; #( $((SYSTEM number) parse-canonical) 617 50000000 )&lt;br /&gt;
 		&lt;br /&gt;
 // Approximated 1/3&lt;br /&gt;
 0.33333333333333333333333333333333 -&amp;gt;&lt;br /&gt;
 		-&amp;gt; #( $((SYSTEM number) parse-canonical)&lt;br /&gt;
 			33333333333333333333333333333333&lt;br /&gt;
 			100000000000000000000000000000000 ) // 10^31&lt;br /&gt;
 // Approximated pi&lt;br /&gt;
 3.1415926535897932384626433832795 -&amp;gt;&lt;br /&gt;
 		-&amp;gt; #( $((SYSTEM number) parse-canonical) &lt;br /&gt;
 			6283185307179586476925286766559&lt;br /&gt;
 			2000000000000000000000000000000 )  // 2 * 10^30, lowest terms&lt;br /&gt;
 &lt;br /&gt;
 Floats in base-16 (e.g. from Java Double.toHexString())&lt;br /&gt;
 // Approximated 1/10&lt;br /&gt;
 0x1.999999999999ap-4&lt;br /&gt;
 		-&amp;gt; #( $((SYSTEM number) parse-canonical)&lt;br /&gt;
 			3602879701896397&lt;br /&gt;
 			36028797018963968 ) // 2^54, lowest terms&lt;br /&gt;
 &lt;br /&gt;
 Actual rationals:&lt;br /&gt;
 1/3		-&amp;gt; #( $((SYSTEM number) parse-canonical) 1 3 )&lt;br /&gt;
 1/10		-&amp;gt; #( $((SYSTEM number) parse-canonical) 1 10 )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When collapsed into a key, a value of this type uses the namespace &amp;lt;code&amp;gt;(SYSTEM number)&amp;lt;/code&amp;gt;. Note that key ordering will not reflect the numeric value: Exactly equal numbers compare equal as keys, but distinct numbers (even nearly equal ones, such as 1/3 versus 0.33333...) may vary in either direction.&lt;br /&gt;
&lt;br /&gt;
===boolean===&lt;br /&gt;
&lt;br /&gt;
 #( $((SYSTEM boolean) parse-canonical) &amp;#039;&amp;#039;atom&amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
Returns a boolean value corresponding to the string value. Error if the input string is not in canonical form.&lt;br /&gt;
&lt;br /&gt;
The canonical form of a boolean value matches the pattern &amp;lt;code&amp;gt;^(true|false)$&amp;lt;/code&amp;gt;. To clarify:&lt;br /&gt;
&lt;br /&gt;
* If the value represented is true, the string is exactly &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt; (U+74, U+72, U+75, U+65).&lt;br /&gt;
* If the value represented is false, the string is exactly &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt; (U+66, U+61, U+6C, U+73, U+65).&lt;br /&gt;
&lt;br /&gt;
The pattern must match without normalizing the string (e.g. to adjust case, remove whitespace, etc.).&lt;br /&gt;
&lt;br /&gt;
When collapsed into a key, a value of this type uses the namespace &amp;lt;code&amp;gt;(SYSTEM boolean)&amp;lt;/code&amp;gt;. Key ordering will cause a false value to precede a true value; no other order relationship is defined.&lt;br /&gt;
&lt;br /&gt;
===nonce===&lt;br /&gt;
&lt;br /&gt;
 #( $((SYSTEM nonce) parse-canonical) &amp;#039;&amp;#039;internal-values&amp;#039;&amp;#039; )&lt;br /&gt;
&lt;br /&gt;
It is illegal for non-internal code to call this function; it only exists for the purpose of deserializing keys containing nonces. To create a new nonce, using the unfollowed &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt; sigil notation. The interpreter replaces this with a nonce value that has not yet been produced this run.&lt;br /&gt;
&lt;br /&gt;
The representation used is implementation-defined, as long as it retains its value through conversion to and from a key.&lt;br /&gt;
&lt;br /&gt;
Copies of the same value must compare equal. Otherwise, no ordering is specified. Older values need not be always less than or always greater than newer values. There should be no meaningful conversion to another value type.&lt;br /&gt;
&lt;br /&gt;
When collapsed into a key, a value of this type uses the namespace &amp;lt;code&amp;gt;(SYSTEM nonce)&amp;lt;/code&amp;gt;. A serialized value should not be seen outside the internals of the implementation. Attempting to deserialize a value from a source outside the internals is an error.&lt;/div&gt;</summary>
		<author><name>Psmay</name></author>
		
	</entry>
</feed>