0.1.3 • Published 8 years ago

metamagical v0.1.3

Weekly downloads
2
License
MIT
Repository
github
Last release
8 years ago

Meta:Magical

WARNING
This project is still in early stages of development. It's not ready to be used yet.

Meta:Magical allows you to annotate objects in JavaScript, and inspect them in an interactive environment (REPL).

Example

You can use the Meta:Magical browser to inspect objects:

$ node
> var meta = require("metamagical");
> meta.browse(Object.prototype)
Object.prototype
================

Category: Built-in

Object is the root of JavaScript’s hierarchy of objects.


Properties in Object.prototype
------------------------------

Comparing and testing:
  * this.hasOwnProperty(key)
     | Tests if the object has a property `key`.
  * this.isPrototypeOf(object)
     | Tests if the object is in the prototype chain of `object`.

( ... )

You can attach meta-data to your own objects by using the metamagical/decorators module:

let { documentation, category } = require('metamagical/decorators');

@documentation(`
A structure for values that may not be present, or computations
that might fail.
`)
class Maybe {
  @category("Transforming")
  @documentation("Transforms the value inside a maybe")
  map(f) {
    ...
  }
}

Or by providing a property with the global @@meta:magical symbol:

function add(a, b) {
  return a + b;
}
add[Symbol.for('@@meta:magical')] = {
  'complexity': 'O(1)',
  'category': 'Maths',
  'documentation': 'Sums two numbers.'
};

For objects that you don't control, you can attach meta-data by using the metamagical/interface module:

$ node
> var { set } = require('metamagical/interface');
> set(Object, 'name', 'Object');

Installing

The only supported installation form for metamagical right now is through npm. If you don't have npm yet, you'll need to install Node.js:

$ npm install --save metamagical

Documentation

To learn about the bits and pieces of Meta:Magical, you can just load the module itself in the Node REPL:

$ node
> var meta = require('metamagical');
> meta.browse(meta);

A conceptual documentation is being written, which will explain the idea behind the project. The following sections of this README are a short introduction to those concepts.

The CHANGELOG.md file documents all of the important changes in the project. It includes information about when or why to upgrade, and how to upgrade in cases of breaking changes.

Why?

How does one learn how to use a library or framework? Usually they would have to open up a separate tab and load an HTML page with the documentation, then search for the thing they want to get more information in. Different applications provide different features for "finding what you want," Hoogle has a powerful search by approximate type signature feature, most HTML documentation allows you to search by the name of the entity you're looking at, and then some provide you no search feature at all.

This is annoying, but more importantly, it makes it hard to find exactly what you're looking for. The experience of learning something becomes far more taxing than what it could be.

In my PL, Siren, one of the core values is that the entire "world" of the language is reflective and inspectable directly from the interactive shell:

Siren's Browser in action

NOTE
This isn't really anything novel. Emacs and Smalltalk have been doing this for ages, but most programming environments still require you to go out of your way to understand how things work.

JavaScript isn't a language built with meta-data at its core, but it's still possible to attach meta-data to objects after-the-fact, and inspect these objects and meta-data. If you support this with some kind of library, then it's possible to get much of the same features Siren's browser has, and their benefits. Meta:Magical is that kind of project.

Approach

Meta:Magical stores data about objects in a global WeakMap, it also supports objects defining meta-data themselves with a Symbol.for('@@meta:magical') symbol.

NOTE

The global WeakMap relies on there existing only one instance of the metamagical module in your entire program. This relies on both the require cache not being cleared, and the resolution algorithm always resolving the identifier metamagical to the very same file. It IS brittle, but so far I don't have any other idea of how to solve this problem in JavaScript.

Supported Platforms

Meta:Magical requires WeakMaps and Symbols to work, and they can't be polyfilled. You'll need a platform that supports said ES2015 features, like Node's 4+ version.

Support

If you think you've found a bug in the project, or want to voice your frustration about using it (maybe the documentation isn't clear enough? Maybe it takes too much effort to use?), feel free to open a new issue in the Github issue tracker.

Pull Requests are welcome. By submitting a Pull Request you agree with releasing your code under the MIT licence.

You can contact the author over email, or Twitter.

Note that all interactions in this project are subject to Origami Tower's Code of Conduct.

Licence

Meta:Magical is copyright (c) Quildreen Motta, 2016, and released under the MIT licence. See the LICENCE file in this repository for detailed information.