Whilelse is an experimental software development platform that aims to simplify programming by representing code as a web instead of plain text and providing an efficient keyboard-centric editor.
Software development should not be done by fiddling with plain text, but by using a semantic editor that provides efficient keyboard commands depending on the selected element and context. Jumping to a function definition, finding callers should be a matter of pressing a few keys.
Focus on the problem
Efficiently tell the computer what you want in a declarative way and stop worrying about low-level implementation details that add noise to the code.
The software development tools take care of optimisations, and generate code that runs fast, while allowing you to focus on high-level problems.
Flexible multi-paradigm language
Use the most appropriate programming paradigm in each module. Mix functional/procedural/dataflow/etc, high-level/low-level, static/dynamic in the same program. Forget about rewriting the codebase or extracting services and writing APIs just to use a different paradigm. Define your own domain-specific languages instead of implementing everything with the limited elements of a traditional language, which generates a lot of noise in the code. Represent the business logic in a way that's closest to how you think about it. Import a language just like you would a library.
No setup - easy to get started
Getting started with a new software development tech should not mean installing an arsenal of development tools, and any tackling problems arising during installation. Just start coding in the browser, with a fully functional editor, runtime and testing environment. A help panel will show you around and help you with keyboard shortcuts and other guidance relevant to the current context.
When you're ready to deploy your application, just press the right keyboard shortcut. No need for mucking about with Puppet or Docker. For advanced deployments you can use a server provisioning language within the same editor.
Easily trace any change to the code. With the source control systems of today, large commits and refactors make it difficult to follow how a piece of code evolved. Each change is recorded individually rather than commiting chunks of code diffs. This also reduces the probability of conflicts during merges. By representing the code as a graph, moving code can be represented as a simple reference change rather than deletions and additions of large blocks of code.
Simple dependency management
Point to the exact versions of called functions or other elements of a library. An application may depend on multiple versions or branches of the same library. Upgrading a library with backward-incompatible changes can be done gradually.
Easy API management
Share your public interface with others so they can interoperate with your application. Creating an API is defining a set of functions and some metadata like access rights. As long as they use the same system or a compatible one, they can call your services like they would call a function, with the same type of parameter completion. Also, as with libraries they will reference a specific version of the API. The nitty gritty details of the API publishing and invokation is automatically handled by the system.
Today, the universal format for programs is plain text, which is very simple and supported by a wide range of editors. With a universal format for representing code as a web, you can have the same simplicity. Multiple languages can use the same underlying format. You can view or edit the underlying web with a basic editor in case the high-level one is incomplete. Source code management is based on this low level format, just like Git/SVN is based on text files.
Code is represented as a web of Nodes which are connected by Refs.
A Node consists of:
- a unique ID by which other nodes can reference it
- a name, a string that can be shown on the UI, acts as a special attribute
- a type which points to a node_type node
- a set of Attributes
- an array of refs, each pointing to a Ref
- an array of inbound refs
An Attribute consists of:
- a type, which points to an attr_type node
- a value, which can be a string, number or boolean
A Ref consists of:
- a type, which points to a ref_type node
- a source node pointer
- a target node pointer
- a dependent flag, that determines whether the target is treated as a component of the source node or the source node simply links to the target
The following diagram shows an example of how a function node is connected to its implemenation node and some core nodes:
The primary storage mechanism is a log of basic commands executed on the web model. Code history, synchronisation, merging, undo operations can be based on this basic model, without knowledge of the language or the tools using it.
The plan is to have Documents that form a unit of access management and each consists of stream of changes, akin to a source control repository. Each document would have its own unique ID and its internal ID space. When a node in an external document is referenced, it will create an import node that will have a local ID, and each reference will point to the local import node ID and the target ID local to the imported document.
The schema language can be used to define the structure and behaviour of other languages.
A language schema consists of a set of node types, attribute types and ref types, and the properties of these, like what types of attributes or refs can a node have, required or optional, single or multiple.
Whilelse is currently in experimental status and has a working partial prototype.
You can define functions, expressions, simple classes. Furthermore, it supports ES7-style async/await, reactive variables (similar to MobX) and a React JSX-style experiment is currently underway. There's also a domain-specific language for building a simple web application with HTML templates.
A trivially simple application written and executed in 21 seconds.
Click the video to play.
Count from 1 to 100.
- When the number is divisible by 3, say "Fizz",
- when divisible by 5, say "Buzz",
- when divisible by both, say "FizzBuzz",
- otherwise say the number.
Attach a test to any function, switch back-and-forth between the function and its test, and run the test with a keyboard command. It can be extended to run the test after each change.
An example of a high-level Domain Specific Language (DSL), using which you can create and run a trivial REST API in less than a minute.
Each endpoint is defined as a function, its parameters are translated into query variables, the inputs are validated and converted according to the data types, and the return value of the function is converted to the response of the request.
Work-in-progress DSL for React components.
Takes care of all the boilerplate so you can run your app with a few keypresses.
To try it out yourself,set it up on your machine. Please note it's early stages so it's a bit hard to get started, but there's is a guide included that will tell you exactly what to do step-by-step.
There's still a lot of work needed in order to make Whilelse a viable development platform. You can help by participating in the development, testing, sharing ideas, writing documentation or providing feedback.
If you're interesed in being part of the project get in touch by email.
Now is your chance to become one of the first contributors!
The following are the major development tasks I have in mind (everything is up for discussion):
- extract reusable components and add tests
- use Webpack as a build tool
- rearchitect UI with React & MobX
- reliable execution and deployment service