-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
688 lines (511 loc) · 35.1 KB
/
index.html
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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
<!DOCTYPE html>
<html>
<head>
<title>Carbide Alpha | Buggy But Live!</title>
<link rel="stylesheet" type="text/css" href="static/css/main.css">
<link rel="stylesheet" type="text/css" href="static/css/splash.css">
<link rel="stylesheet" type="text/css" href="static/css/quick.css">
<link rel="stylesheet" type="text/css" href="static/css/examples.css">
<link rel="stylesheet" type="text/css" href="static/css/docs.css">
<link rel="stylesheet" type="text/css" href="static/css/prior-art.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/themes/prism.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400,600">
</head>
<body>
<div id='header'>
<!-- <div>Alpha Release | Don't mind the bugs!</div> -->
<div class='spacer'></div>
<a href="#quick">Quick Start</a>
<a href="#examples">Examples</a>
<!-- <a href="//alpha.trycarbide.com/anonymous">Anonymous</a> -->
<a href="//alpha.trycarbide.com/me">Mine</a>
<a href="//alpha.trycarbide.com/new">New</a>
</div>
<div id="splash">
<div id='intro'>
<div>
<div id='title'>
<svg id='logo' viewBox="0 0 105 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Artboard-3-Copy-7" transform="translate(-1310.000000, -92.000000)">
<path d="M1410.78688,128.032486 L1383.05486,146.729325 C1377.21873,138.540677 1364.81247,137.512795 1357.6388,144.602599 C1350.86511,151.296015 1351.54391,162.548954 1359.04157,168.449597 C1367.22735,174.891419 1379.85151,172.091625 1384.3881,162.850724 L1414.78086,176.972987 C1409.47945,189.283197 1398.21003,203.565305 1373.3674,204.646229 L1374.60244,219.81286 C1353.7674,216.799461 1334.70715,203.472839 1328.03452,183.581822 L1315.14013,192.182626 C1311.18271,182.480111 1309.75414,171.799173 1311.38198,161.458712 C1312.95534,151.459444 1317.3801,142.492359 1324.10721,134.839873 L1310,128.284797 C1316.62317,120.548447 1324.48854,114.19694 1334.10289,110.276081 C1343.95594,106.257737 1355.04186,104.982562 1365.52066,107.166631 L1364.28635,92 C1385.02175,95.0004971 1404.0863,108.238954 1410.78688,128.032486" id="Fill-1"></path>
</g>
</svg>
<div>
<h1><b>Carbide</b> Alpha</h1>
</div>
</div>
<p>
Carbide is <b>a new kind of programming environment</b> which <small>(as obligatory in this day and age)</small>:
<ul>
<li>Requires <b>no installation</b> or <b>setup</b></li>
<li>Supports <b>Javascript</b>/<b>ES2015</b></li>
<li>Imports modules <b>automatically</b> from <b>NPM</b> or <b>GitHub</b></li>
<li><b>Saves</b> and <b>loads</b> directly to and from <b>GitHub Gists</b></li>
<!-- <li>Is built for Notebook Programming</li> -->
<!-- <li>Can run your code in an <b>external window</b></li> -->
</ul>
But wait, there's more...
</p>
</div>
<div class='demo'>
<img src="static/img/chrome.png"/>
<img src="static/img/tree.png"/>
</div>
</div>
<div id='crazy'>
<div class='demo'>
<img src="static/img/chrome.png"/>
<img src="static/img/noshadow-fahrenheit.gif"/>
</div>
<div>
<p>
<h2>...Crazy Stuff</h2>
<ul>
<li>Comments live in a <b>Rich Text</b> sidebar <b>#LiterateProgramming</b></li>
<li>Carbide shows results <b>in-between</b> the lines of your code— letting you <b>see data in context</b></li>
<li>The result of any expression can be <b>logged, visualized</b>, and <b>directly manipulated</b> with powerful <small>(and shiny)</small> <b>widgets</b></li>
<li>Carbide doesn't distinguish between <b>input</b> and <b>output</b>, using generalized <b>machine learning</b> techniques to run programs <b>backwards</b></li>
</ul>
</p>
</div>
</div>
<div id='outro'>
Carbide is pretty weird <small>(not just because it's still fairly buggy)</small>, so we highly recommend at least skimming the <a href='#quick'>Quick Start Guide</a>. <small>But if you're <i>truly</i> an unstoppable force, you can also <a href='#examples'>jump straight to some examples</a>.</small>
</div>
</div>
<div id='quick'>
<div id='quick-content'>
<div id='quick-pointer'></div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/two-plus-two.mp4'></video>
<div class="ineedtopee">
<h1>Quick Start</h1>
At the end of this guide there will be links to <a href='#examples'>example notebooks</a>.
<h2>Running Code</h2>
<p image='static/mp4/two-plus-two.mp4'>
Running code in Carbide is as simple as hitting the <b>"Run"</b> button located on the bottom right of any cell</b>. You can also quickly run the current cell with (<b>Cmd-Enter</b>).
</p>
<!--<p>
Carbide is a notebook programming environment, so documents are organized into different "cells". Each cell can be executed independently (but can import from other modules).
</p>-->
<p>
Currently Carbide supports the latest version of <b>Javascript</b>, known as ES2015 through built-in support for BabelJS. You can even use ES7's <b>async/await</b> features without wrapping your code in functions.
</p>
<p>
In addition to running code locally within the editor, you can choose to <b>run code within a separate window</b> (this is nice for building out apps which need access to the DOM). To switch to this mode, click on the <b>language dropdown</b> on the top of the page, and select "<b>Javascript (Separate Window)</b>".
</p>
<p>
We haven't launched support for other programming languages yet (rest assured it's on <a href="#roadmap">our roadmap</a>).
</p>
</div>
</div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/attaching-probes.mp4'></video>
<div class="ineedtopee">
<h2>Attaching Probes</h2>
<p image='static/mp4/attaching-probes.mp4'>
In Carbide, you see the results of running your program in "probes" which are displayed <b>in between the lines</b> of your code.
</p>
<p>
You can <b>inspect any expression</b> by selecting it and hitting <b>Cmd-I</b>.
</p>
<p>
Rather than littering your code with print statements and breaking up nested expressions, or painstakingly stepping through with a traditional debugger, it’s easy to see an overview of all the values as they flow through a program.
</p>
<p>
As a convenience, the outermost expression on any line is automatically logged, and a widget is shown for the last expression of the cell.
</p>
</div>
</div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/lots-of-widgets.mp4'></video>
<div class="ineedtopee">
<h2>Visualization Widgets</h2>
<p image='static/mp4/lots-of-widgets.mp4'>
When you want to see more than the basic summary probes show you, you can <b>click any probe</b> to open a "widget", which appears to the right of your code.
</p>
<p>
<b>Hovering over a widget</b> expands a tab bar on top, which allows you to <b>switch between different representations</b> of your data. A string like "orange" can be visualized as color, as plain text, or as JSON, and widgets allow you to easily switch between them.
</p>
<p>
Beyond simply looking at a piece of data, visualization widgets can also incorporate knowledge of your code's abstract syntax tree. This allows us to visualize <tt>array[0]</tt> as a selector into the array, or <tt>“house” == “horse”</tt> as an interactive string comparison, rather than the uninformative <tt>false</tt>.
</p>
<p>
You can see more examples of these kinds of widgets in the <a href='#menagerie'>Widget Menagerie</a> section.
</p>
</div>
</div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/murrica.mp4'></video>
<div class="ineedtopee">
<h2>Manipulation Widgets</h2>
<p image='static/mp4/murrica.mp4'>
The <b>exact same widgets</b> which were used for visualizing data can also be used for <b>manipulating data</b>. This is an idea which really lies at the heart of what Carbide is— peeling away the one-way mirror found in most data visualization tools which forces you to look and not touch.
</p>
<p>
For example, we could represent the number "42" as a slider with the bounds set between 0 and 100. As a visualization, this gives me some spatial sense of how large this number is. When I drag the slider, it would make sense for the part of the code which said "42" to be replaced with the new value.
</p>
<p>
We start to get into trouble when the "42" isn't actually found in the code, and values are computed rather than literal. To figure this out we have to essentially <b>run the program backwards</b>— fixing the outputs, and solving for the inputs. To do this, we use a technique from machine learning, called backpropagation. If you're interested, there's a <a href="#backprop">longer technical explanation</a> of what it is and how it works below.
</p>
</div>
</div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/inserting-cells.mp4'></video>
<div class="ineedtopee">
<h2>Multiple Cells</h2>
<p image='static/mp4/inserting-cells.mp4'>
Carbide is a <b>notebook programming environment</b>, which means that the code is stuck into little boxes called cells. Each cell is a little playground where you can build stuff, aided by all the fancy tools for seeing, poking, and prodding.
</p>
<p>
To <b>insert a cell</b>, click in the area either immediately <b>before or after a cell</b>.
</p>
<p>
Unlike most other notebook programming systems, you'll find yourself needing to make cells much less frequently in Carbide because you don't need to break up your program into multiple cells to visualize what's going on.
</p>
<p>
With multiple cells you can <b>try out multiple approaches</b> to a given problem at <b>the same time</b> without necessarily committing to any particular change.
</p>
<p>
<b>Each cell has a file name</b>, which is shown in the cell toolbar on the bottom of each cell. This filename comes into play when sharing information between cells with the ES6 <tt>import/export</tt> syntax.
</p>
<pre><code class="language-javascript">// cell0.js
export default 420 </code></pre>
<pre><code class="language-javascript">// cell1.js
import data from './cell0.js'
data + 2 </code></pre>
</div>
</div>
<div class="quickblock">
<video class="jetengine" autoplay loop src='static/mp4/saving-gist.mp4'></video>
<div class="ineedtopee">
<h2>Saving and Sharing</h2>
<p image='static/mp4/saving-gist.mp4'>
Currently, <b>all Carbide notebooks</b> are represented as <b>public GitHub Gists</b>.
</p>
<p>
If you are <b>not logged in</b>, hitting Cmd-S or pressing the "Save" button creates a new Gist under the <a href="https://gist.github.com/carbide-public">carbide-public</a> account.
If you <b>are logged in</b>, the gist will be saved under your own personal GitHub account.
</p>
<p>
Notebooks are represented in a nice human-readable plain text format: each cell corresponds to a different file, with a markdown header file containing all the metadata as a comment.
</p>
</div>
</div>
</div>
</div>
<div id='examples'>
<h1>Example Notebooks</h1>
<div id="examples-container">
<a class='example' href="http://alpha.trycarbide.com/@antimatter15/fc142480d3c824b0b98130650b896497">
<div class="example-blurb">
<h2>Smiley Face</h2>
Draw a smiley face!
</div>
<div class="example-img">
<img src="static/img/smile.png"/>
</div>
</a>
<a class='example' href="http://alpha.trycarbide.com/@antimatter15/b7889578bcaf96d3a11a80f5662d971d">
<div class="example-blurb">
<h2>Neural Network XOR</h2>
Drag a slider to train a tiny two layer neural network to approximate the exclusive or function.
</div>
<div class="example-img">
<img src="static/img/xor.png"/>
</div>
</a>
<a class='example' href="http://alpha.trycarbide.com/@bijection/229578b88460f287976e285589ad763a">
<div class="example-blurb">
<h2>THREE.js Cubes Demo</h2>
Many cubes, all floating around your mouse in 3D.
</div>
<div class="example-img">
<img src="static/img/cubes.png"/>
</div>
</a>
<a class='example' href="http://alpha.trycarbide.com/@bijection/50de8e5dbd8cc2ffd3c396aab3d0256d">
<div class="example-blurb">
<h2>GRAIN Data Cleaning</h2>
Import an excel file and clean it up programmatically.
</div>
<div class="example-img">
<img src="static/img/grain.png"/>
</div>
</a>
<a class='example' href="http://alpha.trycarbide.com/@bijection/9b2017391d6509f444c2636d53f1c319">
<div class="example-blurb">
<h2>React TodoMVC</h2>
An es6 adaptation of the popular TodoMVC example app from todomvc.com.
</div>
<div class="example-img">
<img src="static/img/todo.png"/>
</div>
</a>
<a class='example' href="http://alpha.trycarbide.com/@bijection/bae03af5387990320fd8e1efd961397b">
<div class="example-blurb">
<h2>Creating a Youtube Widget</h2>
Add a widget to your notebook that recognizes YouTube video URLs.
</div>
<div class="example-img">
<img src="static/img/youtube.png"/>
</div>
</a>
</div>
<a class='example' href="http://alpha.trycarbide.com/new">
<div class="example-blurb">
<h2>Empty Notebook</h2>
For people who really like the sensation of writer's block.
</div>
<div class="example-img">
<img src="static/img/base.png"/>
</div>
</a>
</div>
</div>
<div id="container">
<div id="table-of-contents-wrap">
<div id="table-of-contents"></div>
</div>
<div id="content-wrap">
<div id="content">
<!--
<h1>Why Carbide?</h1>
<h2>Who is Notebook Programming?</h2>
Notebooks, as opposed to say typewriters, let you sketch your ideas anywhere on the page, however you want. In a noteboook programming environment, you write and run code out of order, and often investigate multiple avenues of attack in parallel.
-->
<h1 id='menagerie'>Widgets</h1>
To try all of these live, visit the <a href="http://alpha.trycarbide.com/@bijection/b1542b3b90cc0b80a56f8393afa46821">Widget Menagerie</a>
<h2>Numbers</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>slider</div><img src="static/img/slide-loop.gif"/></div>
<div class='animal'><div class='animal-name'>integer</div><img src="static/img/integer-loop.gif"/></div>
<div class='animal'><div class='animal-name'>scrubber</div><img src="static/img/scrub-loop.gif"/></div>
</div>
<h2>Strings</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>string</div><img src="static/img/string.png"/></div>
<div class='animal'><div class='animal-name'>string_diff</div><img src="static/img/string-diff.gif"/></div>
<div class='animal'><div class='animal-name'>color</div><img src="static/img/color-loop.gif"/></div>
<div class='animal'><div class='animal-name'>buffer</div><img src="static/img/buffer.png"/></div>
</div>
<h2>Data</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>chart</div><img src="static/img/chart-loop.gif"/></div>
<div class='animal'><div class='animal-name'>surface</div><img src="static/img/surface.gif"/></div>
<div class='animal'><div class='animal-name'>ndarray</div><img src="static/img/ndimage.png"/></div>
<div class='animal'><div class='animal-name'>matrix</div><img src="static/img/matrix.png"/></div>
</div>
<h2>Objects</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>regexp</div><img src="static/img/randexp-loop.gif"/></div>
<div class='animal'><div class='animal-name'>date</div><img src="static/img/date-loop.gif"/></div>
<div class='animal'><div class='animal-name'>json</div><img src="static/img/json.png"/></div>
<div class='animal'><div class='animal-name'>json_diff</div><img src="static/img/json_diff.png"/></div>
</div>
<h2>Basic Widgets</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>date</div><img src="static/img/date-loop.gif"/></div>
<div class='animal'><div class='animal-name'>html</div><img src="static/img/html.png"/></div>
<div class='animal'><div class='animal-name'>map</div><img src="static/img/map.png"/></div>
<div class='animal'><div class='animal-name'>object</div><img src="static/img/object.png"/></div>
<div class='animal'><div class='animal-name'>react</div><img src="static/img/spinner.png"/></div>
<div class='animal'><div class='animal-name'>regex</div><img src="static/img/regex.png"/></div>
<div class='animal'><div class='animal-name'>selector</div><img src="static/img/selector-loop.gif"/></div>
</div>
<h2>Miscellaneous</h2>
<div id='just-call-it-a-zoo'>
<div class='animal'><div class='animal-name'>buffer</div><img src="static/img/buffer.png"/></div>
<div class='animal'><div class='animal-name'>chart</div><img src="static/img/chart.png"/></div>
<div class='animal'><div class='animal-name'>color</div><img src="static/img/color.png"/></div>
<div class='animal'><div class='animal-name'>date</div><img src="static/img/date.png"/></div>
<div class='animal'><div class='animal-name'>html</div><img src="static/img/html.png"/></div>
<div class='animal'><div class='animal-name'>json</div><img src="static/img/json.png"/></div>
<div class='animal'><div class='animal-name'>json_diff</div><img src="static/img/json_diff.png"/></div>
<div class='animal'><div class='animal-name'>map</div><img src="static/img/map.png"/></div>
<div class='animal'><div class='animal-name'>matrix</div><img src="static/img/matrix.png"/></div>
<div class='animal'><div class='animal-name'>object</div><img src="static/img/object.png"/></div>
<div class='animal'><div class='animal-name'>regex</div><img src="static/img/regex.png"/></div>
<div class='animal'><div class='animal-name'>selector</div><img src="static/img/selector.png"/></div>
<div class='animal'><div class='animal-name'>slider</div><img src="static/img/slider.png"/></div>
<div class='animal'><div class='animal-name'>string</div><img src="static/img/string.png"/></div>
<div class='animal'><div class='animal-name'>string_diff</div><img src="static/img/string_diff.png"/></div>
</div>
<h2>Making Your Own Widgets 🎂</h2>
Carbide widgets are just react components (<a href="https://babeljs.io/blog/2015/06/07/react-on-es6-plus">what's a react component</a>) with a static class property <code>title</code> and a static member function called match, with the signature <code>match(value, ast)</code>. Whenever you open a widget on some expression, carbide runs the expressions value and ast through all of the installed widgets' match functions to figure out which widgets it should show in the tabs.
If you have a react component with a static title and match function, you can add it to your notebook like this:
<pre><code class="language-javascript">import React from 'react'
class YOLOWidget extends React.Component {
static title = '#YOLO'
static match(value, ast){
return value === '#YOLO'
}
render(){
return <a href="https://en.wikipedia.org/wiki/YOLO_(motto)">
https://en.wikipedia.org/wiki/YOLO_(motto)
</a>
}
}
doc.kernel.widgets.push(YOLOWidget)</code></pre>
<h1>Backpropagation</h1>
<h2>Numbers</h2>
<img src="static/img/slide-loop.gif">
<p>
For the mathematically minded, you can interpret the entire program as a function whose arguments are the literals in the program, and whose output is the particular inspected expression. The challenge is then to find an assignment to the arguments, such that the output is as close as possible to the desired value. Once that's done, you can substitute those literals back into the code, and you've assembled a new program whose output at that arbitrary expression is what you told it to do.
</p>
<p>
In other words, we're trying to solve for the inverse of a function. Another equivalent (more specific) framing of the problem is that we're optimizing a cost function (the distance between the output and the desired target output) over a space of parameters.
</p>
<p>
Fortunately there's a massive amount of literature available about the problem of unconstrained (or constrained!) minimization. We're currently using a version of NumericJS's <tt>uncmin</tt> function, which implements a quasi-newton method (similar to <a href="https://en.wikipedia.org/wiki/Limited-memory_BFGS">L-BFGS</a>), which is a generalization of Newton's root-finding method to multiple parameters.
</p>
<p>
Quasi-Newton methods need to calculate the gradient of a function at each step to determine which direction to travel toward. Currently this entails evaluating the function several times with slight tweaks to the existing parameters (in the future one could imagine implementing <a href="https://en.wikipedia.org/wiki/Automatic_differentiation">automatic differentiation</a> so one would only need to evaluate once per step).
</p>
<p>
In case the optimization engine ever gets stuck in a place with zero gradient, the previous working parameters are remembered, so each interaction can start with the closest known reasonable point (We know it affectionately as Guillermo "Memo"'s Memoization).
</p>
<h2>Strings</h2>
<img src="static/img/fizzbuzz.gif">
<p>
While there have been many decades of work done on improving numerical optimization, there isn't nearly as much work done on generalizing the idea to other data structures.
</p>
<h2>Nested Objects</h2>
<p>
IM GOING TO WRITE ABOUT THIS REAL SOON NOW
</p>
<h2>Declared Inverses</h2>
<p>
IM GOING TO WRITE ABOUT THIS REAL SOON NOW
</p>
<h2>Cascading Approaches</h2>
<p>
IM GOING TO WRITE ABOUT THIS REAL SOON NOW
</p>
<h1>Technology</h1>
<p>
There's a fair amount of tekmology and stuff that goes into Carbide, and to be totally honest, we totally pulled an all nighter trying to write copy for this website, and there's a lot of detail that we don't really have time to include. But hopefully over the coming weeks, we'll be able to publish some blog posts going into a bit more technical depth.
</p>
<h2>SystemJS/JSPM</h2>
<p>
NPM is probably one of the largest and most successful package managers ever created (albeit not without a few <a href="http://www.haneycodes.net/npm-left-pad-have-we-forgotten-how-to-program/">kerfuffles</a>). So it was pretty important to be able to easily import modules from NPM.
</p>
<p>
Originally, we had written our own tiny implementation of NPM which would run in the browser (calling the official NPM API endpoint, locating tarballs, unpacking them in the browser, and loading the files appropriately). Separately, we were using Babel and Webpack to develop the application itself.
</p>
<p>
But over the past few months we discovered <a href="https://github.com/systemjs/systemjs">SystemJS</a>, and ended up using JSPM to handle just about everything. In fact, nowadays Carbide's "Current Window" mode uses the same SystemJS loader for both the editor itself and the code which gets executed on it. This means that it'll technically be able to self-host, hot-reload, and instrument various parts of itself. That's kinda neat.
</p>
<h2>BabelJS</h2>
<p>
Most browsers don't quite support all the latest features and proposals that people have drafted up, so in order to use the latest and greatest syntax and semantics, people have to use programs called "transpilers" which translate the source code of one language and into another one.
</p>
<p>
But far more important— as far as Carbide is concerned, is just being able to have access to the abstract syntax tree of a chunk of code, and being able to instrument certain ranges.
</p>
<h2>Top-Level Async/Await</h2>
<p>
<img src="static/img/await.png" style="width: 40%; float: right">
To make everyone's life easier, Carbide cheats a bit and allows you to use the <tt>await</tt> keyword in the top level, as if you were writing an async function. The way this works under the hood is basically by detecting top level awaits, and wrapping your entire cell in an async function if it finds them.
</p>
<p>
We've broken out the Babel transform that does this into <a href='https://github.com/eponymous-labs/babel-plugin-top-level-await'>its own repo</a>.
</p>
<h2>Hot Reloading</h2>
<p>
<a href="https://github.com/gaearon/react-hot-loader">Hot reloading</a> is really neat, and it's rapidly become a staple of modern Javascript development (to whatever extent you can string those words together and pretend it's a phrase). But it's actually key to creating a fun interactive programming environment— being able to substitute modules without running everything from scratch.
</p>
<p>
To accomplish this we've built our own Hot Reloading engine on top of JSPM. It's less aggressive in reloading dependents than the <a href="https://github.com/capaj/systemjs-hot-reloader">SystemJS hot reloader</a> and the <a href="https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack">Webpack Hot module replacement</a> system. It exploits the fact that in ES6, references are "live" so imports can be updated simply by calling a getter.
</p>
<p>
However, sometimes you actually do want Webpack's aggressive reloading of dependents— this can be done by exporting a variable <code>__forceReload</code>.
</p>
<pre><code class="language-javascript">export const __forceReload = true</code></pre>
To clean up stateful code in preparation for a reload, export a function called <code>__unload</code> that optionally takes the module compiled from the newer code.
<pre><code class="language-javascript">export function __unload(new_module){
cancelAllEventListeners()
}</code></pre>
<h2>CodeMirror</h2>
<p>
When we started thinking about making Carbide self-hosting, we realized that it had to be made in such a way that it could handle large notebooks. Unfortunately if you use the HTML's natural layout mechanism to lay out your cells, everything still needs to be rendered on every keystroke— there's no way to do optimizations like rendering only the visible lines (because it's then the browser who figures out what a visible line is).
</p>
<p>
Carbide's current implementation is kind of strange in this regard because we have a single gigantic CodeMirror instance whose document represents the total concatenation of all the cells in the document. We have a special layout algorithm to insert vertical spaces where appropriate so we have enough space to paint on user interface elements on top.
</p>
<p>
This allows us to take advantage of CodeMirror's neat lazy rendering capabilities and to only render the things which are visible on screen.
</p>
<h2>Nondeterministic Layout Engine</h2>
To Enable Carbidiculous behaviors, like treating text contours as elements that can block floating widgets, Carbide's layout engine uses a form of <a href='http://community.schemewiki.org/?amb'>McCarthy's AMB operator</a>. Essentially, because Carbide need to calculate layout greedily, layouts sometimes have to exist in a superposition of two states, that can only be resolved after further layout calculations. This is sort of like <a href='http://c2.com/cgi/wiki?QuantumBogoSort'>quantum bogo sort</a> for css.
<h1>Future</h1>
<h2>Preview: Adding Custom Kernels</h2>
Although Carbide is Javascript-first, parsing, compiling, and running code are all implemented as external modules. This means that it's possible to define a javascript module that replaces the carbide kernel in order to run code in a different language.
Here's an example of what a minimal kernel will probably lookl ike:
<pre><code class="language-javascript">export async function parse(code){
// Return some AST
}
export async function match(ast, code, start, end){
// Return closest valid expression
}
export async function evaluate(ast, cell){
// Evaluate the cell
}
</code></pre>
<h2>Preview: Watlab Kernel</h2>
Watlab is compile-to-javascript language inspired by Matlab. Almost all of the syntax is the same as ES2015, with addition of a postfix function application operator, matrix literals, and standard matrix operators (e.g. <code>A\b</code> to solve a system of linear equations).
<img src="static/img/watlab.gif" style="width: 50%; display: block">
<h2>Preview: Python Kernel</h2>
A tiny kernel that communcates with a local python REPL. Pros: filesystem access, cool python libraries. Cons: requires an <code>npm install; npm start</code> command.
<img src="static/img/python.png" style="width: 50%; display: block">
<h2>Preview: MIT Scheme Kernel</h2>
A tiny kernel that communcates with a local MIT Scheme REPL. Pros: filesystem access, arcane wizardry. Cons: requires an <code>npm install; npm start</code> command, arcane wizardry.
<img src="static/img/ltuf.png" style="width: 20%; display: block">
<h2>Preview: Time Traveling</h2>
One of the features that didn't quite make it into the alpha release is a Bret Victor Style program execution scrubber that lets you get a more intuitive sense of stuff like for loops:
<pre>[images]</pre>
Stay Tuned.
</div>
</div>
</div>
<div class='prior-art'>
<h1>Halp + Hallu</h1>
Send us an email at your favorite address:
<ul>
<li>[email protected]</li>
<li>[email protected]</li>
<li>[email protected]</li>
<li>[email protected]</li>
</ul>
<h1>Acknowledgements</h1>
<p>
<img src="static/img/fancy_logo.svg" style="width:100px;float:left;vertical-align: top;margin-right:10px;"><span style="font-size: 40px">arbide </span> builds on the work of a lot of people. It incorporates code from lots of open source libraries, but it also owes a lot to ideas from both academia and industry.
</p>
<p>
Carbide probably couldn't have been possible if it weren't for CodeMirror, by Marijn Haverbeke. Likewise SystemJS/JSPM by Guy Bedford are incredibly useful gems. The <tt>uncmin</tt> function from Sébastien Loisel's NumericJS works well enough that we consider it one of the blackest of magics.
</p>
<!--<p>
My fascination with programming environments was pretty much distilled from my envy for what my physicist friend could do with Mathematica. I think what Wolfram has done is pretty incredible in its own way.
</p>
<p>
Of course, no new programming tool announcement is complete without high praise to its patron saint Bret Victor.
</p>-->
</div>
<!-- <div class="prior-art">
asdfjoijsadf
</div>
<h2>Prior Art</h2>
<img src="static/img/fancy_logo.svg" style="width:60px;float:left;vertical-align: top;margin-right:10px;">arbide is heavily inspired by Previous Notebook programming environments, especially Mathematica. Our comment system is a knod to literate programming as pioneered by Knuth. Interlinear annotation and direct manuipulation have their roots in Sutherlands Sketchpad and have been more recently distrubted in the works of Bret Victor.
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.5.1/prism.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-83153710-1', 'auto');
ga('send', 'pageview');
</script>
<script type="text/javascript" src='static/main.js'></script>
</body>
</html>