{"size": 6205, "ext": "scrbl", "max_stars_repo_path": "private/table.scrbl", "max_stars_repo_name": "avtojaja/rebellion", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "private/table.scrbl", "max_issues_repo_name": "avtojaja/rebellion", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "private/table.scrbl", "max_forks_repo_name": "avtojaja/rebellion", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 39.7756410256, "max_line_length": 80, "alphanum_fraction": 0.6401289283}
#lang scribble/manual

@(require (for-label racket/base
                     racket/contract/base
                     racket/math
                     racket/sequence
                     rebellion/base/symbol
                     rebellion/collection/record
                     rebellion/collection/table
                     rebellion/streaming/reducer)
          (submod rebellion/private/scribble-cross-document-tech doc)
          (submod rebellion/private/scribble-evaluator-factory doc)
          scribble/example)

@(define make-evaluator
   (make-module-sharing-evaluator-factory
    #:public (list 'rebellion/collection/record
                   'rebellion/collection/table
                   'rebellion/streaming/reducer)
    #:private (list 'racket/base)))

@title{Tables}
@defmodule[rebellion/collection/table]

A @deftech{table} is a data structure made up of a collection of rows. Tables
contain a list of column names --- represented by keywords --- and each row has
a value for each column in the row's table. This makes rows similar to @tech{
 records}, with the constraint that all the row records in a table have the same
keys. Tables maintain rows as lists, not sets, so the order of rows in a table
is significant and duplicate rows are allowed. Tables implement the
@tech/reference{sequence} interface, and can be iterated as a sequence of rows.

@defproc[(table? [v any/c]) boolean?]{
 A predicate for @tech{tables}.}

@defform[#:literals (columns row)
         (table (columns column-kw ...) (row row-value ...) ...)]{
 Constructs a @tech{table} containing all of the given rows and whose columns
 are named by the given @racket[column-kw]s. Row values are given by-position
 and there must be exactly one value for each @racket[column-kw].

 @(examples
   #:eval (make-evaluator) #:once
   (table (columns #:name #:population #:capital-city)
          (row "Argentina" 43800000 "Buenos Aires")
          (row "Greece" 10800000 "Athens")
          (row "Nigeria" 198600000 "Abuja")
          (row "Japan" 126400000 "Tokyo")))}

@deftogether[
 (@defform[#:id columns columns]
   @defform[#:id row row])]{
 Syntactic forms recognized by @racket[table]. Both @racket[columns] and
 @racket[row] are meaningless on their own; they can only be used in a @racket[
 table] expression.}

@defproc[(table-ref [tab table?] [pos natural?] [column keyword?]) any/c]{
 Returns the value for @racket[column] in the row at position @racket[pos] in
 @racket[tab].

 @(examples
   #:eval (make-evaluator) #:once
   (define countries
     (table (columns #:name #:population #:capital-city)
            (row "Argentina" 43800000 "Buenos Aires")
            (row "Greece" 10800000 "Athens")
            (row "Nigeria" 198600000 "Abuja")
            (row "Japan" 126400000 "Tokyo")))
   (table-ref countries 3 '#:name))}

@defproc[(table-rows-ref [tab table?] [pos natural?]) record?]{
 Returns the row in @racket[tab] at position @racket[pos], as a record mapping
 column names to their values in the row.

 @(examples
   #:eval (make-evaluator) #:once
   (define countries
     (table (columns #:name #:population #:capital-city)
            (row "Argentina" 43800000 "Buenos Aires")
            (row "Greece" 10800000 "Athens")
            (row "Nigeria" 198600000 "Abuja")
            (row "Japan" 126400000 "Tokyo")))
   (table-rows-ref countries 2))}

@defproc[(table-columns-ref [tab table?] [column keyword?]) immutable-vector?]{
 Returns a vector of all the values for @racket[column] in @racket[tab], with
 each element corresponding to one row in @racket[tab].

 @(examples
   #:eval (make-evaluator) #:once
   (define countries
     (table (columns #:name #:population #:capital-city)
            (row "Argentina" 43800000 "Buenos Aires")
            (row "Greece" 10800000 "Athens")
            (row "Nigeria" 198600000 "Abuja")
            (row "Japan" 126400000 "Tokyo")))
   (table-columns-ref countries '#:capital-city))}

@defproc[(table-size [tab table?]) natural?]{
 Returns the number of rows in @racket[tab].

 @(examples
   #:eval (make-evaluator) #:once
   (eval:no-prompt
    (define countries
      (table (columns #:name #:population #:capital-city)
             (row "Argentina" 43800000 "Buenos Aires")
             (row "Greece" 10800000 "Athens")
             (row "Nigeria" 198600000 "Abuja")
             (row "Japan" 126400000 "Tokyo"))))
   (table-size countries))}

@section{Table Iteration and Comprehensions}

@defform[(for/table (for-clause ...) body-or-break ... body)
         #:contracts ([body record?])]{
 Iterates like @racket[for], but each @racket[body] must evaluate to a @tech{
  record} and the resulting records are collected into a @tech{table}. All
 @racket[body] records must have the same keys. If @racket[body] is never
 evaluated, for instance because the loop iterates over an empty collection,
 then an empty table with no rows and no columns is returned.

 @(examples
   #:eval (make-evaluator) #:once
   (for/table ([god (in-list (list "Zeus" "hera" "hades" "Athena" "PosEIdon"))])
     (define name (string-titlecase god))
     (record #:name name
             #:correct-case? (equal? name god)
             #:name-length (string-length god))))}

@defform[(for*/table (for-clause ...) body-or-break ... body)
         #:contracts ([body record?])]{
 Like @racket[for/table], but iterates like @racket[for*].}

@defproc[(in-table [tab table?]) (sequence/c record?)]{
 Returns a @tech/reference{sequence} that iterates through each row of @racket[
 tab]. Tables already implement the sequence interface, but using this function
 in a @racket[for] form may perform better and give clearer error messages.}

@defthing[into-table reducer?]{
 A @tech{reducer} that reduces @tech{records} into a @tech{table}, in the same
 manner as @racket[for/table].

 @(examples
   #:eval (make-evaluator) #:once
   (reduce into-table
           (record #:person "Sam"
                   #:age 78
                   #:favorite-color 'green)
           (record #:person "Jamie"
                   #:age 30
                   #:favorite-color 'purple)
           (record #:person "Ned"
                   #:age 40
                   #:favorite-color 'red)))}
