diff --git a/doc/Coercion.html b/doc/Coercion.html index e90a5d8..59b9c5a 100644 --- a/doc/Coercion.html +++ b/doc/Coercion.html @@ -1,3 +1,3 @@ -2 Coercion
On this page:
2.1 Values
->int
->string
->symbol
->path
->complete-path
->list
->vector
->boolean
intish?
stringish?
symbolish?
pathish?
complete-pathish?
listish?
vectorish?
2.2 Coercion contracts
coerce/  int?
coerce/  string?
coerce/  symbol?
coerce/  path?
coerce/  boolean?
6.0.1.13

2 Coercion

 (require sugar/coerce) package: sugar

Functions that coerce the datatype of a value to another type. Racket already has type-specific conversion functions. But if you’re handling values of indeterminate type — as sometimes happens in an untyped language — then handling the possible cases individually gets to be a drag.

2.1 Values

procedure

(->int v)  integer?

  v : any/c
Convert v to an integer in the least surprising way, or raise an error if no conversion is possible.

Numbers are rounded down to the nearest integer.

Examples:

> (->int 3)

3

> (->int 3.5)

3

> (->int -2.5)

-3

> (->int (+ 3 (/ 1 2)))

3

Stringlike values — paths, symbols, and strings — are converted to numbers and rounded down.

Examples:

> (->int "3.5")

3

> (->int '3.5)

3

> (->int (string->path "3.5"))

3

Characters are directly converted to integers.

Examples:

> (->int #\A)

65

> (->int #\◊)

9674

Lists, vectors, and other multi-value datatypes return their length (using len).

Examples:

> (->int (list 5 6 7))

3

> (->int (hash 'a 1 'b 2 'c 3))

3

The function will raise an error if no sensible conversion is possible. -

Example:

> (->int #t)

Can’t convert #t to integer

procedure

(->string v)  string?

  v : any/c
Return the most natural string representation of v, or raise an error if none exists.

Examples:

> (->string "string")

"string"

> (->string 'symbol)

"symbol"

> (->string 98.6)

"98.6"

> (->string (string->path "stdio.h"))

"stdio.h"

> (->string #\A)

"A"

> (->string #t)

Can’t convert #t to string

procedure

(->symbol v)  symbol?

  v : any/c
Same as ->string, but return a symbol rather than a string.

Examples:

> (->symbol "string")

'string

> (->symbol 'symbol)

'symbol

> (->symbol 98.6)

'|98.6|

> (->symbol (string->path "stdio.h"))

'stdio.h

> (->symbol #\A)

'A

> (->symbol #t)

Can’t convert #t to symbol

procedure

(->path v)  path?

  v : any/c

procedure

(->complete-path v)  complete-path?

  v : any/c
Same as ->string, but return a path (or complete path) rather than a string.

Examples:

> (->path "string")

#<path:string>

> (->path 'symbol)

#<path:symbol>

> (->complete-path 98.6)

#<path:/Users/MB/git/sugar/98.6>

> (->complete-path (string->path "stdio.h"))

#<path:/Users/MB/git/sugar/stdio.h>

> (->complete-path #\A)

#<path:/Users/MB/git/sugar/A>

> (->complete-path #t)

Can’t convert #t to complete-path

procedure

(->list v)  list?

  v : any/c
If v is a listlike data type — a vector, set, stream, sequence, or list — convert it to a list. A hash or dictionary becomes a list using dict->list. If v is an atomic value, turn it into a single-member list.

Note that a string is treated as an atomic value rather than decomposed with string->list. This is done so the function handles strings the same way as symbols and paths.

Examples:

> (->list '(a b c))

'(a b c)

> (->list (list->vector '(a b c)))

'(a b c)

> (->list (make-hash '((k . v) (k2 . v2))))

'((k2 . v2) (k . v))

> (->list "string")

'("string")

> (->list 'symbol)

'(symbol)

> (->list (string->path "path"))

'(#<path:path>)

> (->list +)

'(#<procedure:+>)

procedure

(->vector v)  vector?

  v : any/c
Same as ->list, but returns a vector rather than a list.

Examples:

> (->vector '(a b c))

'#(a b c)

> (->vector (list->vector '(a b c)))

'#(a b c)

> (->vector (make-hash '((k . v) (k2 . v2))))

'#((k2 . v2) (k . v))

> (->vector "string")

'#("string")

> (->vector 'symbol)

'#(symbol)

> (->vector (string->path "path"))

'#(#<path:path>)

> (->vector +)

'#(#<procedure:+>)

procedure

(->boolean v)  boolean?

  v : any/c
Return #t for all v except #f, which remains #f.

Examples:

> (->boolean "string")

#t

> (->boolean 'symbol)

#t

> (->boolean +)

#t

> (->boolean '(l i s t))

#t

> (->boolean #f)

#f

procedure

(intish? v)  boolean?

  v : any/c

procedure

(stringish? v)  boolean?

  v : any/c

procedure

(symbolish? v)  boolean?

  v : any/c

procedure

(pathish? v)  boolean?

  v : any/c

procedure

(complete-pathish? v)  boolean?

  v : any/c

procedure

(listish? v)  boolean?

  v : any/c

procedure

(vectorish? v)  boolean?

  v : any/c
Predicates that report whether v can be coerced to the specified type.

Examples:

> (map intish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #f #f #f)

> (map stringish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map symbolish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map pathish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map complete-pathish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map listish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #t #t)

> (map vectorish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #t #t)

2.2 Coercion contracts

procedure

(coerce/int? v)  integer?

  v : any/c

procedure

(coerce/string? v)  string?

  v : any/c

procedure

(coerce/symbol? v)  symbol?

  v : any/c

procedure

(coerce/path? v)  path?

  v : any/c

procedure

(coerce/boolean? v)  boolean?

  v : any/c
If v can be coerced to the specified type, change it to that type, then return it. If not, raise the usual contract error. These contracts can be used with input or output values.

Examples:

> (define/contract (add-ints x y)
      (coerce/int? coerce/int? . -> . any/c)
      (+ x y))
; Input arguments will be coerced to integers, then added
> (add-ints 1.6 3.8)

4

> (define/contract (int-sum x y)
      (any/c any/c . -> . coerce/int?)
      (+ x y))
; Input arguments will be added, and the result coerced to an integer
> (int-sum 1.6 3.8)

5

Please note: this is not an officially sanctioned way to use Racket’s contract system, because contracts aren’t supposed to mutate their values (see make-contract).

But coercion contracts can be useful in two situations:

 
\ No newline at end of file +2 Coercion
On this page:
2.1 Values
->int
->string
->symbol
->path
->complete-path
->list
->vector
->boolean
intish?
stringish?
symbolish?
pathish?
complete-pathish?
listish?
vectorish?
2.2 Coercion contracts
coerce/  int?
coerce/  string?
coerce/  symbol?
coerce/  path?
coerce/  boolean?
6.0.1.13

2 Coercion

 (require sugar/coerce) package: sugar

Functions that coerce the datatype of a value to another type. Racket already has type-specific conversion functions. But if you’re handling values of indeterminate type — as sometimes happens in an untyped language — then handling the possible cases individually gets to be a drag.

2.1 Values

procedure

(->int v)  integer?

  v : any/c
Convert v to an integer in the least surprising way, or raise an error if no conversion is possible.

Numbers are rounded down to the nearest integer.

Examples:

> (->int 3)

3

> (->int 3.5)

3

> (->int -2.5)

-3

> (->int (+ 3 (/ 1 2)))

3

Stringlike values — paths, symbols, and strings — are converted to numbers and rounded down.

Examples:

> (->int "3.5")

3

> (->int '3.5)

3

> (->int (string->path "3.5"))

3

Characters are directly converted to integers.

Examples:

> (->int #\A)

65

> (->int #\◊)

9674

Lists, vectors, and other multi-value datatypes return their length (using len).

Examples:

> (->int (list 5 6 7))

3

> (->int (hash 'a 1 'b 2 'c 3))

3

The function will raise an error if no sensible conversion is possible. +

Example:

> (->int #t)

Can’t convert #t to integer

procedure

(->string v)  string?

  v : any/c
Return the most natural string representation of v, or raise an error if none exists.

Examples:

> (->string "string")

"string"

> (->string 'symbol)

"symbol"

> (->string 98.6)

"98.6"

> (->string (string->path "stdio.h"))

"stdio.h"

> (->string #\A)

"A"

> (->string #t)

Can’t convert #t to string

procedure

(->symbol v)  symbol?

  v : any/c
Same as ->string, but return a symbol rather than a string.

Examples:

> (->symbol "string")

'string

> (->symbol 'symbol)

'symbol

> (->symbol 98.6)

'|98.6|

> (->symbol (string->path "stdio.h"))

'stdio.h

> (->symbol #\A)

'A

> (->symbol #t)

Can’t convert #t to symbol

procedure

(->path v)  path?

  v : any/c

procedure

(->complete-path v)  complete-path?

  v : any/c
Same as ->string, but return a path (or complete path) rather than a string.

Examples:

> (->path "string")

#<path:string>

> (->path 'symbol)

#<path:symbol>

> (->complete-path 98.6)

#<path:/Users/MB/git/sugar/98.6>

> (->complete-path (string->path "stdio.h"))

#<path:/Users/MB/git/sugar/stdio.h>

> (->complete-path #\A)

#<path:/Users/MB/git/sugar/A>

> (->complete-path #t)

Can’t convert #t to complete-path

procedure

(->list v)  list?

  v : any/c
If v is a listlike data type — a vector, set, stream, sequence, or list — convert it to a list. A hash or dictionary becomes a list using dict->list. If v is an atomic value, turn it into a single-member list.

Note that a string is treated as an atomic value rather than decomposed with string->list. This is done so the function handles strings the same way as symbols and paths.

Examples:

> (->list '(a b c))

'(a b c)

> (->list (list->vector '(a b c)))

'(a b c)

> (->list (make-hash '((k . v) (k2 . v2))))

'((k . v) (k2 . v2))

> (->list "string")

'("string")

> (->list 'symbol)

'(symbol)

> (->list (string->path "path"))

'(#<path:path>)

> (->list +)

'(#<procedure:+>)

procedure

(->vector v)  vector?

  v : any/c
Same as ->list, but returns a vector rather than a list.

Examples:

> (->vector '(a b c))

'#(a b c)

> (->vector (list->vector '(a b c)))

'#(a b c)

> (->vector (make-hash '((k . v) (k2 . v2))))

'#((k . v) (k2 . v2))

> (->vector "string")

'#("string")

> (->vector 'symbol)

'#(symbol)

> (->vector (string->path "path"))

'#(#<path:path>)

> (->vector +)

'#(#<procedure:+>)

procedure

(->boolean v)  boolean?

  v : any/c
Return #t for all v except #f, which remains #f.

Examples:

> (->boolean "string")

#t

> (->boolean 'symbol)

#t

> (->boolean +)

#t

> (->boolean '(l i s t))

#t

> (->boolean #f)

#f

procedure

(intish? v)  boolean?

  v : any/c

procedure

(stringish? v)  boolean?

  v : any/c

procedure

(symbolish? v)  boolean?

  v : any/c

procedure

(pathish? v)  boolean?

  v : any/c

procedure

(complete-pathish? v)  boolean?

  v : any/c

procedure

(listish? v)  boolean?

  v : any/c

procedure

(vectorish? v)  boolean?

  v : any/c
Predicates that report whether v can be coerced to the specified type.

Examples:

> (map intish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #f #f #f)

> (map stringish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map symbolish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map pathish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map complete-pathish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #f #f)

> (map listish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #t #t)

> (map vectorish? (list 3 3.5 #\A "A" + #t))

'(#t #t #t #t #t #t)

2.2 Coercion contracts

procedure

(coerce/int? v)  integer?

  v : any/c

procedure

(coerce/string? v)  string?

  v : any/c

procedure

(coerce/symbol? v)  symbol?

  v : any/c

procedure

(coerce/path? v)  path?

  v : any/c

procedure

(coerce/boolean? v)  boolean?

  v : any/c
If v can be coerced to the specified type, change it to that type, then return it. If not, raise the usual contract error. These contracts can be used with input or output values.

Examples:

> (define/contract (add-ints x y)
      (coerce/int? coerce/int? . -> . any/c)
      (+ x y))
; Input arguments will be coerced to integers, then added
> (add-ints 1.6 3.8)

4

> (define/contract (int-sum x y)
      (any/c any/c . -> . coerce/int?)
      (+ x y))
; Input arguments will be added, and the result coerced to an integer
> (int-sum 1.6 3.8)

5

Please note: this is not an officially sanctioned way to use Racket’s contract system, because contracts aren’t supposed to mutate their values (see make-contract).

But coercion contracts can be useful in two situations:

 
\ No newline at end of file diff --git a/doc/Container.html b/doc/Container.html new file mode 100644 index 0000000..a73b971 --- /dev/null +++ b/doc/Container.html @@ -0,0 +1,2 @@ + +3 Container
On this page:
get
in?
6.0.1.13

3 Container

 (require sugar/container) package: sugar

Type-neutral functions for getting elements out of a container, or testing membership.

procedure

(get container which [end_which])  any/c

  container : (or/c list? vector? sequence? dict? string? symbol? path?)
  which : any/c
  end_which : (or/c (and/c integer? positive?) #f) = #f
For a container that’s a dict?, retrieve the element associated with the key which. Raise an error if the key doesn’t exist.

Examples:

> (get (make-hash '((a . 1) (b . 2) (c  . 3))) 'b)

2

> (get (make-hash '((a . 1) (b . 2) (c  . 3))) 'z)

get: couldn’t retrieve item z from #hash((a . 1) (c . 3) (b

. 2))

For other container types — which are all sequence-like — retrieve the element located at which. Or if the optional end_which argument is provided, retrieve the elements from which to (sub1 end_which), inclusive (i.e., make a slice). Raise an error if which or end_which is out of bounds.

Examples:

> (get '(0 1 2 3 4 5) 2)

2

> (get '(0 1 2 3 4 5) 2 4)

'(2 3)

> (get '(0 1 2 3 4 5) 100)

get: couldn’t retrieve item 100 from (0 1 2 3 4 5)

> (get '(0 1 2 3 4 5) 2 100)

get: couldn’t retrieve items 2 through 100 from (0 1 2 3 4

5)

> (get (list->vector '(0 1 2 3 4 5)) 2)

2

> (get (list->vector '(0 1 2 3 4 5)) 2 4)

'#(2 3)

> (get "purple" 2)

"r"

> (get "purple" 2 4)

"rp"

> (get 'purple 2)

'r

> (get 'purple 2 4)

'rp

When container is a path, it’s treated as a list of exploded path elements, not as a stringlike value.

Examples:

> (get (string->path "/root/foo/bar/file.txt") 1)

#<path:root>

> (get (string->path "/root/foo/bar/file.txt") 0 3)

'(#<path:/> #<path:root> #<path:foo>)

To slice to the end of container, use (len container) as the value of end_which.

Examples:

> (define xs '(0 1 2 3 4 5))
> (get xs 2 (len xs))

'(2 3 4 5)

> (get (list->vector xs) 2 (len (list->vector xs)))

'#(2 3 4 5)

> (define color "purple")
> (get color 2 (len color))

"rple"

procedure

(in? item container)  boolean?

  item : any/c
  container : (or/c list? vector? sequence? set? dict? string? symbol? path?)
Return #t if item is in container, or #f otherwise.

Examples:

> (in? 2 '(0 1 2 3 4 5))

#t

> (in? 'a '(0 1 2 3 4 5))

#f

> (in? 2 (list->vector '(0 1 2 3 4 5)))

#t

> (in? "pu" "purple")

#t

> (in? "zig" "purple")

#f

> (in? 'b (make-hash '((a . 1) (b . 2) (c  . 3))))

#t

> (in? 'z (make-hash '((a . 1) (b . 2) (c  . 3))))

#f

As with get, when container is a path, it’s treated as a list of exploded path elements, not as a stringlike value.

Examples:

> (in? "foo" (string->path "/root/foo/bar/file.txt"))

#t

> (in? "zam" (string->path "/root/foo/bar/file.txt"))

#f

 
\ No newline at end of file diff --git a/doc/Installation___updates.html b/doc/Installation___updates.html index d2f3cbb..62301d4 100644 --- a/doc/Installation___updates.html +++ b/doc/Installation___updates.html @@ -1,4 +1,4 @@ -1 Installation & updates
6.0.1.13

1 Installation & updates

At the command line: +1 Installation & updates
6.0.1.13

1 Installation & updates

At the command line:

raco pkg install sugar

After that, you can update the package from the command line:

raco pkg update sugar

 
\ No newline at end of file diff --git a/doc/Len.html b/doc/Len.html index 5cd2b91..ab582a5 100644 --- a/doc/Len.html +++ b/doc/Len.html @@ -1,2 +1,2 @@ -3 Len
6.0.1.13

3 Len

 (require sugar/len) package: sugar

procedure

(len x)  integer?

  x : (or/c list? string? symbol? vector? hash? integer? set?)
Convert x to a length in the least surprising way possible, or raise an error if it can’t be done.

 
\ No newline at end of file +4 Len
6.0.1.13

4 Len

 (require sugar/len) package: sugar

procedure

(len x)  integer?

  x : (or/c list? string? symbol? vector? hash? integer? set?)
Convert x to a length in the least surprising way possible, or raise an error if it can’t be done.

 
\ No newline at end of file diff --git a/doc/License___source_code.html b/doc/License___source_code.html index 966bf8c..ab63ba9 100644 --- a/doc/License___source_code.html +++ b/doc/License___source_code.html @@ -1,2 +1,2 @@ -4 License & source code
6.0.1.13

4 License & source code

This module is licensed under the LGPL.

Source repository at http://github.com/mbutterick/sugar. Suggestions & corrections welcome.

 
\ No newline at end of file +5 License & source code
6.0.1.13

5 License & source code

This module is licensed under the LGPL.

Source repository at http://github.com/mbutterick/sugar. Suggestions & corrections welcome.

 
\ No newline at end of file diff --git a/doc/doc-index.html b/doc/doc-index.html index 0eeb05c..2c39421 100644 --- a/doc/doc-index.html +++ b/doc/doc-index.html @@ -1,2 +1,2 @@ -Index
 
\ No newline at end of file +Index
 
\ No newline at end of file diff --git a/doc/index.html b/doc/index.html index a500a87..cefaff1 100644 --- a/doc/index.html +++ b/doc/index.html @@ -1,2 +1,2 @@ -Sugar: readability & convenience library
6.0.1.13

Sugar: readability & convenience library

Matthew Butterick <mb@mbtype.com>

 (require sugar) package: sugar

A collection of small functions to help make Racket code simpler & more readable.

    1 Installation & updates

    2 Coercion

      2.1 Values

      2.2 Coercion contracts

    3 Len

    4 License & source code

    Index

 
\ No newline at end of file +Sugar: readability & convenience library
6.0.1.13

Sugar: readability & convenience library

Matthew Butterick <mb@mbtype.com>

 (require sugar) package: sugar

A collection of small functions to help make Racket code simpler & more readable.

    1 Installation & updates

    2 Coercion

      2.1 Values

      2.2 Coercion contracts

    3 Container

    4 Len

    5 License & source code

    Index

 
\ No newline at end of file diff --git a/scribblings/sugar.scrbl b/scribblings/sugar.scrbl index 1ae4465..877903d 100644 --- a/scribblings/sugar.scrbl +++ b/scribblings/sugar.scrbl @@ -20,6 +20,8 @@ A collection of small functions to help make Racket code simpler & more readable @include-section["coerce.scrbl"] +@include-section["container.scrbl"] + @include-section["len.scrbl"] @include-section["license.scrbl"]