Skip to content
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

Live Projectors #1420

Open
wants to merge 128 commits into
base: dev
Choose a base branch
from
Open

Live Projectors #1420

wants to merge 128 commits into from

Conversation

disconcision
Copy link
Member

@disconcision disconcision commented Nov 20, 2024

Closes #702, closes #829.
Projector fixes: closes #1359, closes #1396, closes #1436, closes #1489
Hazel selection fixes: closes #1448, , closes #1147, closes #890, closes #880, closes #1351, closes #879
General Hazel fixes: closes #1300, closes #1471, closes #933, closes #1421.

For an introduction, see the Probes slide here: https://hazel.org/build/projectors-live/.

TODO:

  • Better control arrow sync across multiple probes
  • Make exercise mode student implementation panel get probe data from student tests

Core Feature: Probe Projectors

  • Use the projector panel or alt/option-v to apply a probe projector to any expression or pattern
  • When a term is probed, live values will show in cells to the right of the line
  • Cells in function bodies are grouped by function call
  • If the dynamics are still calculating, or if the expression is never executed, the probe icon will spin
  • If closures are found for that expression, the number of closures are indicated in the probe superscript
  • By default, live cells based on all gathered closures are shown; double-clicking on any cell restricts that probe to show only that one cell.
  • Hovering over a cell of the currently indicated probe which is not a pattern of variable reference shows the (co-contextual) environment (i.e. the values of variables in the expression)
  • Clicking on a live cell sets a global (across-probe) closure cursor powered by that closure's call stack. Other cells (across all probes) will get decorated based on their 'relative positions' within the call graph.
  • To expand/contract a cell, hold shift and drag left/right to progressively un/summarize the value. This also un/summarizes values in the corresponding environment view.
  • Double-clicking on a probe on a function application 'pins' that application; for applications with more than one execution (call), the currently selected call will be pinned
  • If there are more than 30 ish cells, the others will be cut off; this is indicated by ellipses to the right. When such a probe is indicated, small arrows will appear to the left of its cells to allow moving the window of cells shown.

Probe caveats:

  • Adding two probes on the same line will currently result in their cells overlapping; you can manually add a linebreak to work around this
  • Probe value displays currently do not support indeterminate forms, which will show up as ?

Hazel Features:

  • Probe system. Instrumenting a term by wrapping it in as Wrap(term, Probe(options)) will make the evaluator collect information about the term's evaluations. This currently includes a value, a (filtered) environment, and a call stack. The options on Probe are intended to be added during statics, and can refine what is collected. Currently, they are used to filter the collected environment to the values occurring in the expression's co-context.
  • Clipboard cache: When you copy or cut a selection corresponding to a complete segment (a selection that contains no shards with corresponding backpack items), the underlying segment is statefully retained. If text is pasted which is identical to the text serialization of that stored segment, the segment is used instead. This speeds up pasting, and also retains projectors.
  • Selection improvements: Click-drag now persists when the mouse cursor is outside the browser window. Various other selection fixes and features (see closed issues list)

Projector System Features:

  • The projector API has changed. There are four new entries, described below, and some of the method arguments have been changed to provide new information to projectors.
  • Projectors can get dynamic info in their infopack. This is gated by API flag (dynamics=true). This information consists of a list of 'closures', each of which has a value, a (co-contextual) environment, and a call stack corresponding to one evaluation of the probed term or pattern.
  • Can now project all terms and patterns, not just operand-shaped ones. When un-projecting non-operand-shaped projectors, the previously projected syntax will be left selected, as this now enable back-and-forth toggleability thanks to:
  • Can now project based on selection (not just indication). Any selection which corresponds to a full term can be projected. Caveats: Term must not be whitespace-padded on the outside. It also suffices that the term be a term in isolation, even if it's not a subterm of the program, e.g. 1+2 in 1+2*3 can be projected. If this makes people too angry I'll consider changing it.
  • Projectors are retained on cut/copy/paste (see Clipboard cache below)
  • Projectors can now specify three optional views. The offside view renders at the end of the line where the projector is located (the probe projector uses this for value displays). The overlay view renders above all code text, code decoration, and base projector views (the probe projector uses this for closure count and function pin indicators). The underlay view renders below code text, and is intended to support custom projector indication and selection decorations, although this is currently only partially implemented.
  • All projectors now have keyboard shortcuts. Alt/option-v for probes, -t for type, and -l for livelit-style projectors (chooses the first that matches the indicated syntax)
  • Projector keyboard shortcuts now show when you hover over the projector panel when the relevant projector is active
  • Projectors are now provided (through info.utility) with some helper functions for piece/segment/term conversion. These are included to avoid cyclic dependencies, and will hopefully be deprecated by the upcoming Splice Projectors PR.
  • Projector view functions are now provided with a view_seg callback to render non-interactive view of syntax. This is currently used for probe projector cell value displays. This will be deprecated by the upcoming Splice Projectors PR.

Updates to existing projectors:

  • Fold projector now show their hidden syntax on-hover
  • Type projectors now displays at the end of the line like probes. New keyboard shortcut option/alt-t
  • All livelit-style projectors now have combined keyboard shortcut option/alt-l

Projector System Feature Removal:

  • The ability to project Typs and TPats has been removed. Only fold was currently applicable, and there are brittle syntax edge cases here, so easier to disallow it for now. However, type holes can still be projected (to support eventually type inference UI)

Hazel Internal changes:

  • Parens in Term has been renamed to Wrap, and has a tag which is either Parens or Probe(_). These should be treated identically semantically; the only difference should be side-effects in evaluation.
  • The code completion buffer is now implemented as a comment inside a selection (instead of a tile). This should be noticeable but should be less brittle wrt code changes as remolding/erasure will now never have to care about its shape.

Future work:

These are features that are either cut for time or are waiting on in-pipeline subsystems.

Fixes:

  • There is still an outstanding drag-selection bug (which exists on dev but is masked behind selection bugs fixed above). When dragging down specifically, sometimes the selection will get 'stuck' and require the cursor be jostled from side to side. I don't know why.

Projector System Features Deferred to Future PRs:

  • Feature: Projectors ExplainThis
  • Feature: Projectors should indicate strictly contained static errors
  • Feature: Overlay projector option: Don't replace the syntax, but augment it over top. Could be used for probe, test.
  • Feature: Probe projector: A way to reset the closure cursor

Probe Features Deferred to Future PRs:

  • Feature: Enable editing of probed expressions (requires splices or overlays)
  • Feature: Grey out unevaluated probes (current deco arch makes this awkward)
  • Feature: Use ellipses to rescale space available for cells (ideally snapping to cell, not just cut-off)
  • Feature: Adding a new probe on the same line as another removes the first
  • Feature: Improve & Extend value/syntax abbreviation logic and add multiline value display (drag down)

Speculative Probe Features:

  • Feature: Probe mouse hover & keyboard focus (move closure cursor, resize cell, resize cells bound)
  • Feature: Highlight function names corresponding to pinned/indicated calls associate caller/callee more closely
  • Feature: 'Step' display option showing environment substituted into expression (but not evaluated)

@disconcision disconcision marked this pull request as ready for review December 11, 2024 02:34
@disconcision
Copy link
Member Author

disconcision commented Dec 11, 2024

@Negabinary this is only tenuously out of draft but i'd appreciate a look-over when you get the chance, especially regarding the dynamics bits. Currently I'm doing some things a bit hackily and trying to decide how bad they actually are.

There are two dynamics things in particular I'm wondering about:

  1. Regarding exercise mode dynamics work. I was able to hook up to it in a basic sense, but I'm confused about dynamics across cells. Currently, probes in the correct implementation reflect values from the tests, but the user implementation probes don't reflect values from the user tests, only for executions in the user implementation editor itself. Changing the ExercisesMode piping so that the user implementation cell gets the user test dynamics also doesn't seem to make this work. (As a larger issue, it's not 100% clear to me what should get what. Also, I think I/we should consider, possibly as part of this PR, changing the way dynamics output works to make it slightly more in-line with statics. in particular, maybe dynamics should output a map, and there is just implictly a probe on the syntax root. i.e, the previous dynamics results is now 'just' an entry in the map. This clarifies my interfaces a bit but maybe fucks with stepper stuff?)
  2. Another thing I don't quite understand is that in the current implementation, i'm not actually really accumulating a stack trace... it seems to be more of a lexical equivalent. i.e. I would have expected the current implementation to, if i instrument a variable x inside a function bound to f, defined at the top level, which is called inside a function g, also defined at the top level, and then g is called at the top level, to have entries corresponding to both f and g for variable x. but it only has the immediate call. this doesn't actually immediately matter but I want to understand why my understanding of the code is wrong.

P.S. I did some dead code removal in ClosureEnvironment as I was finding the interface was drifting a bit

Base automatically changed from editor-output to dev December 11, 2024 19:46
src/haz3lcore/FontMetrics.re Outdated Show resolved Hide resolved
src/haz3lcore/statics/TermBase.re Outdated Show resolved Hide resolved
src/haz3lcore/dynamics/Evaluator.re Outdated Show resolved Hide resolved
src/haz3lcore/Measured.re Outdated Show resolved Hide resolved
src/haz3lcore/dynamics/Transition.re Outdated Show resolved Hide resolved
src/haz3lcore/pretty/ExpToSegment.re Show resolved Hide resolved
src/haz3lcore/statics/MakeTerm.re Outdated Show resolved Hide resolved
…with sticky selections during shift-select and jump to indicated
…projector actual unique UUID fixes. fix bug with projector selector showing wrong active projector
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment