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

Deforest All the Things #179

Merged
merged 113 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 commits
Select commit Hold shift + click to select a range
3dc3871
List-ref and cad*r deforestation
dzoep Mar 11, 2024
83384fb
Deforestation of length, empty?, and null?.
dzoep Mar 23, 2024
cf0b178
Deforest filter-map.
dzoep Mar 23, 2024
9d9c064
Pass deforested operation name in cad*r-cstream-next.
dzoep Apr 6, 2024
f315281
Fix failing car-deforested? test.
dzoep Apr 28, 2024
6df1eca
Cleaner syntax matching and production separation.
dzoep Apr 30, 2024
56f880a
Split compiler passes into separate modules.
dzoep May 5, 2024
5813c77
Move deforestation infrastructure into passes subdirectory.
dzoep May 5, 2024
30d812e
Finish fixing all the things broken by the rebase.
dzoep May 5, 2024
8ade245
Improve directory and module naming
dzoep May 24, 2024
04ca289
Deforest take with boxes.
dzoep May 31, 2024
bcb3118
Implement proper state cons-ing for take.
dzoep May 31, 2024
301a542
Add source syntax context to transformer composition.
dzoep May 31, 2024
a0381d7
New qi/list bindings and their literal matching, stateful transformer…
dzoep Jun 14, 2024
6fd8a93
Deforestation: rename all fusable stream syntax classes to fs[PTC]-sy…
dzoep Jun 15, 2024
1975925
Fix tests of qi/list - use the new bindings.
dzoep Jun 15, 2024
0134706
Split bindings module and add appropriate scribblings.
dzoep Jun 14, 2024
3288d0e
Update PR#175 with all the changes agreed upon at the weekly Qi compi…
dzoep Jun 27, 2024
536c75d
Fix phase shifting for fusion.rkt module.
dzoep Jun 28, 2024
ff5a395
Add attach-form-property to both places needed by current deforestati…
dzoep Jun 28, 2024
97a845d
Remove unused `require`
countvajhula Aug 3, 2024
510acb9
Introduce a `#%deforestable` core form
countvajhula Jun 29, 2024
0bed239
support basic cases of filter, map, foldl, foldr and range
countvajhula Jun 29, 2024
c213e80
a couple more tests for `range`
countvajhula Jul 2, 2024
c185564
formatting..
countvajhula Jul 10, 2024
cc8cf45
temporarily comment out some tests
countvajhula Jul 11, 2024
c6ee0b4
register deforestation pass in core
countvajhula Jul 11, 2024
e3eba11
Simplify #%deforestable syntax initially
countvajhula Jul 11, 2024
0dc8fe4
modify benchmarks and tests to work with simplified `range` syntax
countvajhula Jul 11, 2024
b48a276
Match `#%deforestable` in deforesting `map` and `filter`
countvajhula Jul 11, 2024
2d878fb
Remove tests that ensure only right-threading is deforested
countvajhula Jul 11, 2024
580b380
Match `#%deforestable` in `foldl` and `foldr`
countvajhula Jul 11, 2024
0269159
Match `#%deforestable` in deforesting `car`
countvajhula Jul 11, 2024
c6dfd57
Use `#%deforestable` in `cadr`, `caddr`, `cadddr`
countvajhula Jul 11, 2024
33f2b58
Use `#%deforestable` in `list-ref`
countvajhula Jul 11, 2024
9c9ff0a
Use `#%deforestable` in `length`
countvajhula Jul 11, 2024
208aa1b
Use `#%deforestable` in `empty?` and `null?`
countvajhula Jul 11, 2024
d3535b5
Write `filter-map` as a macro expanding to `#%deforestable`
countvajhula Jul 11, 2024
a890931
Match `#%deforestable` in deforesting take instead of a host expression
countvajhula Jul 11, 2024
1130b8d
simplify `range` syntax matching for now
countvajhula Jul 11, 2024
11eef9e
mysterious fix for test errors
countvajhula Jul 11, 2024
78e57c5
lint..
countvajhula Jul 12, 2024
5314024
A few basic tests for deforested forms
countvajhula Jul 12, 2024
cecd4e1
Codegen floe positions in #%deforestable
countvajhula Aug 2, 2024
28c2408
New syntax for `#%deforestable` distinguishing `floe` positions
countvajhula Aug 2, 2024
c3e099f
Use the new `#%deforestable` syntax
countvajhula Aug 2, 2024
03cc55c
Compile higher-order `floe` positions in deforestation pass
countvajhula Aug 2, 2024
50974c1
Surface tests for `qi/list` forms
countvajhula Aug 8, 2024
e117146
Incorporate deforestation semantics tests into surface qi/list tests
countvajhula Aug 8, 2024
81184e7
remove copypasta test
countvajhula Aug 8, 2024
3360d42
Test list forms using higher-order Qi syntax
countvajhula Aug 8, 2024
f7d5e30
Remove unused module providing bindings for deforestation
countvajhula Aug 8, 2024
7f87f94
Fix syntax error in benchmarks
countvajhula Aug 8, 2024
617858a
Remove Racket `range` import in benchmarks
countvajhula Aug 8, 2024
81c9f5d
test the expansion of `#%deforestable`
countvajhula Aug 9, 2024
b6d3a7f
Test syntax error using `range` with no arguments
countvajhula Aug 9, 2024
1140870
Tests for `list-ref`
countvajhula Aug 9, 2024
f439d08
Add a test for a syntax error utility
countvajhula Aug 9, 2024
eb5e395
Modify a `range` test to use syntax with an explicit bound argument
countvajhula Aug 9, 2024
48cdb8e
Update deforestation rules tests
countvajhula Aug 9, 2024
ecb5856
Add a commented-out failing test for a case of desired deforestation
countvajhula Aug 11, 2024
14c41d9
refile the failing test (it now passes)
countvajhula Aug 11, 2024
9d72acd
Use `define-dsl-syntax` instead of `define-qi-syntax`
countvajhula Nov 16, 2024
0ee3d18
Integrate POC extension of deforestation to implement `map`
countvajhula Nov 22, 2024
e84d87f
Add a `name` argument to `define-deforestable`
countvajhula Nov 22, 2024
39d0aba
`make` target to run just `qi/list` tests
countvajhula Nov 22, 2024
4d29ede
translate `filter` to use `define-deforestable`
countvajhula Nov 22, 2024
ce964f0
translate `filter-map` to use `define-deforestable`
countvajhula Nov 22, 2024
0db81b0
translate `foldl` and `foldr`
countvajhula Nov 22, 2024
1a5e4d1
translate `take` to use `define-deforestable`
countvajhula Nov 22, 2024
ae06392
format like ordinary definitions
countvajhula Nov 23, 2024
2e376f9
fix ignored variable name
countvajhula Nov 23, 2024
45f29ec
adopt style suggestion from Ben / resyntax (cr)
countvajhula Nov 23, 2024
19d5068
translate `car`, `cad*r` etc., and `list-ref`
countvajhula Nov 23, 2024
a5f2652
declare `deforestable2` as a datum literal
countvajhula Nov 23, 2024
8a5d650
translate `length` to use `define-deforestable`
countvajhula Nov 23, 2024
f6cecbb
translate `empty?` and (its alias) `null?` to `define-deforestable`
countvajhula Nov 23, 2024
c047a01
Use the "clever hack" to translate `range`
countvajhula Nov 23, 2024
0df7823
Be cleverer in hiding the "clever hack"
countvajhula Nov 23, 2024
3f8a7c4
adopt `syntax-parse` idiom for errors (cr)
countvajhula Nov 23, 2024
c9db34c
Fully replace `#%deforestable` with the new implementation
countvajhula Nov 23, 2024
607bd65
Improve handling of identifier forms of deforestable syntax
countvajhula Nov 29, 2024
85ef9e7
declare `#%deforestable` as a literal in `fs-literals` (cr)
countvajhula Nov 30, 2024
61f6561
Improve error message when a form is used as an identifier
countvajhula Nov 30, 2024
4d6ed0d
Merge pull request #185 from countvajhula/defining-deforestable-opera…
countvajhula Dec 6, 2024
186841d
Support `lambda` (and `λ`) as a core form
countvajhula Jun 29, 2024
0c504f2
Remove unused utility
countvajhula Jun 29, 2024
72f8031
doc: the new `lambda` form
countvajhula Aug 9, 2024
4a45a19
Merge pull request #177 from countvajhula/lambda-core-form
countvajhula Dec 7, 2024
ccb54b4
formally document the syntax
countvajhula Dec 17, 2024
9e7f781
distinguish core and macro forms in full syntax
countvajhula Dec 17, 2024
d6d43aa
link `floe` to the tech definition instead of the containing section
countvajhula Dec 17, 2024
723352f
update intro in qi/list docs
countvajhula Dec 20, 2024
9dd488c
Merge pull request #186 from countvajhula/update-docs-for-deforestable
countvajhula Dec 20, 2024
7e94a65
Update list-operations scribblings.
dzoep Dec 27, 2024
00e1da6
Merge pull request #187 from dzoep/deforest-all-the-things
dzoep Dec 27, 2024
62cdc19
address code review comments re: docs
countvajhula Dec 27, 2024
8b71624
doc: distinguish `floe` from `flow`
countvajhula Dec 28, 2024
9dff1ae
cr: add `range` syntax variants that were missing
countvajhula Dec 28, 2024
efe3268
change deforestable "spec" syntax
countvajhula Dec 28, 2024
760f517
Merge pull request #188 from countvajhula/address-code-review
countvajhula Dec 28, 2024
db48273
Add Makefile target to use the "preview" profile in `vlibench`
countvajhula Dec 14, 2024
db7fe61
Improve Makefile targets for testing
countvajhula Dec 14, 2024
6797eb3
test a few cases that weren't covered
countvajhula Jan 1, 2025
04589f2
Add `#%deforestable` to the de-expander
countvajhula Jan 1, 2025
17fafe7
test for de-expanding `#%deforestable`
countvajhula Jan 2, 2025
6bf3e07
wrap benchmarks with lambda to accommodate new `range`
countvajhula Jan 3, 2025
ffc767e
Address "unused dependencies" warnings (fix #174)
countvajhula Jan 3, 2025
4b1ba3f
Use of left-threading for list operations in docs
countvajhula Jan 6, 2025
07ecec5
Add competitive benchmark for take of 1/3 the input size.
dzoep Jan 11, 2025
1753277
rename "impl" modules to "runtime", as discussed some time ago
countvajhula Jan 14, 2025
3d661fb
add back symbolic aliases that got dropped at some point
countvajhula Jan 16, 2025
f84dc92
Add COPYING file containing public domain dedication
countvajhula Jan 16, 2025
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 .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Check Dependencies
run: make check-deps
- name: Run Tests
run: make test
run: make test-all
coverage:
needs: test
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This is free and unencumbered software released into the public domain.
The authors relinquish any copyright claims on this work.
26 changes: 23 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ build-all:
build-standalone-docs:
scribble +m --redirect-main http://pkg-build.racket-lang.org/doc/ --htmls --dest ./docs ./qi-doc/scribblings/qi.scrbl

build-sdk:
raco setup --no-docs --pkgs $(PACKAGE-NAME)-sdk

# Note: Each collection's info.rkt can say what to clean, for example
# (define clean '("compiled" "doc" "doc/<collect>")) to clean
# generated docs, too.
Expand All @@ -113,15 +116,21 @@ clean-sdk:
check-deps:
raco setup --no-docs $(DEPS-FLAGS) $(PACKAGE-NAME)

test-all: test test-probe

# Suitable for both day-to-day dev and CI
# Note: we don't test qi-doc since there aren't any tests there atm
# and it also seems to make things extremely slow to include it.
test:
raco test -exp $(PACKAGE-NAME)-{lib,test,probe}
test: build
raco make -l qi/tests/qi -v
raco test -exp $(PACKAGE-NAME)-{lib,test}

test-flow:
racket -y $(PACKAGE-NAME)-test/tests/flow.rkt

test-list:
racket -y $(PACKAGE-NAME)-test/tests/list.rkt

test-on:
racket -y $(PACKAGE-NAME)-test/tests/on.rkt

Expand Down Expand Up @@ -211,6 +220,17 @@ new-benchmarks:
--dest-name index.html \
report.scrbl

new-benchmarks-preview:
cd qi-sdk/benchmarks/competitive && \
scribble \
++convert svg \
++arg -p \
++arg preview \
--html \
--dest results \
--dest-name index.html \
report.scrbl

benchmark-local:
racket $(PACKAGE-NAME)-sdk/benchmarks/local/report.rkt

Expand All @@ -234,4 +254,4 @@ performance-report:
performance-regression-report:
@racket $(PACKAGE-NAME)-sdk/benchmarks/report.rkt -r $(REF)

.PHONY: help install remove build build-docs build-all clean check-deps test test-flow test-on test-threading test-switch test-definitions test-macro test-util test-expander test-compiler test-probe test-with-errortrace errortrace errortrace-flow errortrace-on errortrace-threading errortrace-switch errortrace-definitions errortrace-macro errortrace-util errortrace-probe docs cover coverage-check coverage-report cover-coveralls profile new-benchmarks benchmark-local benchmark-loading benchmark-selected-forms benchmark-competitive benchmark-nonlocal benchmark performance-report performance-regression-report
.PHONY: help install remove build build-docs build-all clean check-deps test-all test test-flow test-on test-threading test-switch test-definitions test-macro test-util test-expander test-compiler test-probe test-with-errortrace errortrace errortrace-flow errortrace-on errortrace-threading errortrace-switch errortrace-definitions errortrace-macro errortrace-util errortrace-probe docs cover coverage-check coverage-report cover-coveralls profile new-benchmarks new-benchmarks-preview benchmark-local benchmark-loading benchmark-selected-forms benchmark-competitive benchmark-nonlocal benchmark performance-report performance-regression-report
4 changes: 3 additions & 1 deletion qi-doc/scribblings/field-guide.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ Qi aims to produce good error messages that convey what the problem is and clear

@bold{Common example}: Attempting to use a Qi macro in one module without @racketlink[provide]{providing} it from the module where it is defined -- note that Qi macros must be provided as @racket[(provide (for-space qi mac))]. See @secref["Using_Macros" #:doc '(lib "qi/scribblings/qi.scrbl")] for more on this.

@subsubsection{Contract Violation}
@subsubsection{@racket[map]/@racket[filter] Contract Violation}

@codeblock{
; map: contract violation
Expand All @@ -308,6 +308,8 @@ 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 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}.

@subsubsection{Compose: Contract Violation}
Expand Down
115 changes: 111 additions & 4 deletions qi-doc/scribblings/forms.scrbl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@require[scribble/manual
scribble-abbrevs/manual
scribble/example
metapict ; technically only used dynamically, but adding here for info deps
"eval.rkt"
@for-label[(only-space-in qi qi)
racket]]
Expand All @@ -14,10 +15,102 @@

@title[#:tag "Qi_Forms"]{The Qi Language}

The core syntax of the Qi language. These forms may be used in any @tech{flow}. Flows may be specified in Racket via the @seclink["Language_Interface"]{language interface}.
The syntax and semantics of the Qi language. Qi @tech{flows} may be described using these forms and @seclink["Embedding_a_Hosted_Language"]{embedded} into Racket using the @seclink["Language_Interface"]{language interface}.

@table-of-contents[]

@section{Syntax}

The syntax of a language is most economically and clearly expressed using a grammar, in the form of "nonterminal" symbols along with production rules expressing the syntax that is entailed in positions marked by those symbols. We may thus take the single starting symbol in such a grammar to formally designate the entire syntax of the language.

The symbol @racket[expr] is typically used in this sense to indicate a Racket nonterminal position in the syntax, i.e., a position that expects a Racket expression. Analogously, we use the identifier @deftech{@racket[floe]} (pronounced "flow-e," for "flow expression") to refer to the Qi nonterminal, i.e., a position expecting Qi syntax.

@tech{floe} is not to be confused with @tech{flow}. The relationship between the two is one of syntax and semantics, that is, the meaning of a @tech{floe} is a @tech{flow}.

The full surface syntax of Qi is given below. Note that this expands to a @seclink["The_Qi_Core_Language"]{smaller core language} before being @seclink["It_s_Languages_All_the_Way_Down"]{compiled to Racket}. It does not include the @seclink["List_Operations"]{list-oriented forms}, which may be added via @racket[(require qi/list)].

@racketgrammar*[
[floe @#,seclink["The_Qi_Core_Language"]{core-form}
macro-form]
[macro-form △
(one-of? expr ...)
(and% floe ...)
(or% floe ...)
AND
&
OR
NOR
NAND
XNOR
any?
all?
none?
inverter
(~> floe ...)
(~>> floe ...)
(thread-right floe ...)
X
crossover
==
(== floe ...)
(==* floe ...)
(relay* floe ...)
-<
(-< floe ...)
count
1>
2>
3>
4>
5>
6>
7>
8>
9>
(bundle (index ...) floe floe)
(when floe floe)
(unless floe floe)
switch
(switch switch-expr ...)
(switch (% floe) switch-expr ...)
(switch (divert floe) switch-expr ...)
(gate floe)
><
(>< floe)
(ε floe floe)
(effect floe floe)
apply
(expr expr ... __ expr ...)
(expr expr ... _ expr ...)
(expr expr ...)
literal
identifier]
[literal boolean
benknoble marked this conversation as resolved.
Show resolved Hide resolved
char
string
bytes
number
regexp
byte-regexp
vector-literal
box-literal
prefab-literal
(@#,racket[quote] value)
(@#,racket[quasiquote] value)
(@#,racket[quote-syntax] value)
(@#,racket[syntax] value)]
[expr a-racket-expression]
[index exact-positive-integer?]
[nat exact-nonnegative-integer?]
[switch-expr [floe floe]
[floe (=> floe)]
[else floe]]
[identifier a-racket-identifier]
[value a-racket-value]]

@section{Basic}

@defidform[_]{
Expand Down Expand Up @@ -100,6 +193,20 @@ The core syntax of the Qi language. These forms may be used in any @tech{flow}.
]
}

@deftogether[(
@defform[(lambda expr ...)]
@defform[(λ expr ...)]
)]{
Shorthand for @racket[(esc (lambda ...))].

That is, this lambda is a @emph{Qi} form that expands to a use of @emph{Racket}'s lambda form, providing a shorthand for a common way to describe a flow using Racket.

@examples[
#:eval eval-for-docs
((☯ (λ (x) (+ 2 x))) 3)
]
}

@defform[(clos flo)]{
A @tech{flow} that generates a flow as a value. Any inputs to the @racket[clos] flow are available to @racket[flo] when it is applied to inputs, i.e. it is analogous to a @hyperlink["https://www.gnu.org/software/guile/manual/html_node/Closure.html"]{closure} in Racket.

Expand Down Expand Up @@ -514,9 +621,9 @@ A form of generalized @racket[sieve], passing all the inputs that satisfy each
[(switch maybe-divert-expr switch-expr ...)]
([maybe-divert-expr (divert condition-gate-flow consequent-gate-flow)
(% condition-gate-flow consequent-gate-flow)]
[switch-expr [flow-expr flow-expr]
[flow-expr (=> flow-expr)]
[else flow-expr]])]{
[switch-expr [floe floe]
[floe (=> floe)]
[else floe]])]{
The @tech{flow} analogue of @racket[cond], this is a dispatcher where the condition and consequent expressions are all flows which operate on the switch inputs.

Typically, each of the component flows -- conditions and consequents both -- receives all of the original inputs to the @racket[switch]. This can be changed by using a @racket[divert] clause, which takes two flow arguments, the first of whose outputs go to all of the condition flows, and the second of whose outputs go to all of the consequent flows. This can be useful in cases where multiple values flow, but only some of them are predicated upon, and others (or all of them) inform the actions to be taken. Using @racket[(divert _ _)] is equivalent to not using it. @racket[%] is a symbolic alias for @racket[divert] -- parse it visually not as the percentage sign, but as a convenient way to depict a "floodgate" diverting values down different channels.
Expand Down
Loading
Loading