Documentation updates, rename unfold to produce

db4
Slava Pestov 2008-07-10 01:00:27 -05:00
parent 8a9fd1c2b5
commit 5d9c1ea0a0
20 changed files with 51 additions and 36 deletions

View File

@ -12,9 +12,7 @@ HELP: dll
HELP: expired? HELP: expired?
{ $values { "c-ptr" "an alien, byte array, or " { $link f } } { "?" "a boolean" } } { $values { "c-ptr" "an alien, byte array, or " { $link f } } { "?" "a boolean" } }
{ $description "Tests if the alien is a relic from an earlier session. When an image is loaded, any alien objects which persisted in the image are marked as being expired." { $description "Tests if the alien is a relic from an earlier session. A byte array is never considered to have expired, whereas passing " { $link f } " always yields true." } ;
$nl
"A byte array is never considered to be expired, whereas passing " { $link f } " always yields true." } ;
HELP: <displaced-alien> ( displacement c-ptr -- alien ) HELP: <displaced-alien> ( displacement c-ptr -- alien )
{ $values { "displacement" "an integer" } { "c-ptr" "an alien, byte array, or " { $link f } } { "alien" "a new alien" } } { $values { "displacement" "an integer" } { "c-ptr" "an alien, byte array, or " { $link f } } { "alien" "a new alien" } }
@ -146,16 +144,22 @@ HELP: alien-callback
{ alien-invoke alien-indirect alien-callback } related-words { alien-invoke alien-indirect alien-callback } related-words
ARTICLE: "alien-expiry" "Alien expiry"
"When an image is loaded, any alien objects which persisted from the previous session are marked as having expired. This is because the C pointers they contain are almost certainly no longer valid."
$nl
"For this reason, the " { $link POSTPONE: ALIEN: } " word should not be used in source files, since loading the source file then saving the image will result in the literal becoming expired. Use " { $link <alien> } " instead, and ensure the word calling " { $link <alien> } " is not declared " { $link POSTPONE: flushable } "."
{ $subsection expired? } ;
ARTICLE: "aliens" "Alien addresses" ARTICLE: "aliens" "Alien addresses"
"Instances of the " { $link alien } " class represent pointers to C data outside the Factor heap:" "Instances of the " { $link alien } " class represent pointers to C data outside the Factor heap:"
{ $subsection <alien> } { $subsection <alien> }
{ $subsection <displaced-alien> } { $subsection <displaced-alien> }
{ $subsection alien-address } { $subsection alien-address }
{ $subsection expired? }
"Anywhere that a " { $link alien } " instance is accepted, the " { $link f } " singleton may be passed in to denote a null pointer." "Anywhere that a " { $link alien } " instance is accepted, the " { $link f } " singleton may be passed in to denote a null pointer."
$nl $nl
"Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a pointer type such as " { $snippet "void*" } " takes care of the details." "Usually alien objects do not have to created and dereferenced directly; instead declaring C function parameters and return values as having a pointer type such as " { $snippet "void*" } " takes care of the details."
{ $subsection "syntax-aliens" } { $subsection "syntax-aliens" }
{ $subsection "alien-expiry" }
"When higher-level abstractions won't do:" "When higher-level abstractions won't do:"
{ $subsection "reading-writing-memory" } { $subsection "reading-writing-memory" }
{ $see-also "c-data" "c-types-specs" } ; { $see-also "c-data" "c-types-specs" } ;

View File

@ -1,5 +1,5 @@
USING: help.markup help.syntax strings byte-arrays alien libc USING: help.markup help.syntax strings byte-arrays alien libc
debugger ; debugger io.encodings.string sequences ;
IN: alien.strings IN: alien.strings
HELP: string>alien HELP: string>alien
@ -38,7 +38,11 @@ HELP: utf16n
ARTICLE: "c-strings" "C strings" ARTICLE: "c-strings" "C strings"
"C string types are arrays with shape " { $snippet "{ \"char*\" encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $snippet "\"char*\"" } " is an alias for " { $snippet "{ \"char*\" utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors." "C string types are arrays with shape " { $snippet "{ \"char*\" encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $snippet "\"char*\"" } " is an alias for " { $snippet "{ \"char*\" utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors."
$nl $nl
"Passing a Factor string to a C function expecting a C string allocates a " { $link byte-array } " in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function. If the conversion fails, for example if the string contains null bytes or characters with values higher than 255, a " { $link c-string-error. } " is thrown." "Passing a Factor string to a C function expecting a C string allocates a " { $link byte-array } " in the Factor heap; the string is then converted to the requested format and a raw pointer is passed to the function."
$nl
"If the conversion fails, for example if the string contains null bytes or characters with values higher than 255, a " { $link c-string-error. } " is thrown."
$nl
"Care must be taken if the C function expects a " { $snippet "char*" } " with a length in bytes, rather than a null-terminated " { $snippet "char*" } "; passing the result of calling " { $link length } " on the string object will not suffice. This is because a Factor string of " { $emphasis "n" } " characters will not necessarily encode to " { $emphasis "n" } " bytes. The correct idiom for C functions which take a string with a length is to first encode the string using " { $link encode } ", and then pass the resulting byte array together with the length of this byte array."
$nl $nl
"Sometimes a C function has a parameter type of " { $snippet "void*" } ", and various data types, among them strings, can be passed in. In this case, strings are not automatically converted to aliens, and instead you must call one of these words:" "Sometimes a C function has a parameter type of " { $snippet "void*" } ", and various data types, among them strings, can be passed in. In this case, strings are not automatically converted to aliens, and instead you must call one of these words:"
{ $subsection string>alien } { $subsection string>alien }

View File

@ -11,7 +11,7 @@ HELP: ALIEN:
{ $syntax "ALIEN: address" } { $syntax "ALIEN: address" }
{ $values { "address" "a non-negative integer" } } { $values { "address" "a non-negative integer" } }
{ $description "Creates an alien object at parse time." } { $description "Creates an alien object at parse time." }
{ $notes "Alien objects are invalidated between image saves and loads." } ; { $notes "Alien objects are invalidated between image saves and loads, and hence source files should not contain alien literals; this word is for interactive use only. See " { $link "alien-expiry" } " for details." } ;
ARTICLE: "syntax-aliens" "Alien object literal syntax" ARTICLE: "syntax-aliens" "Alien object literal syntax"
{ $subsection POSTPONE: ALIEN: } { $subsection POSTPONE: ALIEN: }

View File

@ -250,7 +250,7 @@ GENERIC: ' ( obj -- ptr )
#! n is positive or zero. #! n is positive or zero.
[ dup 0 > ] [ dup 0 > ]
[ [ bignum-bits neg shift ] [ bignum-radix bitand ] bi ] [ [ bignum-bits neg shift ] [ bignum-radix bitand ] bi ]
[ ] unfold nip ; [ ] produce nip ;
: emit-bignum ( n -- ) : emit-bignum ( n -- )
dup dup 0 < [ neg ] when bignum>seq dup dup 0 < [ neg ] when bignum>seq

View File

@ -194,7 +194,7 @@ M: anonymous-complement (classes-intersect?)
[ [ name>> ] compare ] sort >vector [ [ name>> ] compare ] sort >vector
[ dup empty? not ] [ dup empty? not ]
[ dup largest-class >r over delete-nth r> ] [ dup largest-class >r over delete-nth r> ]
[ ] unfold nip ; [ ] produce nip ;
: min-class ( class seq -- class/f ) : min-class ( class seq -- class/f )
over [ classes-intersect? ] curry filter over [ classes-intersect? ] curry filter

View File

@ -393,8 +393,14 @@ HELP: >tuple
{ $values { "seq" sequence } { "tuple" tuple } } { $values { "seq" sequence } { "tuple" tuple } }
{ $description "Creates a tuple with slot values taken from a sequence. The first element of the sequence must be a tuple class word and the remainder the declared slots." { $description "Creates a tuple with slot values taken from a sequence. The first element of the sequence must be a tuple class word and the remainder the declared slots."
$nl $nl
"If the sequence has too many elements, they are ignored, and if it has too few, the remaining slots in the tuple are set to " { $link f } "." } "If the sequence has too few elements, the remaining slots in the tuple are set to their initial values." }
{ $errors "Throws an error if the first element of the sequence is not a tuple class word." } ; { $errors "Throws an error if one of the following occurs:"
{ $list
"the first element of the sequence is not a tuple class word"
"the values in the sequence do not satisfy the slot class predicates"
"the sequence is too long"
}
} ;
HELP: tuple>array ( tuple -- array ) HELP: tuple>array ( tuple -- array )
{ $values { "tuple" tuple } { "array" array } } { $values { "tuple" tuple } { "array" array } }

View File

@ -191,4 +191,4 @@ M: priority-queue heap-pop ( heap -- value key )
: heap-pop-all ( heap -- alist ) : heap-pop-all ( heap -- alist )
[ dup heap-empty? not ] [ dup heap-empty? not ]
[ dup heap-pop swap 2array ] [ dup heap-pop swap 2array ]
[ ] unfold nip ; [ ] produce nip ;

View File

@ -540,7 +540,7 @@ ERROR: custom-error ;
{ 1 0 } [ [ ] map-children ] must-infer-as { 1 0 } [ [ ] map-children ] must-infer-as
! Corner case ! Corner case
[ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail [ [ [ f dup ] [ dup ] [ ] produce ] infer ] must-fail
[ [ [ f dup ] [ ] [ ] while ] infer ] must-fail [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail

View File

@ -100,9 +100,9 @@ SYMBOL: error-stream
presented associate format ; presented associate format ;
: lines ( stream -- seq ) : lines ( stream -- seq )
[ [ readln dup ] [ ] [ drop ] unfold ] with-input-stream ; [ [ readln dup ] [ ] [ drop ] produce ] with-input-stream ;
: contents ( stream -- str ) : contents ( stream -- str )
[ [
[ 65536 read dup ] [ ] [ drop ] unfold concat f like [ 65536 read dup ] [ ] [ drop ] produce concat f like
] with-input-stream ; ] with-input-stream ;

View File

@ -116,7 +116,7 @@ ARTICLE: "sequences-slices" "Subsequences and slices"
"Taking a sequence apart into a head and a tail:" "Taking a sequence apart into a head and a tail:"
{ $subsection unclip-slice } { $subsection unclip-slice }
{ $subsection cut-slice } { $subsection cut-slice }
"A utility for words which use slices as mutable iterators:" "A utility for words which use slices as iterators:"
{ $subsection <flat-slice> } ; { $subsection <flat-slice> } ;
ARTICLE: "sequences-combinators" "Sequence combinators" ARTICLE: "sequences-combinators" "Sequence combinators"
@ -130,7 +130,7 @@ ARTICLE: "sequences-combinators" "Sequence combinators"
{ $subsection map } { $subsection map }
{ $subsection 2map } { $subsection 2map }
{ $subsection accumulate } { $subsection accumulate }
{ $subsection unfold } { $subsection produce }
"Filtering:" "Filtering:"
{ $subsection push-if } { $subsection push-if }
{ $subsection filter } ; { $subsection filter } ;
@ -748,8 +748,9 @@ HELP: slice-error
} ; } ;
HELP: slice HELP: slice
{ $class-description "A virtual sequence which presents a subrange of the elements of an underlying sequence. New instances can be created by calling " { $link <slice> } ". Slices are mutable if the underlying sequence is mutable, and mutating a slice changes the underlying sequence." } { $class-description "A virtual sequence which presents a subrange of the elements of an underlying sequence. New instances can be created by calling " { $link <slice> } "."
{ $notes "The slots of a slice should not be changed after the slice has been created, because this can break invariants." } ; $nl
"Slices are mutable if the underlying sequence is mutable, and mutating a slice changes the underlying sequence. However, slices cannot be resized after creation." } ;
HELP: check-slice HELP: check-slice
{ $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } } { $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } }
@ -764,10 +765,10 @@ HELP: collapse-slice
HELP: <flat-slice> HELP: <flat-slice>
{ $values { "seq" sequence } { "slice" slice } } { $values { "seq" sequence } { "slice" slice } }
{ $description "Outputs a slice with the same elements as " { $snippet "seq" } ", and " { $link slice-from } " equal to 0 and " { $link slice-to } " equal to the length of " { $snippet "seq" } "." } { $description "Outputs a slice with the same elements as " { $snippet "seq" } ", and " { $link slice-from } " equal to 0 and " { $link slice-to } " equal to the length of " { $snippet "seq" } "." }
{ $notes "Some words create slices then proceed to read and write the " { $link slice-from } " and " { $link slice-to } " slots of the slice. To behave predictably when they are themselves given a slice as input, they apply this word first to get a canonical slice." } ; { $notes "Some words create slices then proceed to read the " { $snippet "to" } " and " { $snippet "from" } " slots of the slice. To behave predictably when they are themselves given a slice as input, they apply this word first to get a canonical slice." } ;
HELP: <slice> HELP: <slice>
{ $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } { "slice" "a slice" } } { $values { "from" "a non-negative integer" } { "to" "a non-negative integer" } { "seq" sequence } { "slice" slice } }
{ $description "Outputs a new virtual sequence sharing storage with the subrange of elements in " { $snippet "seq" } " with indices starting from and including " { $snippet "m" } ", and up to but not including " { $snippet "n" } "." } { $description "Outputs a new virtual sequence sharing storage with the subrange of elements in " { $snippet "seq" } " with indices starting from and including " { $snippet "m" } ", and up to but not including " { $snippet "n" } "." }
{ $errors "Throws an error if " { $snippet "m" } " or " { $snippet "n" } " is out of bounds." } { $errors "Throws an error if " { $snippet "m" } " or " { $snippet "n" } " is out of bounds." }
{ $notes "Taking the slice of a slice outputs a slice of the underlying sequence of the original slice. Keep this in mind when writing code which depends on the values of " { $link slice-from } " and " { $link slice-to } " being equal to the inputs to this word. The " { $link <flat-slice> } " word might be helpful in such situations." } ; { $notes "Taking the slice of a slice outputs a slice of the underlying sequence of the original slice. Keep this in mind when writing code which depends on the values of " { $link slice-from } " and " { $link slice-to } " being equal to the inputs to this word. The " { $link <flat-slice> } " word might be helpful in such situations." } ;
@ -950,14 +951,14 @@ HELP: supremum
{ $description "Outputs the greatest element of " { $snippet "seq" } "." } { $description "Outputs the greatest element of " { $snippet "seq" } "." }
{ $errors "Throws an error if the sequence is empty." } ; { $errors "Throws an error if the sequence is empty." } ;
HELP: unfold HELP: produce
{ $values { "pred" "a quotation with stack effect " { $snippet "( -- ? )" } } { "quot" "a quotation with stack effect " { $snippet "( -- obj )" } } { "tail" "a quotation" } { "seq" "a sequence" } } { $values { "pred" "a quotation with stack effect " { $snippet "( -- ? )" } } { "quot" "a quotation with stack effect " { $snippet "( -- obj )" } } { "tail" "a quotation" } { "seq" "a sequence" } }
{ $description "Calls " { $snippet "pred" } " repeatedly. If the predicate yields " { $link f } ", stops, otherwise, calls " { $snippet "quot" } " to yield a value. Values are accumulated and returned in a sequence at the end." } { $description "Calls " { $snippet "pred" } " repeatedly. If the predicate yields " { $link f } ", stops, otherwise, calls " { $snippet "quot" } " to yield a value. Values are accumulated and returned in a sequence at the end." }
{ $examples { $examples
"The following example divides a number by two until we reach zero, and accumulates intermediate results:" "The following example divides a number by two until we reach zero, and accumulates intermediate results:"
{ $example "USING: kernel math prettyprint sequences ;" "1337 [ dup 0 > ] [ 2/ dup ] [ ] unfold nip ." "{ 668 334 167 83 41 20 10 5 2 1 0 }" } { $example "USING: kernel math prettyprint sequences ;" "1337 [ dup 0 > ] [ 2/ dup ] [ ] produce nip ." "{ 668 334 167 83 41 20 10 5 2 1 0 }" }
"The " { $snippet "tail" } " quotation is used when the predicate produces more than one output value. In this case, we have to drop this value even if the predicate fails in order for stack inference to calculate a stack effect for the " { $link unfold } " call:" "The " { $snippet "tail" } " quotation is used when the predicate produces more than one output value. In this case, we have to drop this value even if the predicate fails in order for stack inference to calculate a stack effect for the " { $link produce } " call:"
{ $unchecked-example "USING: kernel prettyprint random sequences ;" "[ 10 random dup 1 > ] [ ] [ drop ] unfold ." "{ 8 2 2 9 }" } { $unchecked-example "USING: kernel prettyprint random sequences ;" "[ 10 random dup 1 > ] [ ] [ drop ] produce ." "{ 8 2 2 9 }" }
} ; } ;
HELP: sigma HELP: sigma

View File

@ -420,11 +420,11 @@ PRIVATE>
: accumulator ( quot -- quot' vec ) : accumulator ( quot -- quot' vec )
V{ } clone [ [ push ] curry compose ] keep ; inline V{ } clone [ [ push ] curry compose ] keep ; inline
: unfold ( pred quot tail -- seq ) : produce ( pred quot tail -- seq )
swap accumulator >r swap while r> { } like ; inline swap accumulator >r swap while r> { } like ; inline
: follow ( obj quot -- seq ) : follow ( obj quot -- seq )
>r [ dup ] r> [ keep ] curry [ ] unfold nip ; inline >r [ dup ] r> [ keep ] curry [ ] produce nip ; inline
: prepare-index ( seq quot -- seq n quot ) : prepare-index ( seq quot -- seq n quot )
>r dup length r> ; inline >r dup length r> ; inline

View File

@ -52,7 +52,7 @@ M: mailbox dispose* threads>> notify-all ;
block-if-empty block-if-empty
[ dup mailbox-empty? ] [ dup mailbox-empty? ]
[ dup data>> pop-back ] [ dup data>> pop-back ]
[ ] unfold nip ; [ ] produce nip ;
: mailbox-get-all ( mailbox -- array ) : mailbox-get-all ( mailbox -- array )
f mailbox-get-all-timeout ; f mailbox-get-all-timeout ;

View File

@ -25,7 +25,7 @@ IN: http
[ CHAR: \r assert= read1 CHAR: \n assert= ] when* ; [ CHAR: \r assert= read1 CHAR: \n assert= ] when* ;
: (read-header) ( -- alist ) : (read-header) ( -- alist )
[ read-crlf dup f like ] [ parse-header-line ] [ drop ] unfold ; [ read-crlf dup f like ] [ parse-header-line ] [ drop ] produce ;
: process-header ( alist -- assoc ) : process-header ( alist -- assoc )
f swap [ [ swap or dup ] dip swap ] assoc-map nip f swap [ [ swap or dup ] dip swap ] assoc-map nip

View File

@ -16,7 +16,7 @@ IN: math.combinatorics
! http://msdn2.microsoft.com/en-us/library/aa302371.aspx ! http://msdn2.microsoft.com/en-us/library/aa302371.aspx
: factoradic ( n -- factoradic ) : factoradic ( n -- factoradic )
0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] unfold reverse 2nip ; 0 [ over 0 > ] [ 1+ [ /mod ] keep swap ] [ ] produce reverse 2nip ;
: (>permutation) ( seq n -- seq ) : (>permutation) ( seq n -- seq )
[ [ dupd >= [ 1+ ] when ] curry map ] keep prefix ; [ [ dupd >= [ 1+ ] when ] curry map ] keep prefix ;

View File

@ -80,7 +80,7 @@ SYMBOL: total
: topological-sort ( seq quot -- newseq ) : topological-sort ( seq quot -- newseq )
>r >vector [ dup empty? not ] r> >r >vector [ dup empty? not ] r>
[ dupd maximal-element >r over delete-nth r> ] curry [ dupd maximal-element >r over delete-nth r> ] curry
[ ] unfold nip ; inline [ ] produce nip ; inline
: classes< ( seq1 seq2 -- lt/eq/gt ) : classes< ( seq1 seq2 -- lt/eq/gt )
[ [

View File

@ -40,7 +40,7 @@ PRIVATE>
! ------------------- ! -------------------
: fib-upto* ( n -- seq ) : fib-upto* ( n -- seq )
0 1 [ pick over >= ] [ tuck + dup ] [ ] unfold 3nip 0 1 [ pick over >= ] [ tuck + dup ] [ ] produce 3nip
but-last-slice { 0 1 } prepend ; but-last-slice { 0 1 } prepend ;
: euler002a ( -- answer ) : euler002a ( -- answer )

View File

@ -53,7 +53,7 @@ IN: project-euler.019
: first-days ( end-date start-date -- days ) : first-days ( end-date start-date -- days )
[ 2dup after=? ] [ 2dup after=? ]
[ dup 1 months time+ swap day-of-week ] [ dup 1 months time+ swap day-of-week ]
[ ] unfold 2nip ; [ ] produce 2nip ;
PRIVATE> PRIVATE>

View File

@ -10,7 +10,7 @@ IN: project-euler.148
dup 1+ * 2/ ; inline dup 1+ * 2/ ; inline
: >base7 ( x -- y ) : >base7 ( x -- y )
[ dup 0 > ] [ 7 /mod ] [ ] unfold nip ; [ dup 0 > ] [ 7 /mod ] [ ] produce nip ;
: (use-digit) ( prev x index -- next ) : (use-digit) ( prev x index -- next )
[ [ 1+ * ] [ sum-1toN 7 sum-1toN ] bi ] dip ^ * + ; [ [ 1+ * ] [ sum-1toN 7 sum-1toN ] bi ] dip ^ * + ;

View File

@ -78,7 +78,7 @@ PRIVATE>
] if ; ] if ;
: number>digits ( n -- seq ) : number>digits ( n -- seq )
[ dup zero? not ] [ 10 /mod ] [ ] unfold reverse nip ; [ dup zero? not ] [ 10 /mod ] [ ] produce reverse nip ;
: nth-triangle ( n -- n ) : nth-triangle ( n -- n )
dup 1+ * 2 / ; dup 1+ * 2 / ;

View File

@ -24,7 +24,7 @@ SINGLETON: windows-ui-backend
[ EnumClipboardFormats win32-error dup dup 0 > ] [ EnumClipboardFormats win32-error dup dup 0 > ]
[ ] [ ]
[ drop ] [ drop ]
unfold nip ; produce nip ;
: with-clipboard ( quot -- ) : with-clipboard ( quot -- )
f OpenClipboard win32-error=0/f f OpenClipboard win32-error=0/f