mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
* Clean up doc and docstring for shared substrings and read only strings.
This commit is contained in:
parent
5411d88250
commit
89d04205b4
6 changed files with 539 additions and 543 deletions
|
@ -1,5 +1,12 @@
|
||||||
2001-04-09 Neil Jerram <neil@ossau.uklinux.net>
|
2001-04-09 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
|
* deprecated.texi (Shared And Read Only Strings): New section for
|
||||||
|
deprecated string stuff. I've also updated the text a bit to
|
||||||
|
reflect current usage of "read only" strings.
|
||||||
|
|
||||||
|
* scheme-data.texi (Shared Substrings, Read Only Strings): Moved
|
||||||
|
to deprecated.texi.
|
||||||
|
|
||||||
* deprecated.texi, posix.texi, scheme-binding.texi,
|
* deprecated.texi, posix.texi, scheme-binding.texi,
|
||||||
scheme-control.texi, scheme-data.texi, scheme-debug.texi,
|
scheme-control.texi, scheme-data.texi, scheme-debug.texi,
|
||||||
scheme-evaluation.texi, scheme-io.texi, scheme-memory.texi,
|
scheme-evaluation.texi, scheme-io.texi, scheme-memory.texi,
|
||||||
|
|
|
@ -1,7 +1,146 @@
|
||||||
@node Deprecated
|
@node Deprecated
|
||||||
@chapter Deprecated
|
@chapter Deprecated
|
||||||
|
|
||||||
@deffn primitive tag x
|
@menu
|
||||||
Return an integer corresponding to the type of X. Deprecated.
|
* Shared And Read Only Strings::
|
||||||
|
* Tags::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Shared And Read Only Strings
|
||||||
|
@section Shared And Read Only Strings
|
||||||
|
|
||||||
|
The procedures described in this section are deprecated because explicit
|
||||||
|
shared substrings are planned to disappear from Guile.
|
||||||
|
|
||||||
|
Instead, all strings will be implemented using sharing internally,
|
||||||
|
combined with a copy-on-write strategy. Once internal string sharing
|
||||||
|
and copy-on-write have been implemented, it will be unnecessary to
|
||||||
|
preserve the concept of read only strings.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Shared Substrings:: Strings which share memory with each other.
|
||||||
|
* Read Only Strings:: Treating certain non-strings as strings.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Shared Substrings
|
||||||
|
@subsection Shared Substrings
|
||||||
|
|
||||||
|
Whenever you extract a substring using @code{substring}, the Scheme
|
||||||
|
interpreter allocates a new string and copies data from the old string.
|
||||||
|
This is expensive, but @code{substring} is so convenient for
|
||||||
|
manipulating text that programmers use it often.
|
||||||
|
|
||||||
|
Guile Scheme provides the concept of the @dfn{shared substring} to
|
||||||
|
improve performance of many substring-related operations. A shared
|
||||||
|
substring is an object that mostly behaves just like an ordinary
|
||||||
|
substring, except that it actually shares storage space with its parent
|
||||||
|
string.
|
||||||
|
|
||||||
|
@deffn primitive make-shared-substring str [start [end]]
|
||||||
|
Return a shared substring of @var{str}. The arguments are the
|
||||||
|
same as for the @code{substring} function: the shared substring
|
||||||
|
returned includes all of the text from @var{str} between
|
||||||
|
indexes @var{start} (inclusive) and @var{end} (exclusive). If
|
||||||
|
@var{end} is omitted, it defaults to the end of @var{str}. The
|
||||||
|
shared substring returned by @code{make-shared-substring}
|
||||||
|
occupies the same storage space as @var{str}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
(define foo "the quick brown fox")
|
||||||
|
(define bar (make-shared-substring some-string 4 9))
|
||||||
|
|
||||||
|
foo => "t h e q u i c k b r o w n f o x"
|
||||||
|
bar =========> |---------|
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The shared substring @var{bar} is not given its own storage space.
|
||||||
|
Instead, the Guile interpreter notes internally that @var{bar} points to
|
||||||
|
a portion of the memory allocated to @var{foo}. However, @var{bar}
|
||||||
|
behaves like an ordinary string in most respects: it may be used with
|
||||||
|
string primitives like @code{string-length}, @code{string-ref},
|
||||||
|
@code{string=?}. Guile makes the necessary translation between indices
|
||||||
|
of @var{bar} and indices of @var{foo} automatically.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(string-length? bar) @result{} 5 ; bar only extends from indices 4 to 9
|
||||||
|
(string-ref bar 3) @result{} #\c ; same as (string-ref foo 7)
|
||||||
|
(make-shared-substring bar 2)
|
||||||
|
@result{} "ick" ; can even make a shared substring!
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Because creating a shared substring does not require allocating new
|
||||||
|
storage from the heap, it is a very fast operation. However, because it
|
||||||
|
shares memory with its parent string, a change to the contents of the
|
||||||
|
parent string will implicitly change the contents of its shared
|
||||||
|
substrings.
|
||||||
|
|
||||||
|
@example
|
||||||
|
(string-set! foo 7 #\r)
|
||||||
|
bar @result{} "quirk"
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Guile considers shared substrings to be immutable. This is because
|
||||||
|
programmers might not always be aware that a given string is really a
|
||||||
|
shared substring, and might innocently try to mutate it without
|
||||||
|
realizing that the change would affect its parent string. (We are
|
||||||
|
currently considering a "copy-on-write" strategy that would permit
|
||||||
|
modifying shared substrings without affecting the parent string.)
|
||||||
|
|
||||||
|
In general, shared substrings are useful in circumstances where it is
|
||||||
|
important to divide a string into smaller portions, but you do not
|
||||||
|
expect to change the contents of any of the strings involved.
|
||||||
|
|
||||||
|
|
||||||
|
@node Read Only Strings
|
||||||
|
@subsection Read Only Strings
|
||||||
|
|
||||||
|
In previous versions of Guile, there was the idea that some string-based
|
||||||
|
primitives such as @code{string-append} could equally accept symbols as
|
||||||
|
arguments. For example, one could write
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(string-append '/home/ 'vigilia)
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
and get @code{"/home/vigilia"} as the result. The term @dfn{read only
|
||||||
|
string} was adopted to describe the argument type expected by such
|
||||||
|
primitives.
|
||||||
|
|
||||||
|
This idea has now been removed. The predicate @code{read-only-string?}
|
||||||
|
still exists, but deprecated, and is equivalent to
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(lambda (x) (or (string? x) (symbol? x)))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
But no Guile primitives now use @code{read-only-string?} to validate
|
||||||
|
their arguments.
|
||||||
|
|
||||||
|
String-based primitives such as @code{string-append}
|
||||||
|
now require strings:
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(string-append '/home/ 'vigilia)
|
||||||
|
@result{}
|
||||||
|
ERROR: Wrong type argument (expecting STRINGP): /home/
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@deffn primitive read-only-string? obj
|
||||||
|
Return @code{#t} if @var{obj} is either a string or a symbol,
|
||||||
|
otherwise return @code{#f}.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@node Tags
|
||||||
|
@section Tags
|
||||||
|
|
||||||
|
@deffn primitive tag x
|
||||||
|
Return an integer corresponding to the type of @var{x}. Deprecated.
|
||||||
|
@end deffn
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1346,8 +1346,6 @@ called with string containing unusal characters.
|
||||||
* Alphabetic Case Mapping:: Convert the alphabetic case of strings.
|
* Alphabetic Case Mapping:: Convert the alphabetic case of strings.
|
||||||
* Appending Strings:: Appending strings to form a new string.
|
* Appending Strings:: Appending strings to form a new string.
|
||||||
* String Miscellanea:: Miscellaneous string procedures.
|
* String Miscellanea:: Miscellaneous string procedures.
|
||||||
* Shared Substrings:: Strings which share memory with each other.
|
|
||||||
* Read Only Strings:: Treating certain non-strings as strings.
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node String Syntax
|
@node String Syntax
|
||||||
|
@ -1772,122 +1770,6 @@ is currently reading symbols case--insensitively.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node Shared Substrings
|
|
||||||
@subsection Shared Substrings
|
|
||||||
|
|
||||||
[FIXME: this is pasted in from Tom Lord's original guile.texi and should
|
|
||||||
be reviewed]
|
|
||||||
|
|
||||||
@c FIXME::martin: Shared substrings are gone, so this section should die.
|
|
||||||
|
|
||||||
Whenever you extract a substring using @code{substring}, the Scheme
|
|
||||||
interpreter allocates a new string and copies data from the old string.
|
|
||||||
This is expensive, but @code{substring} is so convenient for
|
|
||||||
manipulating text that programmers use it often.
|
|
||||||
|
|
||||||
Guile Scheme provides the concept of the @dfn{shared substring} to
|
|
||||||
improve performance of many substring-related operations. A shared
|
|
||||||
substring is an object that mostly behaves just like an ordinary
|
|
||||||
substring, except that it actually shares storage space with its parent
|
|
||||||
string.
|
|
||||||
|
|
||||||
@deffn primitive make-shared-substring str [start [end]]
|
|
||||||
Return a shared substring of @var{str}. The semantics are the
|
|
||||||
same as for the @code{substring} function: the shared substring
|
|
||||||
returned includes all of the text from @var{str} between
|
|
||||||
indexes @var{start} (inclusive) and @var{end} (exclusive). If
|
|
||||||
@var{end} is omitted, it defaults to the end of @var{str}. The
|
|
||||||
shared substring returned by @code{make-shared-substring}
|
|
||||||
occupies the same storage space as @var{str}.
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
@example
|
|
||||||
(define foo "the quick brown fox")
|
|
||||||
(define bar (make-shared-substring some-string 4 9))
|
|
||||||
|
|
||||||
foo => "t h e q u i c k b r o w n f o x"
|
|
||||||
bar =========> |---------|
|
|
||||||
@end example
|
|
||||||
|
|
||||||
The shared substring @var{bar} is not given its own storage space.
|
|
||||||
Instead, the Guile interpreter notes internally that @var{bar} points to
|
|
||||||
a portion of the memory allocated to @var{foo}. However, @var{bar}
|
|
||||||
behaves like an ordinary string in most respects: it may be used with
|
|
||||||
string primitives like @code{string-length}, @code{string-ref},
|
|
||||||
@code{string=?}. Guile makes the necessary translation between indices
|
|
||||||
of @var{bar} and indices of @var{foo} automatically.
|
|
||||||
|
|
||||||
@example
|
|
||||||
(string-length? bar) @result{} 5 ; bar only extends from indices 4 to 9
|
|
||||||
(string-ref bar 3) @result{} #\c ; same as (string-ref foo 7)
|
|
||||||
(make-shared-substring bar 2)
|
|
||||||
@result{} "ick" ; can even make a shared substring!
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Because creating a shared substring does not require allocating new
|
|
||||||
storage from the heap, it is a very fast operation. However, because it
|
|
||||||
shares memory with its parent string, a change to the contents of the
|
|
||||||
parent string will implicitly change the contents of its shared
|
|
||||||
substrings.
|
|
||||||
|
|
||||||
@example
|
|
||||||
(string-set! foo 7 #\r)
|
|
||||||
bar @result{} "quirk"
|
|
||||||
@end example
|
|
||||||
|
|
||||||
Guile considers shared substrings to be immutable. This is because
|
|
||||||
programmers might not always be aware that a given string is really a
|
|
||||||
shared substring, and might innocently try to mutate it without
|
|
||||||
realizing that the change would affect its parent string. (We are
|
|
||||||
currently considering a "copy-on-write" strategy that would permit
|
|
||||||
modifying shared substrings without affecting the parent string.)
|
|
||||||
|
|
||||||
In general, shared substrings are useful in circumstances where it is
|
|
||||||
important to divide a string into smaller portions, but you do not
|
|
||||||
expect to change the contents of any of the strings involved.
|
|
||||||
|
|
||||||
@node Read Only Strings
|
|
||||||
@subsection Read Only Strings
|
|
||||||
|
|
||||||
@c FIXME::martin: Read-only strings are gone, too, so this section should
|
|
||||||
@c also die.
|
|
||||||
|
|
||||||
Type-checking in Guile primitives distinguishes between mutable strings
|
|
||||||
and read only strings. Mutable strings answer @code{#t} to
|
|
||||||
@code{string?} while read only strings may or may not. All kinds of
|
|
||||||
strings, whether or not they are mutable return #t to this:
|
|
||||||
|
|
||||||
@deffn primitive read-only-string? obj
|
|
||||||
Return true if @var{obj} can be read as a string,
|
|
||||||
|
|
||||||
This illustrates the difference between @code{string?} and
|
|
||||||
@code{read-only-string?}:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(string? "a string") @result{} #t
|
|
||||||
(string? 'a-symbol) @result{} #f
|
|
||||||
|
|
||||||
(read-only-string? "a string") @result{} #t
|
|
||||||
(read-only-string? 'a-symbol) @result{} #t
|
|
||||||
@end lisp
|
|
||||||
@end deffn
|
|
||||||
|
|
||||||
"Read-only" refers to how the string will be used, not how the string is
|
|
||||||
permitted to be used. In particular, all strings are "read-only
|
|
||||||
strings" even if they are mutable, because a function that only reads
|
|
||||||
from a string can certainly operate on even a mutable string.
|
|
||||||
|
|
||||||
Symbols are an example of read-only strings. Many string functions,
|
|
||||||
such as @code{string-append} are happy to operate on symbols. Many
|
|
||||||
functions that expect a string argument, such as @code{open-file}, will
|
|
||||||
accept a symbol as well.
|
|
||||||
|
|
||||||
Shared substrings, discussed in the previous chapter, also happen to be
|
|
||||||
read-only strings.
|
|
||||||
|
|
||||||
|
|
||||||
@node Regular Expressions
|
@node Regular Expressions
|
||||||
@section Regular Expressions
|
@section Regular Expressions
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2001-04-09 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
|
* strings.c (scm_read_only_string_p): Update docstring to reflect
|
||||||
|
current (non-)usage of "read only" strings.
|
||||||
|
|
||||||
2001-04-06 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
2001-04-06 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
|
||||||
|
|
||||||
* hooks.c (scm_make_hook, scm_make_hook_with_name),
|
* hooks.c (scm_make_hook, scm_make_hook_with_name),
|
||||||
|
|
|
@ -74,15 +74,8 @@ SCM_DEFINE (scm_string_p, "string?", 1, 0, 0,
|
||||||
|
|
||||||
SCM_DEFINE (scm_read_only_string_p, "read-only-string?", 1, 0, 0,
|
SCM_DEFINE (scm_read_only_string_p, "read-only-string?", 1, 0, 0,
|
||||||
(SCM obj),
|
(SCM obj),
|
||||||
"Return true if @var{obj} can be read as a string,\n\n"
|
"Return @code{#t} if @var{obj} is either a string or a symbol,\n"
|
||||||
"This illustrates the difference between @code{string?} and\n"
|
"otherwise return @code{#f}.")
|
||||||
"@code{read-only-string?}:\n\n"
|
|
||||||
"@lisp\n"
|
|
||||||
"(string? \"a string\") @result{} #t\n"
|
|
||||||
"(string? 'a-symbol) @result{} #f\n\n"
|
|
||||||
"(read-only-string? \"a string\") @result{} #t\n"
|
|
||||||
"(read-only-string? 'a-symbol) @result{} #t\n"
|
|
||||||
"@end lisp")
|
|
||||||
#define FUNC_NAME s_scm_read_only_string_p
|
#define FUNC_NAME s_scm_read_only_string_p
|
||||||
{
|
{
|
||||||
return SCM_BOOL(SCM_ROSTRINGP (obj));
|
return SCM_BOOL(SCM_ROSTRINGP (obj));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue