Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs for v5 #192

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion qi-doc/scribblings/field-guide.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ Qi aims to produce good error messages that convey what the problem is and clear

@bold{Meaning}: The interpreter attempted to apply a function to arguments but found that an argument was not of the expected type.

@bold{Common example}: Using @racket[map] or @racket[filter] without first @racket[(require qi/list)]. The built-in Racket versions are @emph{functions} that expect the input list argument at a specific position (i.e., on the right), whereas the Qi versions are @emph{macros} that are invariant to threading direction and expect precisely one input -- the list itself.
@bold{Common example}: Using @racket[map] or @racket[filter] without first @racket[(require qi/list)]. The built-in Racket versions are @emph{functions} that expect the input list argument at a specific position (i.e., on the right), whereas @seclink["List_Operations"]{the Qi versions} are @emph{macros} that are invariant to threading direction and expect precisely one input -- the list itself.

@bold{Common example}: Using a nested flow (such as a @racket[tee] junction or an @racket[effect]) within a right-threading flow and assuming that the input arguments would be passed on the right. At the moment, Qi does not propagate the threading direction to nested clauses. You could either use a fresh right threading form or indicate the argument positions explicitly in the nested flow using an @seclink["Templates_and_Partial_Application"]{argument template}.

Expand Down
1 change: 1 addition & 0 deletions qi-doc/scribblings/forms.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ The full surface syntax of Qi is given below. Note that this expands to a @secli
&
OR
!
NOR
NAND
XNOR
Expand Down
23 changes: 23 additions & 0 deletions qi-doc/scribblings/intro.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,29 @@ Qi is a hosted language on the @hyperlink["https://racket-lang.org/"]{Racket pla

Additionally, Qi itself uses few and carefully benchmarked dependencies, so that the load-time overhead of @racket[(require qi)] is minimal.

@subsection{About Qi's Release Practices}

Qi breaks with traditional Racket package development and occasionally ships breaking changes in a @hyperlink["https://semver.org/"]{SemVer}-style major release. For that reason, in some cases when using Qi as a dependency, it is advisable to pin to a Qi tag using a Git @tech{package source} rather than follow the main "qi" Racket @tech{package source}. Keep reading for details and examples.

Qi follows the @hyperlink["http://timothyfitz.com/2009/02/10/continuous-deployment-at-imvu-doing-the-impossible-fifty-times-a-day/"]{continuous deployment} model of development. This means that fresh changes are pushed to the main branch of development after they pass a rigorous and comprehensive suite of tests and thorough code review. Additionally, Qi packages on the Racket package index point to this main branch on the source host, so that running @racket[raco pkg install qi] or @racket[raco pkg update qi] will always get the version on the @racket[main] branch, reflecting the latest improvements.

This doesn't mean that you must use this version, however. The expressiveness of modern version control systems allows us to define diverse versioning protocols directly on the versioning backend (e.g., Git) to best support diverse usage needs. Towards this end, Qi follows these conventions:

@itemlist[#:style 'ordered
@item{Each significant new release has a tagged version, which is static and immutable.}
@item{Each legacy release has a "maintenance" branch that will be stable without any backwards incompatible changes or new features, and will be supported with bug fixes as needed.}
]

Now, traditionally, we may have grown accustomed to depending on a certain version of a package "or newer" (as are the semantics of using a Racket, rather than Git, @tech{package source}), so that we never have to update the dependency specification to get the latest improvements. We believe that this convention needlessly overburdens development while threatening application stability, requiring us to choose one or the other.

But instead, by relying on a version with either of the above semantics, we gain stability and flexibility as users of Qi without compromising the freedom to innovate and remedy past missteps for developers of Qi. This style of dependency can be accomplished by using a Git @tech{package source} in your @racket[info.rkt], instead of a Racket @tech{package source}. Like this:

@codeblock{
(define deps '("git://github.com/drym-org/qi.git#v5.0"))
}

In addition, as part of each release, backwards incompatibilities are publicly announced and an effort is made to work with dependent package and application developers to ensure compatibility with the latest release, further bridging the gap to Racket's package management practices. Thus, in practice, outside of a production deployment, relying on the Racket @tech{package source} should be fine.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/outside of a production deployment/outside of a major version release

?


@section{Relationship to the Threading Macro}

The usual threading macro in @seclink["top" #:indirect? #t #:doc '(lib "scribblings/threading.scrbl")]{Threading Macros} is a purely syntactic transformation that does not make any assumptions about the expressions being threaded through, so that it works out of the box for threading values through both functions as well as macros. On the other hand, Qi is primarily oriented around @emph{functions}, and @tech{flows} are expected to be @seclink["What_is_a_Flow_"]{function-valued}. Threading values through macros using Qi requires special handling.
Expand Down
1 change: 0 additions & 1 deletion qi-doc/scribblings/principles.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ Qi flow expressions expand to a small core language which is then @seclink["It_s
(or floe ...)
(not floe)
NOT
!
XOR
ground
(thread floe ...)
Expand Down
2 changes: 1 addition & 1 deletion qi-doc/scribblings/qi.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Start by @seclink["Using_These_Docs"]{getting your bearings}. For an overview of

@section{Using These Docs}

@secref["Introduction_and_Usage"] provides a high-level overview and includes installation and setup instructions. Learn the language by going through the @secref["Tutorial"], and read @secref["When_Should_I_Use_Qi_"] for examples illustrating its use. The many ways in which Qi may be used from the host language (e.g. Racket), as well as the ways in which Qi may be used in tandem with other DSLs, are described in @secref["Language_Interface"]. The various built-in forms of the language are documented in @secref["Qi_Forms"], while @secref["Qi_Macros"] covers using macros to extend the language by adding new features or implementing new DSLs. @secref["Principles_of_Qi"] provides a theoretical foundation to develop a sound intuition for Qi, and the @secref["Field_Guide"] contains practical advice. @secref["Flowing_with_the_Flow"] contains recommendations on editor configuration to help you to write Qi effectively.
@secref["Introduction_and_Usage"] provides a high-level overview and includes installation and setup instructions. Learn the language by going through the @secref["Tutorial"], and read @secref["When_Should_I_Use_Qi_"] for examples illustrating its use. The many ways in which Qi may be used from the host language (e.g. Racket), as well as the ways in which Qi may be used in tandem with other DSLs, are described in @secref["Language_Interface"]. The various built-in forms of the language are documented in @secref["Qi_Forms"], while @secref["Qi_Macros"] covers using macros to extend the language by adding new features or implementing new DSLs, and @secref["List_Operations"] describes forms for expressing optimized list-oriented operations. @secref["Principles_of_Qi"] provides a theoretical foundation to develop a sound intuition for Qi, and the @secref["Field_Guide"] contains practical advice. @secref["Flowing_with_the_Flow"] contains recommendations on editor configuration to help you to write Qi effectively.

This site hosts @emph{user} documentation. If you are interested in contributing to Qi development you may be interested in the @emph{developer} documentation at the @hyperlink["https://github.com/drym-org/qi/wiki"]{Qi Wiki}. The wiki is also your one-stop shop for keeping up with planned events in the Qi community.

Expand Down
2 changes: 2 additions & 0 deletions qi-doc/scribblings/using-qi.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ The equivalent Qi flow is:
(~> (filter odd?) (map sqr)))
}

Note that @racket[filter] and @racket[map] here are the ones from @racketmodname[qi/list].

Here, under the hood, each element of the input list is processed one at a time, with both of these functions being invoked on it in sequence, and then the output list is constructed by accumulating these individual results. This ensures that no intermediate lists are constructed along the way and that the input list is traversed just once -- a standard optimization technique called "stream fusion" or "deforestation." The Qi version produces the same result as the Racket code above, but it can be both faster as well as more memory-efficient, especially on large input lists. Note however that if the functions used in @racket[filter] and @racket[map] are not @emph{pure}, that is, if they perform side effects like printing to the screen or writing to a file, then the Qi flow would exhibit a different @seclink["Order_of_Effects"]{order of effects} than the Racket version.

@section{Curbing Curries and Losing Lambdas}
Expand Down
Loading