-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtodo.txt
307 lines (197 loc) · 17.6 KB
/
todo.txt
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
todo:
-- make debugger work even in exceptional scenarios
(done) - make debugger independent of subroutine controller. It needs to remember where it is across subroutines.
- make sure the function gets run, even if it's just for the sequencer.
Set output index to "sequencer" in this case, or maybe just -1
Next challenge is publishing. You need to be able to publish your work and consume work published by others. Once you can do that, you can share programs and build on the shoulders of others.
When you publish a function, it and all of its dependencies each get a "published id". They are each placed in files named after those IDs on the server. I suppose the server needs to decide on this ID so that users cannot abuse the system.
The language has no standard library. The closest thing to a standard library it has are the functions I wrote myself. I suppose functions could be tagged to participate in a collection of some sort though. But those tags may belong to different users.
-- Brett Victor wrote a thing about learnable programming languages: http://worrydream.com/LearnableProgramming/
* Read the vocabulary: arguments are all labeled and there's no hidden state, so we're good here.
* Follow the flow: well things are all connected, and semicolons have an intuitive execution order, but not everything else does. Fortunately, that shouldn't matter. However, it would be good to have a timeline view like he shows.
* See the state: I could make the global state visible somewhere, like next to the logging view.
* Create by reacting: Functions can have default values. Next step would be to make it automatically running your code while you're editing it.
* Create by abstracting: Hell yes. My program does this very well.
* identity and metaphor: not sure. This is more about the environment than the language.
* decomposition: definitely
* recomposition: You can easily make a parent program that combines two child programs. Nothing can possibly collide, and they use event handlers so you don't have to mix any top level functions together like in processing.
---
problem 1 is mostly solved by labeled parameters.
However, that does not give you a visual representation of what things are for. Hm.
The next set of problems could be solved by a nice debugger. Unfortunately the program can't run predictively without the user input, but given a default set of user input it should be able to go. I should make such a debugger, which creates a table to represent the stack traces like bret's diagrams.
The one about putting the parts out on the table is already done by my library. It'd be nice to give them icons too though I guess.
start constant, then vary. That's something my environment could do really well! I need to make some intractive picture drawing demos for it. You can totally create a function by selecting stuff.
Hm, how can I do recomposition? Well, since I'm using JavaScript events you can stitch programs together by atteching new event handlers. Because of this, two whole programs can be mixed together from the outside using their semicolons. That is assuming the people who created it provided semicolons. There should be a stateful checkbox on graphs too that just adds those nibs on either side.
Oh dude! Since I'm storing state in the runtime, I could totally allow you to pause the program, edit things, and then run it some more.
It'd be nice to visualize all the data types. Once a JSON is evaluated, we can figure out what type it is and visualize it accordingly. Also if you use constructors then more complex types can be identified and visualized. Perhaps when you create a type constructor, you could add some code that visualizes it. Perhaps that code could make use of an html template.
It makes me sad that he would say visual programing is worthless. My visual language handles a lot of the things he wants in a language. It lets you connect variables like he shows. It lets you create functions the way he does.
So I've already put in a space for you to populate default values for functions. I should make it so that if things aren't connected, these defaults are used. Then you have something really easily. I dunno how I could do drag and drop in the actual output though. Perhaps just twiddling the values would be good enough.
---------------
For the instructions page:
Basic Values:
Text - Its value is used exactly as it is typed.
JSON - Its value is run through a JSON parser. It can be a number, a list, a map, etc.
Symbol - Its value is its ID. It is useful if you want a value that will not be the same as any other value in the program.
Functions:
JavaScript / CoffeeScript - A function implemented in another programming language
Graph - A function implemented in the visual programming language
Vocab Lesson: A "Function" is a concept in mathematics. It is a mapping from a set of inputs to a set of outputs. For example, Plus is a function that maps two inputs to one output. If the inputs are 2 and 2, the output is 4.
Functions can be used in two ways:
Call - This node uses ("calls") the function once. You can connect other nodes to its inputs and outputs.
Value - This node only has one output nib, like the other value types. The output value it provides is the function itself. This allows you to connect it to the input of another function. Those functions can determine what inputs it gets and what is done with its outputs, and it may call the function multiple times.
Vocab Lesson: Functions that take other functions as inputs are called "Higher Order Functions".
Next steps:
- instructions page
- TYPES!
- click nibs and get contextual options on them
- edit individual nodes, and give the 'clone' option
- copy-paste nodes
- not letting you remove nibs is annoying. It should let you force it and delete connections.
- rearrange nib ordering with drag and drop
- sort nibs in make_from based on their positions on the outside...
how do you compare a node to a nib though? Perhaps parent inputs are always first?
- Allow a paragraph of explanation inside all definitions
big things
- make a game
- add the import/export system
- add a node-creation menu for when you click on empty space
- new [javascript | graph | literal]
- search the library and insert [value | call]
less important
- position/select nodes based on their centers instead of their corners
- keyboard binding for delete
- "idempotent" checkbox that memoizes?
- "glob nibs" - one nib internally that is many nibs externally, var args. This would be especially useful as it would enable a "list" function.
- add 'bypass' option for selections that only have one input and output. Connect around em.
done
- some way of stopping/starting the application --maybe it should be in a different window
- make json / string literals editable, and symbols renamable.
- "stateful" checkbox that adds extra null nibs. Display those specially.
- vectors
- display graphics
- setup/teardown for timers, event handlers, globals, and elements
- delete button
- list all the places a definition is used when you're editing it
- display calls and values differently
New big step: long-running programs as instances.
When you run a program, it needs two things: a graphical output and a log output.
For functions with multiple outputs, you should have the option to evaluate just one or all of them or a selection of them.
Oh my god. What if I did the documentation entirely in the program?
Stateful globals: a real problem. -- solved
I wanted this language to make it easy to test pieces individually. However, there are many ways external information can make its way into (and out of) a function without being picked up as an input or output. This is no good. I need some way to normalize state for testing purposes.
The real problem is interaction with event handlers. Event handlers need to be able to mutate state. When a user hits a key on the keyboard, event handlers need to update the state of the keyboard for consumption by other methods that care about keys being held down. That new state of the keyboard then needs to be fed to anyone who needs that information. How do I tie this knot?
This is the messy stateful problem many languages deal with. Ideally I'd be able to refer to the keyboard as a service, and ask it questions. Its newest state would be provided to my update function any time that function ran. Its newest state would also get run through the event handlers and subsequently replaced. That way it could act as a proper input.
update (keyboard_state, game_state) -> game_state
keydown (keyboard_state) -> keyboard_state
Currently nobody is there to collect the new keyboard state from the keydown handler. The addEventListener implementation has the opportunity to collect this information. What should it do with it? Perhaps it should send it to a publish function of some sort. Somehow the new keyboard state has to make its way to the looper function, since that's where update is invoked, and update needs to be fed the keyboard state.
Perhaps setup-keyboard-events should return some accessor that can get the current state. This could be called by the looper every time it wants to call update. Honestly, I need some way of handling services just like Angular does, and that is kinda like how Angular does it. A service needs to have some way of providing its current state.
Now I need this tying the knot part.
done
- test functions as values - done
- when the same output goes to multiple inputs, it becomes multiple inputs in the new function. This is bad. -- fixed
- Somehow I was doing joins and the new nodes were showing up in the wrong scope.
----
- Next serious architectural problem: nibs on function values. All values should only ever have one nib anyway, so it's irrelevant what that nib is. Perhaps the connection should just have a null there? Is there any situation in which a value node would have multiple nibs? Maybe if you were pulling properties off it, but that is so far ahead of what I have in this language, and it could be accomplished with a regular function anyway. Alright, fixed it by implementing a get_inputs/outputs interface which all node-likes observe.
- gotta release something
Well, I guess I could put the local storage stuff back in. Just need to make a new format for it.
It's currently a little unusable. What does it need?
finish the 'make subroutine from' call -- done
bust apart subroutines - done
better selection support -- click nodes, hold shift, etc -- done
contexual options for the thing you have selected - done
delete nodes - done
- networking / publishing / collaboration
This is a serious component. What should I do for it? Hm.
Currently it is in a 100% local form. Will you always be able to download the whole library? Probably not, but perhaps I can solve that problem when I come to it.
Will need a system to fetch newly published functions. Should they show up in a different area from the normal functions?
- editing this node vs all uses
copy-on-write?
There should be a way to edit "just this node" (which clones the implementation) or dit the original implementation. Perhaps there would also be a middle ground where you would only be editing ones that are referenced by the current pinned functions. You could pin functions to indicate you're working on them, so the UI would know that the functions you edit should track those.
Perhaps for now it would be easiest to go to the main implementation first, but include a "clone" button on the page if you came in from a particular node. This would be the node edit view.
- serious problem -- averted
Creating new inputs/outputs on a subroutine does not update that subroutines uses. It needs to. It would be nice if this information were linked somehow, but unfortunately an input object on one side is an output on the other. But somehow all the implementations need to know if things are changing! Ugh. hm.
It's really important to keep track of what nibs things are connected to with more than just their name or index. Nibs need IDs. Nibs should actually belong to functions, and just be referenced by applications. That way they do double duty. Gotta treat them differently whether you're connecting to a subroutine or not that way though.
Connections should connect to nib objects, and they should be remembered by ID. This way you can easily rearrange nibs by index without breaking connections anywhere in the program. Also, there should be a big warning any time you delete a nib, since this can't be undone...unless we have some 'resurrect a deleted nib' feature, where subroutines remember nibs they used to own. Yeah, that's probably best. Creating a new nib will never substitute for an old one though.
- connection refactor
- editing - done
- execution - done
- inputs for builtins - done
- rename things - done
- saving - done
- loading new and legacy stuff - done
- other important stuff
- placeholder names - done
- proper events for inputs - done
- contextual warning when deleting nibs from definitions - done
- networking
- reduce uses of literal by uniquifying them on creation? But what if you want to edit them? How do you edit literals?
- needed features
- create a subroutine from selected nodes
- use shift button to add to / remove from selection
- allow creation of codes in coffeescript
- variable inputs and splatting
- idempotency
- radial menus when you click
- visual style
- style the code page
- add ace editor
- lock library header to top?
- buttons instead of links on top
- make a game with it
- setInterval primitive
- window primitive
- make a debugger
- highlight the lines, step through
- re-implement UI
+ add/remove inputs
- rearrange inputs
- scale everything based on the size of the screen. Gotta make everything accessible no matter what your screen size is.
-
------- old priorities ----------
- add a place to put documentation on implementations
- don't allow connections from inputs to inputs or outputs to outputs
- add a smart delete feature for subroutines
- list the number of subroutines that use this one. Click this to see their names
- if this subroutine is used by another, ask if we should delete that one as well
- if there are other subroutines that are only used by this subroutine, ask if we should delete those as well
- add history support
- just use the id of the object you're editing
- use Ace editor for the javascript editors
- Create dynamic function call node. Speficy the inputs and outputs on it dynamically
Perhaps show it with no normal inputs/outputs at first, but have a special '+' input and output on the right. When you connect things to this,
they become new inputs/outputs. Would need a way to delete them too. Perhaps as an option in a real right-click menu.
- I should re-do the vis in canvas for more readability. Should I rotate it to look like all the other visual languages out there?
- make a server-side service that will request arbitrary urls for you
- make a jquery selector builtin
- edit the number of inputs/outputs on existing subroutines
- needs lots of feedback for when you delete a nib that is in use in some program somewhere
- ugh, I'd rather this system didn't act so inflexible. Perhaps I should make an 'unknown-nib' show up and bundle all the higher-index connections into there.
- this could help for unknown implementation nodes too! Yeah.
- it could throw the NotConnected exception if you tried to evaluate off of it.
- make a slider to increase the detail level (make everything smaller), and another to zoom in/out and pan like http://worrydream.com/#!/GesturalZoomAndPan
- add an "Idempotent" checkbox to javascript functions. If a all trees leading into an idempotent function are idempotetnt, its result can safely be memoized to improve performance of algorithms like fibonacci.
- add a checkbox to turn off this memoizing on a given subroutine if it takes too much memory
- only memoize at the furthest point that it is safe to. Don't bother memoizing intermediate values.
- how to handle multiple inputs/outputs? Well, we can only really memoize on a per-connection basis I guess.
- think about how version control could work
- save every version of a function
- allow users to upgrade theirs and notice when input compatibility is broken.
- online persistence
- should still allow you to play around in localstorage if you are not registered, but you must register in order to upload your work.
- allow you to search through all the users and see their things
- mark things private? But you can't do that if you used them in public programs. Notify that all referencing functions must be private too.
- don't let literal values contain non-json values. Currently they can if you type stuff in.
- perhaps I should have a save-on-run system?
- add some higher order functions
- map, reduce
- remember what program you were looking at in localstorage
- add a 'fork' button for subroutines that makes a copy with a different id
- add memoize builtin to fibonacci example. use underscore
- implement builtins for dealing with lists and maps
- instructions on page
- right-click nodes to delete them, right-click nibs to delete connections
- warn about clobbering with imports (based on id)
- fix the font somehow
- replace alerts with a console?
- Add box/multi-select
- convert selection to subroutine, counting inputs and outputs