Friday, December 6, 2013

User Registration and Login

Basic user registration and login has been implemented, and anyone is now free to make a beta account!

I've been using, testing, and tweaking Thinker for the past few months (along with a few other beta testers), and it's been working very well.

The login and registration forms themselves actually inherit directly from the Quantum model, meaning that the form is a Node with labeled Links to the inputs which themselves are Nodes. Each Node can render itself, binds it own events, and validate itself. The model for the whole form is defined and initiated with Quantum Thinker Data. This paradigm has become my own kind of app framework analogous to something like Backbone.js.

As illustrated in the diagram from my last post, the Quantum Class Hierarchy included some multiple inheritance connections. After working on how best to accomplish this, I devised a method for ad hoc prototype inheritance in Javascript. Instead of defining a classical prototype chain, this technique compiles prototypes with an object extension method I call `uber()`. It's similar to a typical `extend()` method but it works in reverse. This is because compiling inheritance on the fly typically ascends the hierarchy, and applying super namespaces this way is more straightforward. An instance can be created with a prototype that extends any number of other prototypes in any order. As mentioned, prototypes can be inherited with a namespace which allows access to any super methods with the same name.

You can see a Gist outlining this method here.

Tuesday, July 9, 2013

Nodes, Links, and Quanta

In an attempt to organize my code and keep it DRY, I've added a new class which is a super of both Links and Nodes. Links are very much like Nodes in themselves, but there's enough distinction to inhibit inheritance directly from the Node class.
One of the main reasons I didn't make the class sooner is because I couldn't think of a name for it or ultimately conceptualize it. What is more fundamental than a Node?
I found my answer in physics. Just as people somewhat erroneously think of the most fundamental pieces of matter as "particles" even though matter is also energy and elementary "particles" can also be wavelike and make up all forces, I was thinking of the most elementary piece of Thinker data as "nodes" even though the links that connect nodes were a distinct kind of "node" themselves.
Thus enter the proper concept and name: the quantum. A quantum in physics can appear as a piece of matter or a piece of a force field connecting matter, as a particle or as a wave. Likewise, a quantum in Thinker can appear as a particular Node or as a connecting Link.
It's a great example of cross-disciplinary insight!

The Quantum class hierarchy concept depicted in Thinker. 

I've also created a stringifier to go with my new data parser. This format is tentitavely known as Quantum Thinker Data (QTD), and now replaces JSON as the data transport format of choice for Thinker.

Sunday, June 16, 2013

Demo Interaction

I've finished adding some basic interaction to the Thinker v0.12 WebGL online demo. This includes adding, editing, and deleting elements.

Here's a list of the basic interactions.

  • To reposition a node - Click and drag the node. All child nodes will also move with the node, radiating out from the center of the world.
  • To adjust the curve of a link - Click and drag the link node. This curve will be maintained if you move either of the connected nodes.
  • To add a new node - Click on some empty space, and select the Add icon from the menu. A new node will appear. Click again to place the node where you want it, or optionally, click and drag to adjust the size of the new node. The edit field will automatically appear, allowing you to enter the text of the new node.
  • To add a new child node to an existing node - Click on a node, and select the Add icon from the menu. A new node with a new child link will appear. Click on some empty space to place the node where you want it, or optionally, click and drag to adjust the size of the new node. The edit field will automatically appear, allowing you to enter the text of the new node.
  • To add a new link from one node to another - Click on a node, and select the Add icon from the menu. Move the cursor over the other node that you want to link to. You should see the link change to a dashed associative link to the other node. Click to create the link to this node.
  • To edit the text of a node, link, or world - Click on the item, and select the Edit icon from the menu. The edit field will appear, allowing you to enter the text of the new node. Press enter, or "apply" to submit changes, or select something else to cancel.
  • To change the type of link - Click on the link node, and select the Link icon from the menu. This will toggle the type of the link between associative and hierarchical. You can use this method to reparent existing nodes.
  • To delete a node or link - Click on the node or link node, and select the Delete icon from the menu. (Currently there is no undo in the demo!)

I hate written instructions... Hopefully these are all much more intuitive in practice. The eventual introductory video should be worth a few thousand words.

Anyways, some screenshots of the demo in action!

Thursday, June 6, 2013

Computer ~ Thinker

As you may have seen on the Treehouse ads, not knowing how to code is the new illiteracy of our age.

I was watching some YouTube videos of Steve Jobs and the origins of personal computers and I came to a startling realization: computer applications with graphic user interfaces were one of the saddest things to happen to the computer. They made us computer illiterate. In as much as they made the computer accessible as a tool for solving specific problems, they removed us from the real power of the computer as a tool for solving any problem. In the beginning, when you first got a personal computer, the primary way that you used that tool was by programming it.

There's just one problem with computer programming: coding sucks.

Don't get me wrong. I love the raw creative power of code, and I can get totally absorbed in the process. But as I was learning how to bring my vision for Thinker into working reality, I couldn't help but think how genuinely stupid the whole process was. I firmly believe that that feeling is one of the most valuable assets that I could bring to the creation of this tool. I never want to forget it. I think one of the worst things a developer can do is get lost in the complex technical details of the code and forget how to think in simple intuitive ways. It's a constant challenge.

Code is already an abstraction. Binary code is abstracted to assembly language which is abstracted to a higher level language... so why do we stop there? Because it's typically too complex for a basic user to handle anyway. There are too many details to control. Visual editors tend to bog things down and are typically hideous.

But Thinker aims to harness the power of emergence. Extremely complex results can be achieved with very simple and intuitive building blocks. For example, take the world of Minecraft. The ability of users to intuitively and easily manipulate the basic building blocks of the world, leads to some of the most vast, complex, and intricate systems ever seen in a game...

 The Winter Palace - a Minecraft creation
Maybe in this way, Thinker can help restore some of the true power of the computer and help put that power into even more hands.

Computer - A tool used to compute. ~ Thinker - A tool used to think.

Wednesday, May 15, 2013

Link Nodes

The WebGL version is coming along. I've been working on link nodes and associative links. You can check out the latest demo at thinker.jit.su/demo .

Link nodes contain the link label (if there is one) and can be moved to adjust the curve of the link. Associative links (as opposed to hierarchical links) can connect any node to any other node and are represented with dashed lines.

Update: it seems there's some trouble with the host. If that links fails, please try again later.

Thursday, May 2, 2013

Refactor and Redesign

So I've been working on a major redesign and refactor of Thinker in order to apply the lessons I've learned thus far in the beta.

As for design, Thinker has a brighter look with a new logo. As I mentioned in a previous post, the new application interface is powered by WebGL. This is accomplished with the magnificent Three.js library (to which I am now a very, very small contributor :D ). And after producing a working proof of concept demo, I can now add 3D WebGL graphics to my list of skills.

You can view the new home page at thinker.jit.su and the demo of the WebGL interface here.

Behind the scenes, I'm coding in CoffeeScript, Jade, and Stylus, the minimal whitespace compiling versions of JavaScript, HTML, and CSS. They make developing way more fun, easy and powerful. As a precompiled language, CoffeeScript should be more difficult to debug, but I find that the simple syntax allows me to avoid more bugs in the first place. The natural closures, "classes", and scoping of CoffeeScript also helps me maintain better code. Nib for Stylus is also amazing. It makes resetting and implementing browser specific styles a breeze. And all these work great with Node.js on the backend

I'm still using MongoDB, but I'm rethinking it a bit. Storing child nodes as nested documents was an interesting idea, and I tried out Mongoose which has support for nested models; however, that approach doesn't allow for easy access or queries to child nodes. Then I read a great blog post about keeping it simple and flat. The new Thinker data paradigm also works well with this approach. It allows for things like only loading nodes as they become visible and performing queries and analysis on nodes in the database regardless of wether they are loaded in the interface.

I'm also working on the nifty Nodejitsu service instead of directly on Joyent.

Friday, April 19, 2013

Node Data Evolution

While working on Thinker I searched for a data syntax that could gracefully handle the kind of challenges that would Thinker would present. I wanted a human readable, minimal syntax that handled node-based data. These considerations were mostly for the sake of the developer (in this case me); though, I was also thinking of the user. If the user ever needed to export or convert Thinker data into text for backup or transport, I wanted it to be something they could understand and pick up easily.
In the beginning, Thinker data was based in XML. XML certainly satisfied the node-based requirement. You can stick many nodes of the same kind under one parent, and XML even has explicit metadata syntax for each node in the form of attributes. But XML, despite being human readable, is still a chore to work with manually. Markup really is best used for marking text and not complex data. And despite having explicit metadata, the metadata doesn't really have any structure. If you attempt to store structured metadata in an XML attribute (such as styles in HTML) the results are hardly readable.
Then Thinker used JSON. JSON was nice because it was easy to work with in Javascript, to stringify and transport objects. The data was easier to manually work with than XML; there were no lengthy closing tags to deal with. But JSON is not inherently node-based. You can make node structures in JSON: child nodes are just nested in an array, but nesting objects in an array gets very messy in JSON when you're stacking all those brackets, braces, and commas together.
Then I got into CoffeeScript. I've always liked the beauty of languages with whitespace syntax though I hardly use Ruby or Python. So I though I would just use CoffeeScript syntax to work with my data in the form of CSON if you will. (That's actually a thing) But despite the beautiful whitespace syntax of objects in CoffeeScript there's one glaring problem: you still need brackets for arrays. And putting indented objects into an array over multiple lines wasn't much better than JSON with node-based structures... So close, yet so far.
But then I had a brilliant idea! Why not just use colons without keys to represent indexed items in an array. Since "arrays" in Javascript are generally just objects (sparse hashes) anyway, colons without keys would just be shorthand for assigning indices. So I posted on a ticket on Github...
Alas, they get people complaining about the array syntax all the time, and they are probably tired of hearing about it, especially since there are alternatives like Coco and LiveScript. Though I actually agree with jashkenas that stars and hyphens are not the best solution to the problem. Though one problem my solution would be the risk of accidentally mixing keyed and unkeyed properties. Arrays with keyed properties work in runtime, but not in a precompiled language. It would have to be a compiler error.
So ultimately, I had no choice but to create my own data syntax, which really means I had to create my own parser. The reason I didn't just go with YAML at this point was that, 1) I don't actually prefer it's hyphen syntax, and 2) I thought I would go all the way and create a syntax that satisfied my node-based requirements as well. Also, YAML doesn't accept tabs in whitespace. Yes, I see that as a flaw, and I don't care who knows.
So to start, I just created a parser that parses objects like CoffeeScript (or actually like YAML with unquoted strings). Then I added the ability to convert objects with unkeyed properties to arrays. Since this data will be parsed at runtime, it allows for arrays with some keyed properties. Of course, those properties don't output to JSON, but they could be set in the result.
So this:
obj:
 foo: bar
 key: val

arr:
 : 2
 : -1
 :
  foo: bar
  zip: zap
 :
  : 1
  : 2
  : 3
Translates to this in JSON:
{
        "obj": {
                "foo": "bar",
                "key": "val"
        },
        "arr": [
                2,
                -1,
                {
                        "foo": "bar",
                        "zip": "zap"
                },
                [
                        1,
                        2,
                        3
                ]
        ]
}
Awesome! It's the most straightforward and simple hierarchical data syntax ever. But while I'm at it with a custom parser  I could go ahead and create an expanded syntax with support for node structures. So I added some extra key symbols for Thinker node data shorthand.
So this:
root node
 some node prop: 0
 position:
  x: 0
  y: 0
 - link
  link prop: 0
  > a child node
   more node props:
    :1
    :2
    :3
   -
    > grandchild node
 -
  > another child node
...is equivalent to:
_value: root node
some node prop: 0
position:
 x: 0
 y: 0
_links:
 :
  _label: link
  link prop: 0
  _target:
   _value: a child node
   more node props:
    :1
    :2
    :3
   _links:
    :
     _target:
      _value: grandchild node
 :
  _target:
   _value: another child node
...which in JSON looks like this :
{
        "_value": "root node",
        "some node prop": 0,
        "position": {
                "x": 0,
                "y": 0
        },
        "_links": [
                {
                        "_label": "link",
                        "link prop": 0,
                        "_target": {
                                "_value": "a child node",
                                "more node props": [
                                        1,
                                        2,
                                        3
                                ],
                                "_links": [
                                        {
                                                "_target": {
                                                        "_value": "grandchild node"
                                                }
                                        }
                                ]
                        }
                },
                {
                        "_target": {
                                "_value": "another child node"
                        }
                }
        ]
}
...which would be a real chore to work with manually. This node structure uses the new link paradigm. Note that the links themselves are a kind of node and can contain their own properties. The hyphens in this case don't just designate array items, but link nodes that are added to a links array. I also added "=" as shorthand for a meta link. Carets point to link "targets" which are actual nodes, which themselves can contain links to other nodes. I even added some support for node id's and references to serve as the basis for associative links in Thinker. Normal node properties use the same basic object structure from before.
This expanded node data syntax is obviously not quite as straightforward as the basic object structure, but it is much better than the alternative for node-based data. I'm not even going to share the parser code here because I know nothing about writing parsers, and it's probably the most clumsy, inefficient, fragile parser ever written. It just works... most of the time. So For now I'll just use it internally.

Edit: mixed up the terms compiler and parser...

Tuesday, April 9, 2013

Interface Improvements

The Thinker interface is currently all HTML with some SVG. The future Thinker interface will be WebGL. WebGL is entirely hardware accelerated which will vastly increase graphics performance. Since WebGL is just OpenGL for the browser, it should also make Thinker more portable to other platforms. And of course, it will also allow for cool things like 3D mind mapping and data visualizations. Panning and zooming around a world will be trivial (currently Thinker only has panning, unless you count browser zooming).


There is also another interesting aspect of moving to WebGL that will help improve the interface. I've noticed that the Beta testers like to think visually from the center out. Currently, Thinker places the origin and title of the world in the upper left corner with upper and left limits. Nodes can only extend down and to the right. This was a natural consequence of using an HTML paradigm to display the worlds. With the WebGL paradigm, the origin and title of the worlds will be centered and nodes will be free to extend outward in all directions (and dimensions). This will make it easier to rearrange node trees manually and automatically as they will have more space as they grow outward.

I might even be able to recreate the Metaphysical Index entirely in Thinker...

Thursday, April 4, 2013

Protometa

Protometa - my username on Github and the beta invite code for Thinker. It's short for prototype metadata, the virtual metadata nodes that stores default values that are otherwise undefined. If a node does not have a certain property defined in it's metadata nodes, it would inherent this default prototype metadata. Whenever a property of a node is initially set, a metadata child node is added that overwrites the protometa.

Metadata nodes within metadata nodes...

Why would you want the properties of nodes to be stored as nodes within nodes? Ideally, this fractal, recursive structure makes nodes more editable and extensible.

Metadata can as complex as any other data, and since Thinker nodes are meant to be a way to navigate and edit such data, it only makes sense to use such nodes to explore the metadata as well. In this way, nested node metadata allows for manual editing of properties. E.g. you can edit the radius of a node by dragging the edge and resizing it, or you can open the radius metadata and set it to some specific value.

Also, it potentially allows for the use of data to drive the appearance of nodes, which would be a way to create custom data visualization. E.g. the radius of a node could be driven by a value which would allow you visualize it relative to others. Creating formulas to drive values is itself done with metadata nodes. It's sort of like visual scripting.

Working out formula/function syntax in nodes

But it has some major downsides. It overcomplicates many things that would otherwise be very simple, and the nested metadata nodes are difficult to query and update in the database.

In considering the new linked data structure for Thinker, specifically the idea of link node metadata, I had a happy realization. Nested metadata nodes should not be created by default every time a property is adjusted. According to the new paradigm, metadata links could be an optional addition to allow for plugging node values into node properties. This would let nodes store their own properties in a compact fashion by default while still allowing for advanced functionality such as manual override of properties, custom data visualization, and function nodes.

Furthermore, adding these metadata links could simply be a matter of adding a child node and changing the type of link that connects it. So there would be normal links with any arbitrary labels and meta links with special keyword labels that could alter various properties or provide other advanced functionality based on the values to which they linked.

Bottom line: things will be much simpler for the developer and the user without sacrificing any potential functionality.




Tuesday, April 2, 2013

App vs Web

In my first post, I touched on the topic of monetization and the struggle to display contextual ads in a web app. (Since then I've discovered Google Interactive Media Ads and Google In-Game Advertising. Unfortunately the former seems to be specifically for video and the latter is specifically for Flash games...)

I thought it might be good to review my thoughts on the web vs app issue. Thinker is currently being developed on the web.

Thinker would make a great app. It's probably easier to develop as an app with existing libraries, SDK's, and standards. I might be easier to monetize as an app. Thinker is designed around a touch screen interface paradigm which would naturally work well as an app on a tablet device. There are some aspects of advanced web technology and standards that almost make it somewhat browser specific, so the cross-platform advantages of the web are more limited.

Despite these points in favor of apps, Thinker is on the web for now. One big advantage of the web is it's inherent interconnectivity. A web app can easily link and connect to any other content on the web. I want Thinker to have that kind of interconnectivity. Also, the web is a good place to start. When you want something that goes everywhere you can always start with the web and them make optimized apps and platform specific versions later.

Friday, March 29, 2013

Cybernetics

Lately, I've been reading The Web of Life by Fritjof Capra. It's got me thinking about interconnectivity and cybernetics...

Metabolic enzyme pathways showing biological feedback loops

Cybernetics involves the study of systems with feedback loops. These looping systems can be simple or very complex, and they apply to a wide variety of topics including ecology, homeostasis, neural processing, cognition, self-organization, economics, and much more.

As a consequence, I've come to the conclusion that Thinker is currently flawed. The node data structure of Thinker is too fixed on strictly hierarchical structures. Thinker does not handle complex nonhierarchical looping networks of nodes as well as it could. Nonhierarchical links do exist in Thinker, but their implementation is limited, and their structure is awkward. Consequently, I am working on some major upgrades to Thinker with this new paradigm in mind.

Working out some link structures...
There's will be no strict attempt to avoid hierarchies, just expand beyond them. Nodes may still be arranged hierarchically by default for practical data storage reasons, but the ability to link to any other data node in the system will also be ingrained in the data format. It will be just as easy to create a flat interconnected associative web as a deep hierarchical tree.

The new data format will also have the added benefit of separating the label and value fields of nodes and hopefully clearing up some of the confusion, awkwardness, and ambiguity of two fields in each node. The new paradigm will have only one value field in a node. This will make it clear to the user where they should enter text instead of immediately presenting them with a choice.

When new nodes are added as children or when an associative link is created, the link connecting the nodes will automatically contain another node. This node will initially be visually inconspicuous and will most readily be used as a spline handle for adjusting the curve of the link (an added bonus feature which Thinker doesn't not currently have). Menu options on this link node will allow the user to edit the link and add a text label, thus replacing the old label field. Since associative links will also follow this structure as well, the user will be able to apply labels to them (something one can't currently do in Thinker either).



So there will be standard nodes with values connected by link nodes with labels that describe the relationships between the values. This will make informal data and mind mapping much more intuitive and straightforward while also easily allowing for more formal structure and definitions when you need it.



Sunday, March 17, 2013

The Vision

I have a dream. I dream of a world were all data is visual, interactive and easily editable.

Data should be visual. A good infographic is a beautiful piece of work, a true marriage of the atheistic and the practical. When data is visual, it comes to life, it means something; we can begin to comprehend it and draw conclusions from it.

Data should be interactive. Your lists should be sortable. Your notes should be searchable. Your dry erase board should allow for drag-and-drop reorganization and never run out of room. Your infographics should let you focus on different aspects and explore various details of the bigger picture.

Data should be easily editable. Infographics should not just be a rendering of some data, they should be the interface of the data, and that interface should be as simple and easy to grasp as the infographic itself. Data should not just be visual at an end point, but it should be visual form the very beginning, from the point of entry to the final presentation.

There are many tools out there for mind mapping, but none so far that I know live up to my atheistic or technical standards. There are many tools for creating data visualizations, but none that I know that serve as a visual interface to data. They often have complex API's and require an abundance of technical knowledge. These kinds of technical tools certainly have there place, but I want a tool to create and edit beautiful interactive visual data and ideas that is accessible to everyone.

That is the vision of Thinker.

Existing dataviz / infographic tools

Existing mind mapping tools

Monday, March 11, 2013

Hello World

Welcome to the Thinker Development Blog!


As you may have noticed (or more likely not noticed), Thinker development has been on hold for a bit as I have recently been relocating to Portland, Oregon. Why Portland? Well honestly, because I thought it sounded like a cool place to live. Little did I know that Portland is actually a big hub for web and user interface design, and one of the most entrepreneur friendly cities in America. So the prospects are very exciting.

I'm starting this blog for several reasons. Firstly, people need a good way to learn more about Thinker. The information on the beta has been very sparse and not very engaging thus far. The facebook page doesn't suffice, and some of the beta testers aren't even on facebook. I need to make more connections with more people and broaden the social marketing base. Thinker is still somewhat obscure to many of the testers, so hopefully this blog can help fix that. I'm also constantly thinking about new ideas for features and direction, so this will be the place to document all that.

Secondly, on the dev side, I need Google AdSense approval. In theory, Thinker could use AdSense to serve contextual ads based on whatever you're thinking about. This is a concept that I would really like to begin testing. Unfortunately, it's notoriously difficult to get AdSense approval for some web apps because they don't always serve traditional web content. I've modified Thinker so that it serves the content of a world directly without any scripts. Nevertheless, I've been repeatedly turned down for "insufficient content". Google offers some great resources for web app monetization. Thinker currently uses the great in-app payments system via Google Wallet to allow for tipping. Sadly, they seem to be lacking the same kind of contextual ad solutions that they use in their own web apps (e.g. Gmail). If anyone out there knows of any alternatives or solutions to this problem, please let me know.


Anyway, the workaround is that once you have AdSense approval for one site, you're able to put it on other sites or apps with very little hassle. The easiest kind of site to get approved on is a blog. So here we go...