-
Notifications
You must be signed in to change notification settings - Fork 56
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
p4 #86
Comments
The goal is to submit this work to <Programming> in Feb and a good title for the PX workshop (says JE) is "FRP eXperience". There are a few different levels here:
Infinite canvas drawingsOther tools for inspiration
Worst parts of Reflex/HaskellBut then I thought: let's focus on the really key issue here. What's the highest-leverage improvement to be made? What's the worst part of using Reflex/Haskell now? In the shower note on the right below, it says:
p4 prioritized features
ImplementationJE send me an email:
My response: The only implementation of the FRP I argue for in my paper is Reflex/ghcjs. It doesn't exist in PureScript, Elm, F#, etc. Turns out laziness makes it a lot easier to implement. My next experiment is to try to do it in JS with CycleJS. I've tried this in the past. It's not easy -- it's not built for this use case -- but it seems possible, even cycles. More to follow...
Some other ideas for building this:
|
* TOC {:toc} ### SPLASH 2018 recap I normally don't like to travel but this trip was possibly the best thing I've had to travel for in my life. I'm very excited to do more things like this, maybe a couple times per year. #### Internet friends IRL I've been referring to this period of my life as my "Twitter Friends Phase" because I am making so many friends and then I also get to see them in person. Just in last week in Boston alone, here are all the amazing people I got to spend time with: Will Chriton, Joel, Jonathan Edwards, Ravi, Brian, Cyrus, Glen, Sean McDirmid, Paul Chuisano, Geoffrey Litt, John Maloney, Charles Roberts, Chris Granger, Eyal Lotem and Yair Chuchem from Lamdu, Roben Kleene, Daniel Moon, the ReScala team from Technische Universität Darmstadt (Ragnar, Pascal), Josh Horowitz, Roly Perera, Caleb Helbling, Evan Czaplicki Sadly I only have one photo from the event. I should do better next time! ![image](https://user-images.githubusercontent.com/2288939/48514489-683f8b00-e82c-11e8-91aa-6b54dd936273.png) #### LIVE 2018 I have trouble with lectures. I'd much prefer sitting at home in my sweatpants, listening at 2x speed and bouncing if it's not for me right now. However, LIVE 2018 was one of the best days ever, not in spite but *because* it was a day full of mind-blowing demos one after another. I recorded them on my phone and uploaded online to a lot of thank-you's. The Bootleg page had a fun run, including Jeremy Asheknas's transcript which landed on the front page of HN for the day (not when I posted it, but when he posted it a few hours later). ### Next Research I really have two very interesting directions to go in: making FRP experience better, or expanding the FRP universe to multi-node. We choose FRP experience for now, but I'm thinking about the other thing on the side. #### p4 11/14/18 (Tracked at #86) The goal is to submit this work to \<Programming\> in Feb and a good title for the PX workshop (says JE) is "FRP eXperience". There are a few different levels here: * the abstraction / code * the streams, including data and how they fit together * the output UI ##### Infinite canvas drawings ![image](https://user-images.githubusercontent.com/2288939/48514496-6d9cd580-e82c-11e8-8bf4-1b4af9aef054.png) ##### Other tools for inspiration * WYSIWYG hybrids such as Sketch-n-Sketch * Aprt.us, which would be a more visual language. Key question is how to do higher-order & cyclic, and other abstractions * Facebook Origami * Lamdu/Luna/Dark and all the projectional editors * principle - design tool with timeline editor * framer ##### Worst parts of Reflex/Haskell But then I thought: let's focus on the really key issue here. What's the highest-leverage improvement to be made? What's the *worst* part of using Reflex/Haskell now? In the shower note on the right below, it says: 1. feedback loop: knowing if the syntax is right, if the types make sense, what the code I'm looking at *is* from both a type, data, and UI perspective 2. knowing what's possible (syntax, API, types) ##### p4 prioritized features 1. With this framing, a quick compile time (or intepreter time) could be key. Reflex seems to take 4+ seconds. Can I do sub 1? Or faster? How about hot reloading? 2. Great docs, autocomplete, type annotations everywhere 3. Automatic plumbing: can we semi-automatically lift transforms inside monadic contexts? Ditto for automatic type coersion plumbing like int to string, etc 4. Stream visualization, including how streams make other streams, the shape of streams, and also the data for each stream 5. (Bi-directional) Direct manipulation of UI ![image](https://user-images.githubusercontent.com/2288939/48357110-d0904000-e665-11e8-9154-3768ad3ce414.png) ##### Implementation JE send me an email: > Can you implement your FRP eXperience using FRP, and apply it to itself? That might be challenging, but would also be very impressive. It will be seen as a limitation if it can't apply to itself, although that might be unavoidable in the first phase. But I think that at the very least you need to implement it in some FRP framework to avoid the charge of hypocrisy. My response: The only implementation of the FRP I argue for in my paper is Reflex/ghcjs. It doesn't exist in PureScript, Elm, F#, etc. Turns out laziness makes it a lot easier to implement. My next experiment is to try to do it in JS with CycleJS. I've tried this in the past. It's not easy -- it's not built for this use case -- but it seems possible, even cycles. More to follow... * I did a very naive implementation of streams stuff in JS here: https://codesandbox.io/s/81225lrop2 * It'd probably be better to build off cyclejs. Over a year ago I tried to do something similar so maybe I can start there? https://codesandbox.io/s/xlrynkqoqp Inspecting the types of streams is key. Maybe I can use the cyclejs devtools and/or augment them somehow. Could typescript or something similar help me encode the types of streams of streams of streams? Could monaco help with autocomplete suggestions? Some other ideas for building this: * racket turnstule dsl for building typed langauges * L. Kats and E. Visser. The spoofax language workbench. * C. Omar. Reasonably Programmable Syntax. PhD thesis, Carnegie Mellon University, 2017. * Build a JS interpreter with laziness based on [Stephen Diehl's work](https://futureofcoding.org/log#stephen-diehl-lunch) #### Cloud FRP 11/14/18 (Tracked at #85) * At SPLASH, I was really excited to find [ScalaLoci](https://scala-loci.github.io/) which was about placement types of reactive programming in Scala. Very related to this work. I need to peruse their Related Work section for more details. * I found a way to make sense of reading (which I was having trouble with above). All data is "public" but by default anything you do is encrypted so only you can read it. You can also encrypt it with others' private keys if you want them to have access. We'd probably want to make who can have access be a `Behavior` so that we can change this if we want to revoke access. * Eventually, the next step here will be implementing this, probably in Haskell #### Name ideas 11/14/18 Now that I'm clear I am building a system, and not just producing research, I am thinking on a name. Here are some themes it could embody: * malleability * conviviality * casual * customizability * cooperation * denoational And here are my favorite names of the moment: 1. Potluck 2. viv 3. Stride (probably can't do because there's already a similar-ish thing) And here's what Twitter thinks: <blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Preferences on potential new programming language name..?</p>— Steven Krouse (@stevekrouse) <a href="https://twitter.com/stevekrouse/status/1061441377890942976?ref_src=twsrc%5Etfw">November 11, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> #### 2019 Conference deadlines - \<Programming\>: Salon de Refuge (Jan 7, April 1) Genoa, Italy - \<Programming\>: PX/19 (Feb 1, April 1) Genoa, Italy - PPIG (June-ish, Aug) UK - SPLASH: Onward! (mid-April, end-Oct) Athens, Greece - SPLASH: LIVE (June/July, end-Oct) Athens, Greece ### Possible Dec 2018 Re-group Projects I got this project started a year ago as fast as possible, and it seems like now-ish is a good time to regroup a bit and work on a few upgrades... Maybe I'll set aside Dec in do some of these things... #### Meetups more a thing It seems like there's interest in hosting/attending these in lots of cities, and with a bit of effort (a website with guidelines) we can have them in a bunch of cities. I can do London and maybe New York, Caleb Helbing has been talking about starting for Boston, Amjad Masad (of Repl.it) says he can take SF... #### Branding * Amjad suggested that a cool logo could go a long way. I actually had a dream a night or two ago about making the logo a interesting color blue... * Relatedly, the webiste styling could use an upgrade, a color scheme, top nav, footers, make it clear I accept pull requests on github, comments on pages * The podcast could really use intro and outtro music * Change the Slack URL to futureofcoding.slack.com, and make a doc explaining channels (maybe fix this up a bit) with descriptions and threading #### Re-organize systems * This log system is a bit janky (too much git integration, adding date to headers, hashtag based system could be nice for collecting for topics, todo system could be better than constant appending) * Jekyll seems simple but is actually quite complex and I've found it to be a nightmare to get things the way I want. Maybe I switch to a different platform. Maybe I slowly roll my own static site generator. Maybe I do it on now.sh...? * Especially now that Google Inbox is dying, I need to get my FoC research + FoC Thinking lists out and into another system * Relatedly, Github Issues could use some love. Potentially I could move everything here, and then come up with a better input mechanism to github issues... #### Sustainability * I have had a number of people strongly encourage me to set up a Patreon so they can support my work. This is terribly exciting! Top priority. * Here's a probably silly idea: a future of coding job board. A place where people in the community can connect with companies in the community. Maybe if it gets big enough, companies can sponsor it to get listed higher? ### Todos 11/14/18 * Dec regroup projects (above) * p4 storyboards (maybe 2-3 totally different takes, shallow, brainstorming mode) * schedule JE podcast in late Nov
making frp easier by having sequential semantics and we abstract to frp - like how joyJS can go from derivative iterative to continuous. logo and Nicky cases language and derivative thinking from inside vs implicit matjmstcal thinking from outside. two sides of same coin? |
https://futureofcoding.org/log#p4-thinking-for-je-meeting p4 thinking for JE meeting
Theme of my workA fun question on Twitter yesterday encouraged me to think a bit broader as to an underlying theme to my work that would encompass this project, as well as other outside of "improving programming" (namely, LogicHub). I'm proud of what I came up with: <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> Some responses about fluid HaskellSean McDirmid suggested Haskell for Mac, which is very cool and close to what I want so I installed it, but I wasn't able to see an easy way to get Reflex to work with it... Luke Iannini apparently worked on a live recompiler for Haskell. The monadfix people shocked me when they said:
My new thesis is that this fluid Haskell doesn't really exist - at least for most Haskell developers. Artyom from monadfix was also very kind and commented on my issue about installing intero. Too bad they can't help here! Biggest experience problems with Haskell/ReflexI made a full day's effort of trying to steelman Haskell/Reflex and make the experience as good as possible before trying to improve it - yet I just have such distaste for installing and debugging shit in the terminal (as well as using the existing Reflex setup I have) that I wonder if I can simply pull on my memory for the key issues... 1. Speed of feedback loopThe main thing was that speed of feedback on all fronts (syntax, types, output) was so slow and required so many keystrokes. In particular there were times that I could point to places in my code where I just wanted to know the type of something but did not know how to ask Haskell for that information. 2. API DiscoverabilityIn other words, "I have some things. I want some other things. What blocks can I use to go from what I have to what I want?" In Scratch, all the "legos are on the floor" to help with this. I find that the lodash JS library also does a superb job of this. I found the Reflex documentation and the Haskell autocomplete tooling to feel like I'm basically guess and checking. 3. Plumbing codeSuch as converting 4. Visualize streamsThis includes seeing the "shape" of streams and how streams make up other streams as in rxmarbles.com, as well as watching the live data flow through streams. 5. Direct manipulationThis whole thing won't feel natural without direct or bi-directional manipulation of the output because why not? Next step ideas1. Stay in HaskellContinue working towards a fluid experience in Haskell/Reflex.
2. Build/use JS library/framework
3. Build/use JS Haskell interpreter
4. Build a higher-level system that compiles to JS
I'm going to spend the next ~30 min doing the sketching discussed above in preparation for my meeting in a few hours with JE. |
https://futureofcoding.org/notes/jonathan-edwards/11-21-18
|
https://futureofcoding.org/log#fluidity-vs-structure Fluidity vs structureI need to spend some time defining fluidity and structure, but this graph feels provocative: I think fluidity has to do with live-ness, feedback loop speed, incremental actions causing incremental result, etc. And structure has to do with possible / impossible states, types, schemas. I'm stuck on where AST editors fit in this layout: they enable greater feedback loop speed knowledge of errors and prevent error states, yet they are not as fluid as using text but text doesn't give you as much info as fast. One interesting note is that Airtable is particularly noteworth as having high structure and also high fluidity. Conal -> TurbineJust as I decided (in the last meeting with JE) to build or find a JS lib for DCTP, I popped onto Twitter to find this: <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> Which led me back to Turbine, which I had found a few months back and mistakenly disregarded as the "wrong kind of FRP" as mistakenly interpreted their Now monad thing. I'm now quite excited about this library! I already sent two long emails to the creator, Simon, and hope he responds soon. Here's what I wrote I'd like to collaborate on:
And after we/I work on these more pressing issues, the next step will be building a layer on top of that Turbine that would make the development experience much better. That is, building a GUI that "compiles" to Turbine, for example, kind of in the spirit of Conal's Tangible Functional Programming. Here I am referring to more radical ideas than improving the documentation or a simple devtool, such a projectional editor in the spirit of Lamdu, Luna, Isomorf, Dark, Unison, and Hazel. |
https://futureofcoding.org/log#p4-thoughts-12318 p4 thoughts 12/3/18Start with non UI motivating problemsA way to simplify this problem is to build an FP playground to solve normal FP problems with cyclical streams first and work our way up to UI:
[].slice.call(editorElement.querySelectorAll('*'))
.map(e => [e, e.innerText])
.map(([e, text]) => [e, text.match(/^(#+)\s.*$/)])
.filter(([e, m]) => m)
.map(([e, m]) => [e, m[1]])
.forEach(([e,m]) => {
e.style.fontSize = (50 - (5*m.length)) || 3;
e.style.marginBottom = 2 + "px";
e.style.marginTop = 2 + "px";
}) The issue with this approach is that we may create a FP playground that won't scale up to cyclical UI problems... Fluidity is not the initial focusI realize that part of why structured editors haven't been able to compete with text-based coding is:
It's simply not a fair comparison to expect a new interface to be as fluid as text from Day 1. Of course fluidity is important and of course making it work with people's existing hardware and skills will help with adoption, but they aren't the first things to worry about. Maybe the ultimate interface will require new input hardware and/or a lot of practice to get the hang of. Hopefully we can get away with the keyboard and mouse and make the onboarding simple, but we don't want to pigeonhole ourselves over it. The initial focus should be on the comprehensibility of the code and the liveness of the experience. Liveness means that an incremental action should result in an incremental result. This is possible without fluidity, which means that "taking the incremental action" may not be ergonomic for some reason. (However, I will note that fluidity is SUPER important to me. I would love to build an interface that's only optionally dependent on the mouse.) All Literals are GUIs...If we throw out text-based coding and agree to a structured editor of some kind, you may realize that we can automatically represent colors as a color picker instead of (or in addition to) a hex value or rgb value. Cyrus Omar has work where he embed's a regex playground right into the IDE. (As Tudor Girba says, whenever you leave the IDE, the "I" has failed.) If you follow this line of thinking, you realize that ALL literals are GUIs! Numbers can be scrubbable or many other interactive representations, booleans are a checkbox thing... We can even nest GUIs! You could have a string as a widget which is basically a text box but you can add other arbitrary expressions inside - no more escaping characters necessary! Lists can be a specialized GUI where you can add and remove expressions or do comprehensions. We can continue this idea for all kinds of expressions: if-expressions, pattern-matching, lambdas, function application... Can we build nestable custom GUIs for every part of System F/Haskell?! I think so! The key here is the nestability. Normally a color picker or other GUI is a top-level thing. But why? I don't see any reason why it can't be as expression-like as coding. When you define a function it will default to a basic representation but it should allow you to add a more specific GUI to represent your function! These thoughts were inspired mostly by Tudor Girba, but also are related to Niko Autio's Microeditor ideas. I am curious how to combine this idea with the ideas of Hazel and Josh's principle of radical visibility of preview evaluation with test data. Same with the hashing stuff. There are so many cool PX ideas to combine together! Drawing this out will be interesting. And if I can show how we can do any pattern from Haskell, completeness is guaranteed! In terms of implantation, not sure if HTML or canvas is the way to go. Would be fun to play with Turbine on this project... |
* TOC {: toc } Feeling a bit overwhelmed, rushed, frenetic today for some reason. Deep breaths, Steve, deep breaths. ### One prototype at a time [History and future of p4](#86) Now that I'm settled on Turbine (modulus the 15 issues I created, and many more to come), I'm beginning to think about what I hope to build with Turbine: p4. I was getting a bit overwhelmed with all my ideas for p4. I made a big list and asked JE for help figuring out what's essential and what I can do without for this prototype: * Immutable editing * content hash like Unison and IPFS * do we hash definitions or expressions? * do we do work to cannonicalize hashes? (such as commutativity of addition) * no delete * no edit, only create new thing * refacorting * Detachable GUI Literals * Everywhere you have a GUI, you need to be able to put an expression: detachable GUI literals! * GUI for every system f language primitive * Bootstrap visual editor?! * Are all apps just expressions visualized? * Expression-based operating system instead of file-based or app-based * Other ideas * A la carte language semantics, like haskell langauge extensions * Always running, like spreadsheet or google doc, no run or pause, only open or close * infinite canvas (can I still use Turbine...?) * exploring which concepts we can move from the language compiler to the editor (no free variables, type inference is just local if not just a type “suggestion”) He helped me realize that most of these ideas represent *entirely different prototypes*! I can't just combine them all like this. Prototypes explore one new idea at a time. So what's the idea for p4? JE hit the nail on the head: p4 is an IDE for Turbine. This is particularly funny because p1 was an IDE for JQuery and p2 was an IDE for VueJS! Those both used blockly but that wouldn't help with p4 because blocks solve a different problem than what p4 is trying to solve: improve the PX of DCTP, most directly by _showing live streams as the user interacts with the output_. On my run a few hours ago, I was thinking about what my data model would be for p4. Then it hit me: Turbine is the data model. (Along with hareactive, io, and jabz.) Those stream data structures *are the thing the p4 user is creating*. I *could* start p4 by building a projectional editor for Turbine/hareactive/io/jabz and all of JS. But can I get away with less? One way to get away with less is to build a UI for the turbine/hareactive/io/jabz functions/combinators and then have users type regular text js where we need functional expressions (similar to aprt.us and pane). The other way to do *even less* is to allow text to be the interaction model for Turbine and simply start with a devtools that shows the streams. If my main conviction is that seeing the streams will help, let's *just* do that. What's great about this idea is that a stream visualizer is a pre-req for any other p4 end-product anyways, so I might as well just publish it as it's own thing, and then move on afterwards. In summary, p4 is now the Turbine devtools project, in the spirit of the CycleJS devtools. Wait... because this feels reachable (I can imagine myself achieving it in early 2019 and it existing), it makes me wonder more about next steps... * Do I try to take up the Turbine mantel and get others to use it? * Do I go towards the structured editor idea? * Do I experiment with one of the other ideas listed above? All valid answers. The thing is, whatever I do, I need a UI library I love, and that library needs a stream visualizer, so build that first. And then we'll talk. ### Donation platform Before starting the Patreon, I wanted to look around for alternatives. I found Stripe, Paypal and Donationbox allow for subscriptions with much less fees. However, I asked a few people with Patreons and a few of the people who said they'd be my supporters, and both said that I should stick with Patreon, mostly for the branding. It explains itself and gives off the right vibes, which is hard to do with a do-it-your-self platform. Patreon it is! ### Next week * p4 & Turbine * Patreon launch * couple hours of freelance Maybe something like: * Monday - Patreon * Tuesday - Patreon * Wednesday - p4 & Turbine * Thursday - p4 & Turbine * Friday - freelance
https://futureofcoding.org/log#one-prototype-at-a-time Now that I'm settled on Turbine (modulus the 15 issues I created, and many more to come), I'm beginning to think about what I hope to build with Turbine: p4. I was getting a bit overwhelmed with all my ideas for p4. I made a big list and asked JE for help figuring out what's essential and what I can do without for this prototype:
He helped me realize that most of these ideas represent entirely different prototypes! I can't just combine them all like this. Prototypes explore one new idea at a time. So what's the idea for p4? JE hit the nail on the head: p4 is an IDE for Turbine. This is particularly funny because p1 was an IDE for JQuery and p2 was an IDE for VueJS! Those both used blockly but that wouldn't help with p4 because blocks solve a different problem than what p4 is trying to solve: improve the PX of DCTP, most directly by showing live streams as the user interacts with the output. On my run a few hours ago, I was thinking about what my data model would be for p4. Then it hit me: Turbine is the data model. (Along with hareactive, io, and jabz.) Those stream data structures are the thing the p4 user is creating. I could start p4 by building a projectional editor for Turbine/hareactive/io/jabz and all of JS. But can I get away with less? One way to get away with less is to build a UI for the turbine/hareactive/io/jabz functions/combinators and then have users type regular text js where we need functional expressions (similar to aprt.us and pane). The other way to do even less is to allow text to be the interaction model for Turbine and simply start with a devtools that shows the streams. If my main conviction is that seeing the streams will help, let's just do that. What's great about this idea is that a stream visualizer is a pre-req for any other p4 end-product anyways, so I might as well just publish it as it's own thing, and then move on afterwards. In summary, p4 is now the Turbine devtools project, in the spirit of the CycleJS devtools. Wait... because this feels reachable (I can imagine myself achieving it in early 2019 and it existing), it makes me wonder more about next steps...
All valid answers. The thing is, whatever I do, I need a UI library I love, and that library needs a stream visualizer, so build that first. And then we'll talk. |
https://futureofcoding.org/log#prototype-4
The future work section of my paper talks about visual metaphors for FRP. While I do think this is quite important in order to "democratize visual intuition" (Penrose), I wonder if it's necessary. What if we take normal FRP haskell-ish notation as a starting place and simply augment it with LIVE-ness, such as an interpreted environment, showing data, and evaluating as far as possible even when there are holes (Cyrus Omar's work). Geoff Litt and Paul Chiusano suggested that expressions with holes are just functions with those holes as parameters, and we could put a slider or examples values in there. Always concretions, never pure abstractions.
Here's another idea I've been toying with: Jason's Brennan's notion of a programming environment on an endless canvas, like in Sketch or Photoshop. One thing this could enable is a structure-less structured editor - in that you could put together pieces of expressions in various places and combine them later. I guess this would be similar to Scratch or Blockly... which I don't love... One possibility is to use the layer metaphor from Photoshop as a programmatic abstraction, but I don't know what that would mean exactly yet.
My first thought was to build this as a FP thing first and build my way up to FRP. It could be the data slice-and-dice ninja thing, starting with JSON/CSV slice, dicing, and joining -- this is related to datafun.
But then I went ahead and did a drawings for it as an FRP platform:
The text was updated successfully, but these errors were encountered: