Repository navigation
Expand file tree
/
Copy pathabout.cfm
More file actions
232 lines (217 loc) · 10.5 KB
/
Copy pathabout.cfm
File metadata and controls
232 lines (217 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<cfscript>
request.section = "about";
request.title = "About: background, aims and architecture";
request.desc = "Why RustCFML exists, what it refuses to become, how it is put together, and honest answers about compatibility with the CFML you already know.";
icons = new lib.Icons();
</cfscript>
<cfinclude template="includes/_head.cfm">
<cfinclude template="includes/_header.cfm">
<section class="page-hero">
<div class="wrap">
<cfoutput>
<h1>A language runtime, rewritten once</h1>
<p class="lead">
CFML is still being written, still being maintained, and until recently had only JVM
runtimes to run on. RustCFML is an attempt at the other option: the same language, a
native binary, and documentation that says where it does not work.
</p>
</cfoutput>
</div>
</section>
<!-- ==================================================================== -->
<!-- Story -->
<!-- ==================================================================== -->
<section>
<div class="wrap">
<div class="split">
<cfoutput>
<div class="split-text">
<h3>It began as a question about models</h3>
<p>
<a href="#( application.repo )#" rel="noopener">RustCFML</a> started as a proof of
how capable AI models had become, begun by
<a href="https://github.com/alexskinner" rel="noopener">Alex Skinner</a>.
The engine has been written almost entirely by AI, predominantly Claude Opus, with research and
test synthesis assisted by local models.
</p>
<p>
Rust was not an arbitrary choice of host language. Its compiler rejects unsound
code immediately and specifically, which is what makes it a good substrate for
AI-assisted work: a stochastic generator becomes something that converges, because
every wrong turn comes back as an error a model can act on. CFML sits at the other end of the same idea: a powerful,
forgiving language with one obvious way to do most things, which is why models emit
it correctly and why people learn it quickly.
</p>
<p>
There is a test suite
that has to pass against Lucee, a compatibility target published in cfdocs, a
licence that is genuinely permissive, and a written account of everything that does
not work yet.
</p>
</div>
</cfoutput>
<div class="term reveal">
<div class="term-bar"><span class="dot"></span><span class="dot"></span><span class="dot"></span><span class="term-name">the pipeline</span></div>
<pre class="term-body"><code><span class="tk-com">// CFML source, all the way down to native code.</span>
.cfm / .cfc
→ tag preprocessor
→ CFScript
→ lexer
→ parser
→ AST
→ compiler
→ bytecode
→ VM <span class="tk-com">( bytecode cached per template )</span>
<span class="tk-com">// A Cargo workspace of focused crates:</span>
cfml-common cfml-compiler cfml-codegen
cfml-vm cfml-stdlib cli
cfml-qoq wasm</code></pre>
</div>
</div>
</div>
</section>
<!-- ==================================================================== -->
<!-- Aims -->
<!-- ==================================================================== -->
<section class="tint">
<div class="wrap">
<div class="section-head reveal">
<h2>Five opinions, held deliberately</h2>
<p class="lead">These are the reasons the engine is smaller than you might expect.</p>
</div>
<div class="grid grid-2">
<cfoutput>
<div class="card reveal">
<div class="card-ico">#( icons.get( "shield" ) )#</div>
<h3>A lean, stable core</h3>
<p>Nothing gets added to the core that doesn't belong or is prone to constant churn in the wider ecosystem. Think of it as an LTS-style engine: reliability first, and already fast enough that speed is not the constraint.</p>
</div>
<div class="card reveal">
<div class="card-ico">#( icons.get( "package" ) )#</div>
<h3>Libraries over built-ins</h3>
<p>Where a capability is better served by a library, it stays out of the core. What the engine does is make sure it is compatible enough to <em>run</em> those libraries.</p>
</div>
<div class="card reveal">
<div class="card-ico">#( icons.get( "grid" ) )#</div>
<h3>No administrator, ever</h3>
<p>There is no web console and there never will be. Configuration is a file, <code class="inline">.cfconfig.json</code>, with environment-variable substitution for secrets, so your settings live in version control and your deploy pipeline.</p>
</div>
<div class="card reveal">
<div class="card-ico">#( icons.get( "refresh" ) )#</div>
<h3>Inspired by real apps</h3>
<p>Features are driven by applications people are trying to run, and by modern deployment practice.</p>
</div>
<div class="card reveal">
<div class="card-ico">#( icons.get( "info" ) )#</div>
<h3>Honest about Java</h3>
<p>There is no JVM under the hood, so the classes applications actually reach for are hand-written shims instead: over a hundred of them, across <code class="inline">java.lang</code>, <code class="inline">java.util</code>, <code class="inline">java.util.concurrent</code>, <code class="inline">java.security</code>, <code class="inline">java.text</code> and <code class="inline">java.time</code>, plus the third-party libraries frameworks depend on. Enough that CFWheels and Preside run without application changes. They are emulations rather than the JDK, though: the goal is to run the libraries, not to reimplement Java. Every gap is written down.</p>
</div>
<div class="card reveal">
<div class="card-ico">#( icons.get( "check" ) )#</div>
<h3>Compatible, verifiably</h3>
<p>The target is cfdocs.org with Lucee as the reference implementation, and a suite that runs against both. Compatibility is something the project checks, not something it claims.</p>
</div>
</cfoutput>
</div>
</div>
</section>
<!-- ==================================================================== -->
<!-- Architecture -->
<!-- ==================================================================== -->
<section>
<div class="wrap">
<div class="section-head reveal">
<h2>Where the speed comes from</h2>
<p class="lead">A preprocessor, a compiler and a bytecode VM: the same shape every serious language runtime has, minus the host virtual machine underneath it.</p>
</div>
<cfoutput>
<div class="pipeline reveal">
<span>.cfm / .cfc</span><em>→</em>
<span class="hi">tag preprocessor</span><em>→</em>
<span>CFScript</span><em>→</em>
<span>lexer</span><em>→</em>
<span>parser</span><em>→</em>
<span>AST</span><em>→</em>
<span class="hi">compiler</span><em>→</em>
<span>bytecode</span><em>→</em>
<span class="hi">VM</span>
</div>
<div class="grid grid-3" style="margin-top:32px">
<div class="card reveal">
<span class="tag">crates/cfml-common</span>
<h3>Shared ground</h3>
<p>The types, scopes and utilities every other crate needs, so the parser and the VM never disagree about what a query is.</p>
</div>
<div class="card reveal">
<span class="tag">crates/cfml-compiler</span>
<h3>Front end</h3>
<p>Tag preprocessing, lexing, parsing and AST construction. Fifty-plus tags become CFScript before anything is compiled.</p>
</div>
<div class="card reveal">
<span class="tag">crates/cfml-codegen</span>
<h3>To bytecode</h3>
<p>AST to stack-based bytecode, cached per template so an unchanged file is never compiled a second time.</p>
</div>
<div class="card reveal">
<span class="tag">crates/cfml-vm</span>
<h3>Execution</h3>
<p>The interpreter, the component model, threading and the async runtime that serves your requests.</p>
</div>
<div class="card reveal">
<span class="tag">crates/cfml-stdlib</span>
<h3>Four hundred functions</h3>
<p>The built-in library: strings, dates, JSON, hashing, database, mail, HTTP, spreadsheets and images.</p>
</div>
<div class="card reveal">
<span class="tag">crates/cfml-qoq</span>
<h3>SQL for queries</h3>
<p>Query-of-queries on a pure-Rust SQL engine, parallelised with rayon. No JDBC, no embedded Java database.</p>
</div>
</div>
<p class="small muted" style="margin-top:22px">
Deeper, including the memory model and the extension ABI:
<a href="#( application.docsBlob )#architecture.md" rel="noopener">docs/architecture.md</a>.
</p>
</cfoutput>
</div>
</section>
<!-- ==================================================================== -->
<!-- FAQ -->
<!-- ==================================================================== -->
<section class="tint">
<div class="wrap">
<div class="section-head reveal">
<h2>The ones that come up every time</h2>
</div>
<cfoutput>
<cfloop array="#application.faq#" item="entry">
<details class="faq-item reveal">
<summary>#( entry.q )#</summary>
<div class="faq-body"><p>#( entry.a )#</p></div>
</details>
</cfloop>
</cfoutput>
</div>
</section>
<!-- ==================================================================== -->
<!-- CTA -->
<!-- ==================================================================== -->
<section>
<div class="wrap">
<cfoutput>
<div class="cta reveal">
<h2>Read the source, it is only Rust</h2>
<p>
Everything is in one repository: the interpreter, the documentation, the tests that
run against Lucee, and the issue tracker where the hard decisions get made in public.
</p>
<div class="btn-row">
<a class="btn btn-primary btn-lg" href="#( application.repo )#" rel="noopener">#( icons.get( "github" ) )# RustCFML on GitHub</a>
<a class="btn btn-secondary btn-lg" href="/download">Download #( application.version )#</a>
<a class="btn btn-ghost btn-lg" href="/features">See what it does</a>
</div>
</div>
</cfoutput>
</div>
</section>
<cfinclude template="includes/_footer.cfm">