jathak / dart_scheme Goto Github PK
View Code? Open in Web Editor NEWOnline Scheme interpreter, formerly for 61A
Home Page: https://scheme.jenthakar.com
License: BSD 3-Clause "New" or "Revised" License
Online Scheme interpreter, formerly for 61A
Home Page: https://scheme.jenthakar.com
License: BSD 3-Clause "New" or "Revised" License
It looks like contenteditable
is never set to false after a statement is run, so if you select an old input, you can still edit it.
I would suggest that call/cc
should be renamed call/ec
, and callWithCurrentContinuation
similarly to callWithEscapeContinuation
, since that's what it really is in this implementation.
Right now, the Number
class effectively wraps BigInt
and double
, using whichever is appropriate. It might be cleaner to have separate Integer
and Double
classes that inherit from an abstract Number
class. This would allow for cleaner type checking for integers and probably clean up the implementation somewhat as well.
This works but shouldn't
>>> '[1 2 3)
(1 2 3)
The web REPL's input field has a lot of complex logic for syntax highlighting, paren counting/completion, and (soon, once #50 is merged) automatic indentation.
A lot of this functionality will also be necessary for the editor (#21), so it would be nice to reuse as much of it as possible.
If we ever add doc previews as you type (#4), then this new refactored library could allow that functionality to be shared between the REPL and the editor too.
Although it's not that hard to add them on my own, (in a hacky roundabout way), I thing this 3 important functions should be included in default scheme library:
(define (macroexpand-1 exp)
(apply (eval (car exp)) (cdr exp)))
(define (gensym . prefix)
(if (null? prefix)
(string->symbol (string-append "gsym_" (random-string)))
(string->symbol (string-append (car prefix) "_" (random-string)))))
(define (string->symbol str)
(deserialize
(string-append "{\"type\":\"SchemeSymbol\", \"value\":\""
str
"\"}")))
(define (random-string)
(js "Math.random().toString(36).substring(2, 15)"))
As the user types, available procedures that match the prefix should be displayed in some fashion
It would be nice to be able to embed reference docs (such as the language spec and primitive procedure reference) directly into the interpreter.
For instance:
scm> (info map)
------------------------------------------------------------------------
map - built-in procedure
------------------------------------------------------------------------
(map <proc> <lst>)
Returns a well-formed list constructed by calling `proc` (a one-argument
procedure) on each item in `lst` (a well-formed list).
(this would then be rendered nicely in the web interpreter (we could even have info automatically display as you type)
(define n3 (list 'c))
(define n2 (cons 'b n3))
(define w (cons 'a n2))
(set-cdr! n3 w)
When typing commands such as display w
or even just w
, it falls into a dead cycle without any response.
The problem may be solved by introduce '#n#' notation as what DrRacket does. So the list can be represented as #0=(a b c . #0#)
.
Example:
scm> (+ 1 2)
3
scm> (
)
()
scm> # up arrow takes me to the multi line ( )s but I can't get to the first expression anymore
From @jathak on November 26, 2017 8:23
Changing the interpreter theme should call the same jsPlumb refresh method that we currently call on screen resizes.
Copied from original issue: jathak/scheme_web_interpreter#2
Right now, there's no indication in the diagram that a frame is for a macro. The old interpreter at least tagged the function with "macro". It might be helpful to distinguish between the macro's return and the expression evaluated afterwards.
pub serve
will apparently be removed in Dart 2, so I'll need to switch things over to the new build_runner
infrastructure.
Perhaps if "logic" is somewhere in the URL, change to a Logic interpreter with no Scheme. We could then have logic.cs61a.org map to the same app as scheme.cs61a.org, but have it load Logic.
scm> (pixelsize 100)
scm> (pixel 0 0 "red")
scm> (pixel 0 0 "#00FF00")
draws a blue pixel, when it should be green.
The Python interpreter includes several additional math built-ins.
It would be nice to have functionality that more-or-less matches the Python version.
Since the built-ins in Python come directly from the Python math module, there's likely to be some variance between them and the corresponding functions in the dart:math library.
These built-ins should probably be added as a part of a separate SchemeLibrary, instead of adding them to the StandardLibrary
While it's not as bad as the old interpreter in this regard, there's a decent chunk of built-in procedures that aren't really relevant to this interpreter's core purpose: teaching 61A students Scheme.
To that end, I'd like to restrict the core library to the following:
clear
, bindings
, theme
, maybe a few othersFor everything else, we'll move them into a set of core libraries that can be imported when needed, similar to how the Logic library currently works (though we'll only have a single library
procedure for imports, rather than a separate loading procedure for each library).
tldr: Does it spark joy teach Scheme? If not, throw it in an optional library.
When typing something into the interpreter and you press the down arrow before pressing Enter
, the interpreter displays an empty line. Pressing the up arrow displays the previous line, and the "in-progress" line being typed is lost.
Similarly, when you are typing something into the interpreter and press the up arrow before pressing Enter
, the interpreter displays the previous line. Pressing the down arrow displays a blank line, and the "in-progress" line being typed is lost.
A possible behavior that is more intuitive is to save the in-progress line being typed when the up or down arrow is clicked. Here are a few scenarios, where the user has typed some input and hasn't pressed Enter
yet:
The old interpreter had vectors. The diagramming framework has been set up to support them from the beginning, but I haven't actually gotten around to actually implementing them.
Some of these tests build on each other, but a lot don't. We can split some out to allow the tests to be run in parallel. This would be especially useful for the logic tests, since some of them can take longer to run.
Ctrl-Enter might be a good keyboard shortcut for this, since we already use Shift-Enter to auto-complete parens
This is trivial to do here (the displays were changed from #t
and #f
to True
and False
for consistency with the Python version of the interpreter), but we're blocked on Cal-CS-61A-Staff/berkeley-cs61a#856 (the same behavior for the Python version).
In preparation for the editor (#21), I'd like to add some sort of unified file system.
Ideally, it should support files from the following sources, accessible through a unified API and mountable at any level:
web/scm
directoryweb/scm
directory, but hosted elsewhere)Of these, only the first three would be especially important to start, but I want to make sure the system is set up to allow for the others. Mounts of outside sites could also be useful for things like lecture code.
I think I'll likely create a separate package for this, and then depend on it here.
When (logic)
is run a second time, it should clear the existing Logic environment. I thought this was already happening, but apparently not.
Not sure if this worked before or not, but I can't select text and hit command-c and command-v. Did this just never work?
I know you're still updating the editor, but at this point the old editor still works really well and would really help a lot of students. It's hard to find at the moment and I've talked to many students that didn't know it existed.
Once #21 is done, it would be nice to be able to load code from your Ok backups.
This is likely due to listening for Ctrl-V, but not Cmd-V.
Right now, unforced promises are displayed as #[promise (unforced)]
and forced streams are displayed as #[promise (forced)]
.
This means that you can't see the remaining values in a stream, even if they've already been forced.
Ideally, it would be nice if streams (at least) could render as
(1 2 3 ...)
or something similar (possibly with an indicator to distinguish between a stream and Scheme list).
This change would need to be made simultaneously both here and in the Python interpreter, and should happen between semesters.
Let's keep discussion of this issue that doesn't have to be private to the course here.
The chess app that I wrote back in Fall 2014 has survived with minimal changes for 3.5 years. However, it still doesn't support the following features:
Compiled from the old interpreter (note, the repo is private to staff, so the links may not work):
There's probably others too (underpromotion, for instance).
I don't really know the rules to chess that well, so I don't think I'll ever end up fixing them. This is low priority, but if anyone wants to work on it, the code is here. @sequoia-tree?
We've used "primitive" in the past to refer both to built-in procedures and to atomic expressions. I'd like to eliminate the overloaded use. This change needs to be made both here and in Cal-CS-61A-Staff/berkeley-cs61a#1570. (private issue to change it in the Scheme project)
When typing something like the following
scm> (if predicate
consequent
alternative)
it would be nice to have newlines auto-ident to the right level (according to rules like these).
It should work exactly like error.
scm> (define x (delay (begin (print 2) (/ 1 0))))
scm> (force x)
2
Error
scm> (force x)
2
Error
but right now it seems to cache the value and not re-evaluate it
scm> (define x (delay (begin (print 2) 0)))
scm> (force x)
2
Error
scm> (force x)
Error
It would be nice to be able to render pairs after they have been output when you hover over them.
In the old interpreter, there were 4 UI components (the REPL, the diagram, the turtle canvas, and the button list). There was only one of each component and its location was fixed (the REPL took up the whole screen, and each other element was kept in the corner).
In the new interpreter, most components can support being created multiple times (though in practice, this is only currently done with diagrams). In the future, an editor component, might spawn another REPL.
We should remove the render
built-in entirely. Diagrams/visualizations are now displayed inline, and the corner rendering for them is broken anyway. This will probably also allow us to remove the concept of "rendering" diagrams from the interpreter entirely. HtmlRenderer
should be a separate library that the web REPL (and any other components that might render diagrams in the future) depends on directly.
The old interpreter had an editor that was mediocre, but got the job done. I'd like to get something even better added to this one.
Implementing this would likely require setting up some sort of file system (another old interpreter feature missing here)
Right now, visualize
turns off TCO while it is running. This makes sense because the diagrams that would be generated if it was on wouldn't make sense.
It would be nice to have a separate visualize-tco
option to show how the frames are reused.
The old interpreter did this automatically whenever these objects passed between the two languages, which was a bad decision that lead to some hacks like:
; array lives in js land to avoid expensive conversion
(define sequence ((js "(arr)=>(type, a, b) => {\n"
"if (type === 'add') {\n"
" arr.unshift(a); return;\n"
"}\n"
"if (type === 'dump') {a(true, arr); return;}\n"
"return arr.slice("
"Math.max(0, arr.length - a - b), "
"Math.max(0, arr.length - a));\n"
"}\n") nil))
from lib/music.scm
Because of this, I made Scheme pairs and JS arrays pass to the other language with no conversion. JS arrays are readable in Scheme through code like (js-ref (js "[1, 2, 3]") "1")
, but there's currently no good way to manipulate Scheme pairs from JS (due to dart2js making the properties unreadable).
There are two things I'd like to do:
list->js-array
and js-array->list
procedures, or possibly piggy-back off vectors (#23)first
and second
directly.lib/builder.dart
makes adding primitive procedures to the interpreter easy, with type checking and automatic conversion between Dart and Scheme types.
However, it's also an unmaintainable mess. _buildPrimitive
should be split into two phases: a parser that creates some sort of struct representing the various properties, and a code generator that builds the primitive wrapper code based on the struct.
On https://scheme.cs61a.org/, visualize
seems to be broken.
When running the command (visualize (define x 5))
, I get the error message
TypeError: Instance of 'minified:tp<dynamic, dynamic>': type 'minified:tp<dynamic, dynamic>' is not a subtype of type 'minified:et<minified:l, minified:c>'
Easy fix would be when students type (clear) have a little help icon appear on the right side of the screen. When clicked, it creates a pop up that displays the same text that can be found on the top of the interpreter (including the link to the editor).
Or maybe you could always just have the help icon on the side that opens the text on the top and just default it to be open. Not sure but either way it's annoying having to refresh the page to get the links back.
From a student bug report, code like (remainder -4 3)
stalls.
This should be a pretty quick fix in lib/src/core/standard_library.dart
From @jathak on March 10, 2018 0:16
Promises are currently the same color as pairs in the default theme. This should be fixed.
Copied from original issue: jathak/scheme_web_interpreter#4
This expression freezes scheme repl:
(print (+ 10 (call/cc (lambda (c) (* 20 (c 5))))))
From @jathak on November 26, 2017 8:22
The old interpreter had both mouse clicks and touchscreen taps on the Turtle window fire turtle-click Scheme event.
In the new interpreter, only mouse clicks currently work. This should be fixed so that touchscreen taps trigger some event, whether it be turtle-click, or a separate event.
Copied from original issue: jathak/scheme_web_interpreter#1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.