I view it as a mild plus that the confusion around the name has educated so many about confectionery taxonomies.
451 karma · joined July 29, 2012
I view it as a mild plus that the confusion around the name has educated so many about confectionery taxonomies.
Tweet thread explainer: https://twitter.com/ShriramKMurthi/status/142918126348784435...
https://dcic-world.org/2021-08-21/part_appendix.html#%28part...
https://people.cs.umass.edu/~arjun/main/papers/2016-rehearsa...
https://ucsd-cse131-s18.github.io https://course.ccs.neu.edu/cs4410/lec_let-and-stack_notes.ht... https://ucsd-progsys.github.io/131-web/lectures/05-cobra.htm...
(I designed the original version, though it's improved a lot in the past few years)
Stopify is a JavaScript -> JavaScript compiler, implemented as a Babel transform, that enables pausing and restarting control operators for JavaScript programs.
A lot of the comments note the rich history of systems for debugging and execution control. Stopify's goal is to enable those kinds of systems, efficiently, while constrained by the browser's execution model.
This is a problem we've thought a lot about with Pyret, and have different concrete solutions. Rather than use heuristics that turn long-running computations into errors, we capture continuations and yield to the browser periodically. This allows long-running computations to eventually complete, while allowing the user to fully interact with buttons and the page while it's happening. This generalizes to nice abstractions for functional event loops and ways to manage asynchronous APIs for novices.
The Doppio JVM and the Whalesong compiler for Racket have similar underlying approaches.
It's quite a bit of effort to work around this inherent limitation of the browser's evaluation model for web-based IDEs!
I've used this informally as justification before when renting housing and bringing my dog to work (she's a plain CGC).
I think there's value in having these be more recognized. I especially wish they were by airlines.
Note that this isn't the same thing as the issue with service animals, where credentials are at a totally different standard, and more important than where I can bring my pet.
This archives the state of the system when we made the switch:
https://github.com/brownplt/pyret-lang/releases/tag/pyret-20...
Some things, like the grammar (https://github.com/brownplt/pyret-lang/blob/5f22ec7c8affde15...) have survived largely intact from that prototype for years.
Plug for my course, which is built around the ideas in Ghuloum's paper, and I've talked about before on HN:
https://news.ycombinator.com/item?id=13207695 https://news.ycombinator.com/item?id=15005853
https://cs.brown.edu/~sk/Publications/Papers/Published/yk-wh...
Results range from 20x to 100x slowdown – just fine for the games and animations middle- and high-school students write for Bootstrap, for example.
This is huge because with powerful control operators like call/cc, you can simulate pre-emptive multithreading within a browser tab. This gives the runtime:
- The ability to simulate synchronous functions backed by asynchronous library calls (e.g. apparently make a synchronous request to a URL from the program's point of view, but have it backed by an AJAX request) - The ability to add a pause and/or stop button to an IDE within a browser tab, even if the program goes into an infinite loop
In fact, work on Whalesong (and a few earlier prototypes) more or less run the Racket-using parts of www.wescheme.org which 10s of thousands of students use each year.
Most x-to-JS implementations don't have this level of feature richness; Doppio and GopherJS are two that have similar levels of execution control.
I worked in the same office as dyoo while he was implementing Whalesong about 5 years ago, and learned a ton from him and from the system. Pyret and code.pyret.org directly built on some of the code for the "framework to program the web in functional event-driven style" in reactors (https://www.pyret.org/docs/latest/reactors.html). Whalesong's APIs for programmatically saving and restoring the stack inspired the ones we use in Pyret, as well.
This is just my materials, I don't have an associated platform with verification/certification. However, some folks from HN have previously done the course and emailed me after, and seem to have gotten some value out of it.
https://cseweb.ucsd.edu/classes/sp17/cse131-a/
https://podcast.ucsd.edu/podcasts/default.aspx?PodcastId=401...
https://github.com/ucsd-cse131-sp17
Earlier offering:
1. Hitting "Enter" doesn't send the message. This encourages writing actual paragraphs in response, rather than sending fragments of sentences
that can be interrupted across multiple lines
because you're not really sure if you've finished your sentence just yet
oh and you thought of one more thing so everyone else please take this line into consideration as well
Of course, you might say "train your team to not do that." Sure. But I'd rather use a tool that doesn't require breaking (perhaps reasonable) habits. And if communication shouldn't be through short bursty chunks by default, why make that the easiest thing to do?
2. Make threads more of a default way to respond, and make thread comments first-class citizens. Presented with the UX of Slack, it's really hard to move yourself towards using threads because the easiest way to respond to things is to type and hit enter. Also, threads live in their own "All threads" space, not organized by channel. Thread comments aren't first-class citizens like regular chat is because they can't have files attached, be posts or snippets, etc, so sometimes it feels like I actually _lose_ functionality by starting a thread.
Twist looks like it has what I love about Slack – good for newbies to join in and see organized, curated history (I can't show new folks _my_ inbox labels and organization, or spin up a new channel on a mailing list for each topic we want to discuss), good for lurking on projects that aren't your own but are related, and has emoji responses for celebration, quick feedback, and commiseration.
http://www.ccs.neu.edu/course/cs2510/Lectures.html
The NEU course assumes that students have taken How to Design Programs in Racket, so the early notes refer to Racket syntax. I'm working on notes for a Racket-less introduction that uses the same tools for my course right now:
https://cseweb.ucsd.edu/classes/sp17/cse11-a/Lectures.html
These notes also rely on a particularly good testing library that is capable of doing things like comparing objects for structural equality without requiring that students define a .equals() method first, which can be incredibly helpful for getting off the ground.
http://www.bootstrapworld.org/
Bootstrap 1 is computing tied to algebra concepts, targeted at the middle school age group (US grade 6-8). Students learn things like order of operations and what a function is while building up their own game. The curriculum has lots of activities that show students how to use code to generate images early on, which gives something immediately interesting and tangible to work with.
It runs in a stock browser (lots of students do Bootstrap on inexpensive Chromebook models), has a great support mailing list, and is used in schools across the US already. It also explicitly helps with math skills, which can be doubly useful in preparing for other STEM topics in the future.
I think this is one of the key concepts in a compiler, yet I don't think it has much to do with parsing.
Parsing (in a compiler) is the act of taking a linear sequence of characters or tokens, and turning them into a rich AST structure.
The back end of the compiler is what takes this recursive structure and flattens it out into a linear sequence of instructions that "mean" the same thing as the tree.
Parsing is critical, of course, for building a working compiler. But I think not focusing on surface syntax gets to the key recursive-to-linear insight you mention more directly!
I see a few interesting contrasts with the my course off the bat:
- I skipped forcing students to implement uniquifying variables early on. I wanted to get from source to assembly as quickly as possible, but this may have been a worthwhile step to force, since it teaches some valuable lessons.
- I had them implement ANF (AKA flatten in those notes) in a different style, because I was used to it. The style in that textbook is better (Ranjit Jhala at UC San Diego also pointed this out when he taught a version of the course), where an expression is turned into a list of bindings and a final expression, rather than using a continuation-passing ANF algorithm as I did.
- The linked book has instruction selection with semi-abstract addresses followed by a "patching" phase, to avoid instructions that, say, move from stack location to stack location. This is cool, but is a few more steps than I wanted to get into for the simplest compilers. I didn't pursue as structured an approach, and instead gave a simple description to the first few "compile" functions we wrote:
Generate a list of instructions that gets the "answer"
for this expression into EAX
This avoided detailed discussion of instruction selection, abstract vs. concrete addresses, etc, in the beginning, and just made students generate some instructions that work. We quite quickly after that needed to start talking about issues of clobbering other expressions' state, and finding unique locations for variables, but then those just became constraints on "getting the answer into EAX" correctly. In fact, I found that repeating the mantra "get the answer into EAX" was a nicely actionable way to go about generating instructions, and letting students get started when we introduced a new feature (to compile it, we need to get the answer into EAX!)After we'd done this a few times, we had the shared vocabulary to realize that answers don't _always_ have to go to EAX (the compiler can be parameterized over where the current answer should go), and not every constant's value needs to flow through EAX in order to get to its variable's home, etc. But these were refinements on top of our dead simple strategy.
Just some thoughts I had while perusing the first few chapters here. Thanks again for sharing!
https://github.com/compilers-course-materials/
The lecture notes (as SVG/source code) are at:
https://github.com/compilers-course-materials/cs75-s16-lectu...
in particular.
https://www.cs.swarthmore.edu/~jpolitz/cs75/s16/index.html
I think the incremental approach is terrific, because it allows you to get to a program the emits assembly and builds a working binary in week one. The first thing this does is give a concrete example of what "a compiler" is. The second is to provide a great foundation for discussing static vs. dynamic and what decisions are made at compilation time vs. runtime, without needing a full implementation. These concepts are not obvious (e.g. when can and should a check for unbound ids happen? What about divide by zero, or overflow, or type mismatch?), and deserve to be carefully taught and considered.
This lets the course build up a new feature, from front-to-back, each week or two, and consider its implications on the whole pipeline each time.
fun square(n):
n * n
end
is a closer direct comparison to the Python program, for contexts that don't use annotations.