Giter Club home page Giter Club logo

codeworld's Introduction

CodeWorld

Build Status Build status

CodeWorld is an educational environment using Haskell. It provides a simple mathematical model for geometric figures, animations, and interactive and multi-player games. The web-based programming environment supports this educational mission with a zero-setup editor and compiler, easy sharing and cloud storage of projects, and the ability to run programs right in the web browser using GHCJS.

There are several variants of CodeWorld available:

  • CodeWorld uses an educational variant of the Haskell language and libraries, designed to support mathematics instruction.
  • CodeWorld Haskell is built against standard Haskell instead of the educational variant, to build programs which can either be on the web site with GHCJS, or compiled natively with the codeworld-api package and blank-canvas.
  • CodeWorld Blocks provides a drag-and-drop programming user interface for younger students to build programs with CodeWorld. This interface still has some bugs, and isn't recommended for use.

Status

CodeWorld is stable and has been used in schools for years! See the users page for a partial list. We're constantly improving the environment, though. Breaking changes, when necessary, are scheduled to occur between typical (U.S.) K-12 school semesters, to minimize disruption of existing classes.

Google is distributing the code for CodeWorld, but CodeWorld is not an official Google project, and Google provides no support for it. Instead, questions about the project or code should be asked to the codeworld-discuss mailing list. A student-friendly question and answer forum is also available at http://help.code.world for questions about programs written using CodeWorld, rather than questions about building or modifying CodeWorld itself.

Getting Started

Just visit https://code.world to get started.

There is no need to download or install anything to use CodeWorld. This repository will be useful if you prefer to fork and modify the CodeWorld environment, or contribute changes.

Discuss and Learn More

To discuss and hear announcements about CodeWorld, subscribe to the mailing list at https://groups.google.com/forum/#!forum/codeworld-discuss

The mailing list should be used to:

  • Hear announcements about and discuss upcoming changes and features.
  • Ask questions about using the system, and give feedback about your experiences.
  • Share interesting ways of using the site, related classroom activities, and more.

To report bugs or file formal feature requests, try https://github.com/google/codeworld/issues.

Contributing

There is a slight bit of paperwork involved in contributing to CodeWorld. You'll need to agree to a Contributor License Agreement. See CONTRIBUTING.md for details.

Build and Deployment

Building and running CodeWorld can be a lengthy process, but is automated using the installation scripts in the root directory, which work on most forms of Linux, including Debian, Ubuntu, RedHat, and CentOS. The step by step instructions are as follows:

  1. Read the caveats, explained below.
  2. Change to the root directory of the project.
  3. Run ./install.sh to set up the project.
  4. Run ./run.sh to start the server.

You can now access the CodeWorld system at http://localhost:8080.

If you make changes to CodeWorld, you can rebuild it without rebuilding the dependencies:

  1. Change to the root directory of the project.
  2. Run ./build.sh to recompile just CodeWorld itself, using previously installed tools and libraries.
  3. Run ./run.sh to start the server.

Docker

It's also possible to build and run the server using Docker. This is not yet the recommended way to develop with CodeWorld, but it could get there soon.

Commands to try for docker:

sudo docker build -t codeworld https://github.com/google/codeworld.git
sudo docker run -p 80:8080 -t codeworld

For now, the docker container has no way to access a client id, mount a shared NFS drive, or other setup steps. It will work, but it won't be complete. In the future, this should become the standard way to deploy CodeWorld.

Stack

The stack.yaml in the project's root is present to partially support Intero and Travis CI. On Travis, codeworld-compiler tests do not run.

Building and running CodeWorld locally with Stack is unsupported, and in fact doesn't work. Stack cannot yet substitute for the shell scripts or docker usage above.

Caveats

Authentication

CodeWorld offers two modes of authentication or the ability to run with authentication disabled with reduced functionality. The two methods provided are as follows:

  • Google authentication: this method uses the Google API and Google accounts and is the mode of authentication enabled in the live CodeWorld site; this allows CodeWorld to offload account and credential management to a third party
  • Local authentication: this method uses a simple local database of account information and JWT-based stateless authentication in the browser; this is useful for applications where minimal external dependencies is required

Running CodeWorld in one of these two modes allows users to save and manage their projects and folders. With no authentication enabled, users are able to write, build and run code but lose the ability to save and manage projects and folders.

Google authentication

For Google authentication to work, you will need to obtain a Google API key and store it in web/clientId.txt.

To get a Google API key for your CodeWorld installation, please consult the following resources:

Once you have a Google API key, copy and paste it into web/clientId.txt. A running CodeWorld instance will immediately pick up changes to this file.

In general, the Google authentication system will be the easiest system to maintain since no local password stores are required. This is the mechanism used by the official, live version of CodeWorld.

Local authentication

For applications in which external dependencies, such as Google accounts, are not acceptable, we provide a simple local authentication system:

  • Uses a SQLite3 database
  • Uses good security practices by storing only BCrypt hashes of passwords
  • Uses JWT-based stateless authentication

This provides a local authentication system with very similar workflows to Google authentication (i.e. stateless client-side sessions). Currently, no web-based administrative interface is provided. Instead, you can use the codeworld-auth CLI tool to manage accounts.

The local authentication system may be useful for situations where an instructor cannot reasonably expect all students to have a valid Google account and in which the instructor is willing to deploy a local CodeWorld stack.

Create account database

Local authentication will be enabled if a codeworld-auth.db file is present in the application's root directory. To create this database, run the following from the root of the Git repository:

build/bin/codeworld-auth init-accounts -d codeworld-auth.db

This will create an empty account database with no accounts.

Create one or more user accounts

Assuming you have already created an account database as described above, you can create a new account as follows:

build/bin/codeworld-auth create-account -d codeworld-auth.db johndoe Expired

This will create a new account with user ID johndoe with a randomly generated password. The account will be set to "Expired" which means the user will be prompted to enter a new password at next sign-in time.

Other subcommands are provided for updating and deleting accounts etc. For help:

build/bin/codeworld-auth --help
Create a JWT secret

To use local authentication, you will also need to generate a JWT secret stored in a file named codeworld-auth.txt. This is used to sign JWT tokens passed back and forth between the server and the browser. From the Git repository's root directory, run the following command:

build/bin/codeworld-auth generate-secret -s codeworld-auth.txt

This will generate a new random JWT signing key. The server should not expose this secret to external users.

Swap Space

If you are installing CodeWorld on a virtual server, be aware that the default RAM on these servers is often not sufficient for GHC. CodeWorld needs to compile very large Haskell projects during its installation. The following should be sufficient to resolve any out-of-memory problems you encounter:

$ sudo dd if=/dev/zero of=/swap bs=1024 count=2097152
$ sudo mkswap /swap
$ sudo swapon /swap

This creates a 2 GB swap file to increase available virtual memory. Installation with a swap file may be slow, but it will succeed. (Unless you intend to write very large programs in CodeWorld, it's usually safe to remove the swap file after running the server for the first time.)

codeworld's People

Contributors

3noch avatar alphalambda avatar blackgnezdo avatar cdsmith avatar chelseaharper avatar devanshbatra04 avatar endgame avatar jhrcek avatar josephcsible avatar joshcough avatar kammitama5 avatar kaustubhhiware avatar luite avatar marcianx avatar misterbeebee avatar nixorn avatar nomeata avatar parvmor avatar patrickscottd avatar peterbecich avatar powell-v2 avatar pranjaltale16 avatar rcook avatar sjakobi avatar stefaj avatar tgdavies avatar three avatar thsoft avatar venkat24 avatar zavierhenry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

codeworld's Issues

Bad types appearing in error messages

When compiling the declaration:

f(0, 0) = f(0)

CodeWorld produces a bizarre error message:

Couldn't match type Number with (Number, Number)
Expected type: integer-gmp:GHC.Integer.Type.Integer
               -> (Number, Number)
  Actual type: integer-gmp:GHC.Integer.Type.Integer -> Number
In the first argument of f, namely (0)
In the expression: f (0)
In an equation for f: f (0, 0) = f (0)

Eww! GHC appears to be talking about the type of the implied fromInteger function, which is inserted by the RebindaleSyntax language extension.

Runtime errors with source locations print poorly

A pattern match failure looks pretty awful:

P02419H-LTUMYgT3m0AtqgQ==.hs:3:1-31: Non-exhaustive patterns in function branch

Two issues here:

  1. The hash-based file name wasn't replaced with a friendly version as we do for compile errors.
  2. The column range in the srcloc isn't converted into a link as we do for compiler errors.

Both should be happening. This probably means moving all post-processing of compiler messages to the client, but that's fine.

More elaborate tutorial help

The tutorial help should be much more elaborate. It should include:

  1. A sequence of lessons, to introduce students gradually to the capabilities of the system.
  2. Exercises to do along the way.

Sound

We could support programmatic generation of sound by using a function Number -> Number (time to amplitude sample). The sampling frequency would need to be FAR higher than the animation frequency, so we'd batch it and use a buffer.

Problems:

  • The JavaScript audio API doesn't work with Internet Explorer (possibly other browsers).

  • Performance would be a challenge, and we need to make sure this can be done efficiently to avoid stuttering, even on slow computers.

  • It's not clear how to merge this into games. The obvious way would be

    audibleInteractionOf(initial, step, event, draw, sound)

But this ties the audio sample rate to the frame rate, which is bad. Another way would be to maintain a different World type for sound, but this is too complicated. Definitely could use some thought.

  • We'd need a reasonable kind of abstraction that doesn't involve new ADTs with complicated behaviors. Working directly with wave forms might be an educational experience for a bit, but it shouldn't be unreasonably hard to just choose a timbre and play a melody.

Constructive geometry

Additional operations should be added to combine shapes:

intersection :: [Picture] -> Picture
difference :: Picture -> Picture -> Picture

(Names are debatable.) intersection should produce a picture bounded by the intersection of the list. The second should produce a picture containing all areas of the first image that are not also in the second. Note that together with the existing pictures, this gives the three basic operations for constructive geometry.

The implementation is a little tricky. Combining two images in this way can be done with globalCompositeOperation (https://developer.mozilla.org/samples/canvas-tutorial/6_1_canvas_composite.html) But getting the resulting shapes to nest correctly will involve using off-screen canvases as temporaries. Since creating a new off-screen canvas is expensive, this should involve determining the minimum number of offscreen canvases needed, and reusing them between frames.

Pre-define a Picture called coordinatePlane

It's very useful to be able to superimpose a coordinate plane onto the image. To facilitate this, predefine a "coordinatePlane" symbol, which is the the axes and coordinate plane, and can be drawn onto the canvas.

Sign-in buttons stop working after identity token expires.

If the identity token expires, the server fails to validate it, but the client thinks the token is still valid. At this point, strange things start failing. Even signing out and signing back in does not restore things to a usable state.

Firefox tries to run gapi.auth when it isn't set

In Firefox, this message sometimes appears in the JavaScript console:

TypeError: gapi.auth is undefined

This is most likely a result of a timing problem, where some call that relies on sign-in state is being made before the authentication API is completely loaded.

Offer other options for logging in

Rather than requiring everyone have a Google account, there should be other options. Including:

  • Creating a username and password for this specific site.
  • Log in via something else, such as Facebook

This means we'll need to maintain our own user identifier, and a mapping from various kinds of credentials to the local identifier. Not too hard.

Doc on hover

When the user hovers the mouse over a standard library function, we should pop up a tool tip with basic type and documentation for that symbol.

Autogenerate the syntax highlighting word list

I've just hard-coded the list of built-in words into JavaScript for syntax highlighting. This duplicates the efforts for auto-complete, and is very likely to get out of date if the prelude is modified in the future. Instead, this should be generated from the output of codeworld-autocomplete just like the auto-complete word list is.

Most likely, both should just use a JavaScript source file that defines the list in a structured format (with type information, etc., for future features... but that can be added when the time comes)

Better example browser UI

Examples should be more easily browsable in the UI. That might just mean a collapsible section (or sections), a tree structure, a search box... something that's not just a wall of buttons.

Trigger auto-complete more often

Auto-complete on ctrl-space is not very discoverable if you don't know about it. Perhaps, instead of binding to ctrl-space, we should actually pop up auto-complete rather more often?

For an extreme case, we could attempt to pop up auto-complete on every keystroke. Then you'd just basically always work with a list of auto-complete options sitting by the cursor. We'd obviously need to turn off the option to auto-choose unique completions, and there are probably some other things we should do to blacklist certain keys at certain times, so that it's at least possible to dismiss the auto-complete box manually.

API documentation needs a custom theme

We should see try to theme haddock to make the API documentation less busy. Things like instances should be removed. The page structure should be re-organized to remove references to modules (like Prelude). Confusing notation should be removed for fixity declarations (or the entire fixity removed if it can't be phrased in a more friendly way.)

Time step debugger

For animation, simulation, and game modes: add a debug option, where students can look at how things look at different times, control the speed of motion (slow-motion and pause), and so on.

The debugger wouldn't operate within the rendering of a single frame; just between frames. So this isn't a GHC internals sort of thing; just a JavaScript/UI issue.

Auto-complete in the editor

The editor should offer auto-complete. Possible sources of auto-complete words:

  1. The standard library
  2. Occasional parse of the user program for things that look like definitions.

Optionally, auto-complete should look for context, by knowing types, scanning backwards for something that looks like the beginning of an expression, and finding things with an appropriate type to fit in the current cursor location.

Text is spaced oddly

Text is spaced very oddly sometimes. This probably has to do with the fact that we're rendering in a 1px font. We should instead render in a larger font, and scale the result down to the desired size.

GHCJS should be invoked in a sandboxed build environment

GHCJS currently runs using the system and user-wide package databases in ~/.ghcjs. This means that updating GHCJS to a new version requires about an hour of downtime while the new GHCJS version is bootstrapped and packages installed.

We should use a sandboxed environment, so that it's possible to rebuild and bootstrap GHCJS, and then copy the environment over in a single operation.

Collaborative coding environment

Students should be able to work together on a group project, and see what each other is doing, edit simultaneously, etc.

It's an open question whether this should follow a source control model, or a Google Docs style collaborative editing. The latter would probably be better, given the ease of use and lower required complexity of projects, but it's also harder to build.

Post projects socially

There should be some way for students to share their projects with friends, parents, etc. This could involve:

  1. Posting to Google+, Facebook, etc., assuming they have an account (for students under 13, this is problematic)
  2. Sharing by email (but careful about abuse potential!)
  3. Some kind of sharing within the site itself.

I lean away from doing anything too elaborate here, since I would rather integrate with something than reinvent it. The right way forward isn't clear.

Better examples

The current set of examples is very scary. We should collect short, easy, and clean examples, each with a specific topic. One or two elaborate examples would be fine, but they should be the exception, and moved to the end.

GHCJS should be killed after a fixed time limit

It's currently possible to write a sort of DOS attack against the server by submitting code that's very expensive to compile (or even doesn't terminate, with UndecidableInstances). To fix this, we should set a time limit for the compiler, and kill it after it's run for too long.

Undo currying for functions in standard library

All standard library functions should be reworked to use tuples as arguments, rather than currying.

The reason for this is that we want to keep the language as close as possible to mathematics, and in mathematics, it's ubiquitous to model multi-parameter functions as cartesian products and to write them as f(x,y). The idea is to adopt a convention (just like in mathematics) of always writing parentheses in function application.

As a nice side-effect of that notation, the number of situations where parentheses are only needed for negative numbers drops a lot, and the places where it happens are more obviously confusing.

Errors in Firefox JavaScript console.

Firefox shows a lot of errors in the JavaScript console, such as:

syntax error listExamples:1
syntax error listProjects:1
not well-formed compile:1

Since these responses are just plain text, it's not really clear what syntax or well-formed-ness condition Firefox is trying to check. Should probably track these down and figure out what they are about.

This does not stop the correct operation of the site.

Web redesign

The web site is poorly designed, from a visual standpoint. It needs some care and attention from someone with decent visual design skills and more experience with web page design.

thickRectangle doesn't match up properly.

thikRectangle leaves a corner out of the picture. This is because it's converted into a thickLine, and the underlying canvas doesn't realize it's a closed shape.

Two possibilities for a fix:

  1. If the last point is the same as the first in a path, just close it instead of explicitly moving to the last point.
  2. Introduce a new primitive for an open polygon, and use that instead of thickLine.

Library projects

Students should be able to create "library" projects, that give common definitions and can be imported by other projects of theirs. This would be an alternative to copying and pasting definitions between their projects.

API documentation is missing descriptions.

There is no haddock-format documentation for most of the API. This should change. Given the target audience, we need extremely high quality documentation, including examples with images of the results, and careful explanations that don't assume prior knowledge of language ideas.

Auto-complete should be type-sensitive

We can do a better job of showing only the auto-complete options that might fit in a certain context. For example, we could look around the current cursor position to see if the user is typing a function call, and if so, look up the type of the function, and only show function names if they might eventually lead to the desired result type.

This would necessarily be a heuristic, since the user is typing the program, so it's guaranteed to not be syntactically correct most of the time; but there's a lot we can do.

Leave comments on a project

Students and teachers should be able to comment on projects. The comments could be attached to the entire project, or a line of code.

Consider changing the logical scale to 20x20

For pedagogical reasons, we likely want to rescale the "logical" canvas to (-10, 10) x (-10, 10). This would:

(a) let students reason with smaller numbers that they are more familiar with.
(b) introduce more reasons to use fractions or decimals for precision, which aligns with middle school mathematics.

Point pins

In picture, animation, and simulation modes, when the user hovers the mouse over the picture, we should render a tool tip with the coordinates of the current point. When the user clicks, we should "pin" the tool tip, leaving a visual pin there, labeled with the coordinates where the mouse click occurred. Clicking a pin should cause it to go away.

In the past, students found this to be an extremely helpful way to plan their drawings.

Think about how not to retain too much at drawing time

The standard pattern in CodeWorld is that a program defines a potentially large tree structure, and then traverses it exactly once. Laziness helps here, but the default memoization that Haskell uses for lazy values is unnecessary, and likely results in worse-than-needed memory usage for large scenes.

I should:

  1. See if I can gather benchmarking or profiling data to show that this is a real problem.
  2. If so, consider possible solutions. For example, pictures could be Church encoded as functions, if the result performed better in benchmarks. Or the recursive constructors could use () -> Picture instead of Picture to prevent memoization of their result.

Errors likely due to overly aggressive caching of generated JavaScript

Hi,

I'm using Chrome and currently getting many errors. My javascript console is telling me that it's simply internal server errors (when I press the run button). Things were working fine with Chrome last night. Was there possibly a redeploy that might have broken things?

Things are working well in Safari though.

-Josh

Guided help

There should be some guided help flows that show new users around, with arrows pointing to which buttons to click, etc.

Large edit history prevents files from saving

Because we limit the incoming size of requests, trying to save a file with a large undo history can overrun this and fail. The workaround is to copy the buffer, paste into a new buffer, and save that. What a pain!

Need to increase the max size limit, and/or limit the length of undo history to stop this from happening.

Need to stop TemplateHaskell more systematically

Currently, TemplateHaskell isn't possible within CodeWorld because we pass --no-native to GHCJS. With Luite's upcoming TH changes, though, this will not suffice. Most likely, the right answer is to build a filter that pre-parses the source file using haskell-src-exts, and then rejects programs which enable TemplateHaskell, and perhaps other dangerous extensions as well.

List comprehension helper

Add an interactive list comprehension builder that lets students build list comprehensions easily and see sample results as they go.

It's not entirely clear how this should work, but it's an interesting idea.

Option to export projects to Android and/or iOS

It would be really cool if students could generate links to install their projects as Android or iOS apps on a phone or tablet. The app would be a web view, wrapped as an application with a set of generated files.

Concerns:

  • The set of available events would be much smaller. It may be that we should simplify the event model anyway to include just mouse moves, clicks, and drags.
  • iOS might not be possible without the student either jailbreaking or getting a $100 developer license. Android would require enabling third-party apps.

Scaling and zooming controls

For picture, animation, and simulation modes, add controls for the students to zoom and pan the canvas. Gloss has these, and they are often convenient.

Project gallery

Students should be able to submit projects for public release, which would go into a project browser that other students can see.

Some form of filtering might be needed to make this safe for kids projects. An easy implementation would be a global queue for trusted users to evaluate. A more elaborate answer would know who each child's teacher is, and let them approve it.

Folders for student projects

It's actually pretty easy to create enough projects that you start to lose track of them all in a flat list. I should add the ability for students to group projects into folders, so they can keep similar or related projects together.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.