Kiichigo

Rich Internet and Agent Oriented Consulting with Raspberry Flavor

Route Framework: Routes

without comments

Summary

Before we start, I want to point out, that this article covers low-level API of Route Framework. In most case you don’t want to worry about low-level, unless you building your own framework on top or with Route Framework

Center of Route Framework are IRoute and it’s implementor Route hence the name of the framework. Route sort of inspired by Agent Oriented1 approach minus concurrency and proactivity and EventHandlers from Mate Framework2. Generally it consists of three types of instances: ISensor, IPattern and IAction.
Simply put:

  • Sensor get’s messages from Environment, which uses some way to send and receive messages, whether it’s flash.events.Event or some custom solution.
  • After sensor received message, it parses it if needed and passes it’s to IRoute.perceive( percept:Object ); method. In future we’ll call “sensed” message – percept.
  • IRoute will match percept against IPattern
  • If successful Route will then execute it’s IAction

.
This allows IRoute to be very agile Inversion of Control3 container. Each part of a framwork is simple enough system that can be easily modified.

Percept

Plainly speaking percept can be anything: Object, String, Event or any kind of instance. Whatever Sensor retrieves from Application and passes to Route considered to be Percept. Percept will then be matched against Patterns and passed along to Actions assigned to current Route.

Sensor

In lamen terms Sensor is an Event Listener or an instance of Observer. It simply receives messages from Application/Environment. Of course Sensors can be internal too. For example there could be a Sensor that listens to internal messages of other Routes, but that’s more rare case.

Pattern

Plainly put, Patterns used by Route to see if Actions will be executed. For example Handle Route:

route( Handle, { event: SampleEvent.BIND_PLEASE, generator: SampleEvent } ).
<route:Handle event="{SampleEvent.BIND_PLEASE}" generator="{SampleEvent}"/>

Uses two patterns, to filter by Event.type and actual Class of Event.

Actions

Actions are variation on Command Design Pattern5. Predefined actions in package eu.kiichigo.route.actions cover basic Application manipulation such as: Apply/Bind/Copy data, run closure or method on class, invoke RPC operation and such. You can extend Action, AsyncAction or Actions classes in order to create custom functionality.

There is two major things you can do with actions: assign predicates and group actions

Conclusion

This covers basic logic of Route, once again, this is low-level API which most programmers should not concern themselves with.

Footnotes

[1] PDF: Shoham, “Agent-oriented Programming”.
[2] Mate Framework.
[3] Martin Fowler about IoC.
[4] Command Pattern at Wikipedia.

Written by nirth

February 15th, 2011 at 1:58 pm

Route Framework: Guards and Execution Control

without comments

Most instances of IAction also implement IGuarded interface, that allows programmer to control when certain actions will be executed. It acts a lot like guards from declarative languages, such as Prolog, Erlang or Scala. Essentially speaking: if IGuard.when evaluates into true IAction will be executed successfully, otherwise it won’t.

Predicate for guard ( value of IGuard.when ) can be in a form of: Boolean, function ():Boolean or function ( percept:Object ):Boolean. Here is small example with fluent dsl:

var router:IRouter = new Router().
	route( Handle, { event: LoginEvent.LOGIN } ).
		run( Run, { closure: Alert.show, arguments: ["Logging in "] } ).
			when( check ).
end;

protected function check( percept:LoginEvent ):Boolean
{
	if( percept.username == null || percept.username.length == 0 ||
	    percept.password == null || percept.password.length == 0 )
		return false;
	return true;
}

Action Run will be executed only if incoming LoginEvent has defined username and password. Of course, you will prefer sophisticated validation than simple length check.

Following example shows how to use multiple IGuarded.when predicates with some Functional Programming mojo:

var router:IRouter = new Router().
	route( Handle, { event: LoginEvent.LOGIN } ).
		run( Run, { closure: Alert.show, arguments: ["Logging in "] } ).
			when( check( "username" ) ).
			when( check( "password" ) ).
end;

/**
 * Checks if <code>String</code> that's evaluated via <code>percept[property]</code> is not empty and is not <code>null</code>.
 *
 * @param	property	<code>String</code> name of property on <code>percept</code> argument.
 * @param	percept		<code>percept</code> received by <code>IRoute</code> for testing.
 *
 * @returns	<code>Boolean</code>. <code>true</code> if string is not <code>null</code> and contains at least 1 symbol, <code>false</code>otherwise</code>.
 */
protected function checkString( property:String, percept:LoginEvent ):Boolean
{
	var string:String = percept[property];
	if( string == null || string.length == 0 )
		return false;
	return true;
}

/**
 * Higher order function. Simplistic Curry function.
 */
protected function check( property:String ):Function
{
	return function( percept:LoginEvent ):Boolean
	{
		return checkString( property, percept );
	}
}

I’ve used Higher Order Function, to construct actual predicates. If you have some experience working with Functional Programming, you will find this methods more elegant and logical.

MXML syntax also allows us to use Data Bindings in this example:

<route:Router id="router">
	<route:Handle event="{ LoginEvent.LOGIN }">
		<route:Run closure="{ Alert.show }" arguments="{ ['Logging in'] }"
			   when="{ router.percept.username != null && router.percept.username.length > 0 &&
					   router.percept.password != null && router.percept.password.length > 0 }" />
	</route:Handle>
</route:Router>

No additional functions are requited.

This is rather simple, yet very powerful mechanism of controlling execution cycle of application, without need to create special actions that will check data before execution that can be achieved by simple injection of a guard.

Example and Sources

Futher Reading

About Guards on Wikipedia.

Written by nirth

February 13th, 2011 at 6:05 pm

Route Framework: Sensors and Routing

without comments

In Model View Controller or Delegate Model architectures special place is reserved to messaging system. When it comes to ActionScript, we usually utilise one of three solutions:
flash.events.Event/flash.events.IEventDispatcher.
custom Observer implementation.
AS3 Signals by Robert Penner.

Usually Application Framework comes tightly coupled with some or another messaging library. It might work in many cases, but sometimes it might be a serious bottleneck*. Route Framework can switch messaging systems easily by subclassing just 2 classes: Sensor, that will receive messages, and Route to wrap sensor and pattern in it.

Let’s consider following example with custom Observer Implementation:
IMessage.as

package observer
{
	public interface IMessage
	{
		/**
		 * IMessage name, can be used for additional filtering.
		 */
		function get name():String;
		/**
		 * @private
		 */
		function set name( value:String ):void;

		/**
		 * Any data that can be sent with IMessage
		 */
		function get data():Object;
		/**
		 * @private
		 */
		function set data( value:Object ):void;
	}
}

IObserver.as

package observer
{
	public interface IObserver
	{
		/**
		 * Invoked automatically by instance of IObservable. Should contain any update logic.
		 *
		 * @param message		IMessage sent by IObservable
		 */
		function update( message:IMessage ):void;
	}
}

IObservable.as

package observer
{
	public interface IObservable
	{
		/**
		 * Adds an instance of IObserver to notify queue.
		 *
		 * @param observer		IObserver to be added.
		 */
		function add( observer:IObserver ):void;

		/**
		 * Use this methods, to notify all instances of IObserver added to current IObservable.
		 *
		 * @param message		IMessage to be sent.
		 */
		function notify( message:IMessage ):void;
	}
}

You can check actual implementation of this interfaces in sources, but implementation does not really matter in this case.

In order to teach Route to accept Messages all we need is to subclass Sensor and Route as follows:

package observer
{
	import eu.kiichigo.route.pattern.*;
	import eu.kiichigo.route.pattern.match.type;
	import eu.kiichigo.route.routes.*;

	/**
	 * Version of IRoute to work with custom Observer pattern implementation.
	 * Fluent style:
	 * 
	 * route( Receive, { from: "idOfObserver" } );
	 * 
	 * MXML Syntax:
	 * 
	 * 
	 * 
	 *
	 * @author David "nirth" Sergey
	 *
	 */
	public class Receive extends Route implements IRoute
	{
		public function Receive()
		{
			super();

			// Setup pattern to filter out messages of correct type.
			var p:IPattern = new Pattern;
				p.matcher = type;
				p.store( "type", IMessage );
			// Inject pattern.
			pattern = p;
			// Inject Sensor.
			sensor = new ObserverSensor;
		}

		// Receive.from is simple proxy get-set accesor
		/**
		 * @copy		ObserverSensor#from
		 */
		public function get from():Object
		{
			return ( sensor as ObserverSensor ).from;
		}
		/**
		 * @private
		 */
		public function set from( value:Object ):void
		{
			( sensor as ObserverSensor ).from = value;
		}
	}
}
import eu.kiichigo.route.sensors.Sensor;

import observer.IMessage;
import observer.IObserver;
import observer.Messenger;

class ObserverSensor extends Sensor implements IObserver
{
	/**
	 * @copy		observer.IObserver#update
	 */
	public function update( message:IMessage ):void
	{
		send( message );
	}

	/**
	 * @private
	 */
	protected var _from:Object;

	/**
	 * Indicates an instance of IObservable that this ISensor is listening too.
	 */
	public function get from():Object
	{
		return _from;
	}
	/**
	 * @private
	 */
	public function set from( value:Object ):void
	{
		//ToDo: Handle removal from old Messenger here.
		_from = value;
		Messenger.get( value ).add( this );
	}
}

Now our class has nice readable class name and accessor name, and it’s actually reads as: “Receive from accessorId” as in example:

const router:IRouter = new Router().
	route( Receive, { from: "leftButtons" } ).
		action( Run, { closure: Alert.show, arguments: ["Received message from leftButtons"] } ).
	route( Receive, { from: "rightButtons" } ).
		action( Run, { closure: Alert.show, arguments: ["Received message from rightButtons"] } ).
end;

Alternatively you can use MXML Syntax too:

<route:Router>
	<observer:Receive from="leftButtons">
		<route:Run closure="{ Alert.show }" arguments="{ ['Received message from leftButtons'] }" />
	</observer:Receive>
	<observer:Receive from="rightButtons">
		<route:Run closure="{ Alert.show }" arguments="{ ['Received message from rightButtons'] }" />
	</observer:Receive>
</route:Router>

Example and Sources

* Another framework that handles decoupling of messaging from mvc logic very nicely is Parsley framework.

Written by nirth

February 9th, 2011 at 8:43 pm

Route Framework: Interfacing

without comments

[ToDo: add link to Route Framework introduction]
[ToDo: add link to overview of the Route]

There is 3 basic ways of working with Route Framework: ActionSctipt, ActionScript-Fluent and MXML.
ActionScript: Allows you to work with Route Framework on a low level. It should be used in case you are interested in generating FrontControllers in Runtime from Configuration files or Data Base settings.
Fluent: This is also a way of defining Routers in ActionScript, but much less verbose, and easier to read and define. em>You can read more about fluent programming on Martin Fowler’s Bliki.
MXML: This style allows programmer to define Routers in MXML.

Let’s get some abstract but nevertheless good example: We’ll create two TextAreas original and copy and link their values via Model which we call LabModel. Overral data flow can be represented as:
original.text → labModel.text → copy.text

ActionScript: Low Level

// Create a pattern that will match input to flash.events.Event:
var eventPattern:IPattern = new Pattern;
	eventPattern.matcher = eu.kiichigo.route.pattern.match.type;
	eventPattern.store( "type", flash.events.Event );

// Create Pattern that will match "bindPlease" string.
var bindPleasePattern:IPattern = new Pattern;
	bindPleasePattern.matcher = eu.kiichigo.route.pattern.match.values;
	bindPleasePattern.store( "type", "bindPlease" );

// This action will bind view to model
var view2model:Bind = new Bind;
	view2model.from = original;
	view2model.to = LabManager;
	view2model.text = "text";

// And this will bind model to view.
var model2view:Bind = new Bind;
	model2view.from = LabManager;
	model2view.to = copy;
	model2view.text = "text";

// Create Route that will be catching "bindPlease" events:
var routeBindPlease:IRoute = new Route;
	routeBindPlease.pattern = new Patterns( eventPattern, bindPleasePattern );
	routeBindPlease.add( view2model );
	routeBindPlease.add( model2view );
	routeBindPlease.sensor = Events;

var router:eu.kiichigo.route.kore.IRouter = new eu.kiichigo.route.kore.Router;
	router.add( routeBindPlease );

Here is what happens:

  • We define two patterns:
    • First will match incoming percepts and filter by Class: percept is flash.events.Event
    • Second pattern checks value: percept.type = "bindPlease"
  • We then create two instances of Bind actions and set them up.
  • We create instance of Route and inject Patterns, Actions and Events-Sensor.
  • We add Route to Router.

    Fluent and MXML

    Following two examples show how same logic can be defined in Fluent and MXML DSLs:

    var router:IRouter = new Router().
    	route( Handle, { event: "bindPlease" } ).
    		action( Bind, { from: original, to: LabManager, text: "text" } ).
    		action( Bind, { from: LabManager, to: copy, text: "text" } ).
    end;
    <route:Router>
    	<route:Handle event="{ 'bindPlease' }">
    		<route:Bind from="{ original }" to="{ LabManager }" text="text" />
    		<route:Bind from="{ LabManager }" to="{ copy }" text="text" />
    	</route:Handle>
    </route:Router>

    I want to stress attention on Handle. Handle is one of the pre-defined types of Route that handles percepts of flash.events.Event. There is other Route types available:
    ValueObject: Will perceive and process data from RPC services.
    Inject: Will perceive and process created by Router instances, or added DisplayObjects to DisplayList.
    Programmer can also create own Routes and Sensors to work with other ways of messaging, such as custom implementation of Observer or Delegating Event Model design patterns.

    Example and Sources

  • Written by nirth

    February 9th, 2011 at 1:44 pm

    Consulting and Documents

    without comments

    While I write it from consultant perspective, I guess it’s quite good practice for any semi-executive position in research and development department in software company. The idea is – your client have to know what you doing. That’s good ethics and actually quite useful for self management.

    General Rules

    Company might use internal jabber service or even some exotic IM protocol, voip, bug tracker or any other means of talking to each other. That’s all good, and consultant should use them. But never forget about good old E-Mail. Try to send anything important to your-self for future reference. And copy status updates and white papers to the clients mail box.

    There is multiple reasons for that, one of them, starting from: you might have dozen of clients, and everybody use different protocol, it’s nice to know that you won’t accidentally forget to send somebody a note or update.

    Status Updates

    Make this regular, I would not recommend sending them more than once a day. But daily is good. If you lazy you can try bi-daily or weekly, consider weekly status updates to be an absolute limit. Daily is actually not that bad, and will take only 5-10 minutes or your (paid by a client) time.

    Always [blind] carbon copy yourself (cc/bcc), and it’s nice to have an imap mail server, where you can have different folders per status updates for each client. If you are not a modest type like me – you might consider compiling huge update in a PDF from all those small emails you were writing for weeks or months to a client – to remind him of enormous work you’ve done wink.

    White Papers

    It’s nice to write a white paper for libraries, frameworks and utilities you develop. While documentation in code will be most likely seen and understood only by programmers in your current department. Whitepapers should be a good reference point for people from any other department: UI, GUI, Back-end, Front-End, QA and such. If you are involved in Rich Internet Application / Web 2.0 development it’s really useful to supply Web Designers, UI, GUI and Web Security people with some reference on code, so that they know what to expect.

    If a library or framework you’ve developed is particularly huge (150 or more classes for Flex Project for example) – it’s nice to provide your fellow developers with some kind of reference on Facade points of your library too, while they can get documentation, it’s not always clear where to start reading documentation.

    And don’t forget to include whitepaper writing to the status updates wink.

    Client Specific

    As I stated before – each company might have some specific ways of communication. While some of them are exotic and hard to guess. JIRA, Redmine, Mantis, Confluence, SIP and BaseCamp. While it’s quite useless to guess what client’s company might use – it’s nice to install bunch of different IMs from old ICQ to new Skype and open source Jabber, and learn some wikisyntax. Also If you are going to work for scientific/research companies and there is lot’s of interesting job in that sector – LaTEX is quite useful.

    Written by nirth

    December 26th, 2010 at 12:16 pm

    Posted in Consulting

    DIY QA or What to do when QA Engineer left company

    without comments

    That’s not professional QA technic, but in my experience it’s a best one for team that does not have dedicated QA engineer for some reason.

    If you working in young Start Up company, or huge company in pre-Christmas season, you might experience lack of QA engineers. Personally I consider QA-people to be second most important engineers in Software Development. While programmers can find critical bugs and develop software on their on. It’s quite hard to find all those small glitches, and small bugs. But it’s very easy to miss them, and build rather smelly foundations.

    Usually this bugs are quite easy to fix, but occasionally you can accidentally base important bits of architecture on buggy library. So, I want to share a simple QA technic that can be exploited in almost any company/group. I will use Twitter and WordPress as a simple enough examples.

    I want to make a point here: all this sounds very-very easy. But you should not rely on your memory. Tests should be done step by step, and it’s good to have a actual document, and not just oral contract with other people.

    Brainstorm use-cases

    Get all possible use-cases that matter at this point. It might be good idea to write use-cases that does not matter too, for future. Use cases can be devided by “start position” In case of twitter we might have 3 start position:

    • Full Stop: Logout, Quit Browser, Clear Cache and open Twitter site
    • Main: Simply go to main page, without relogging.
    • Refresh: Simply refresh current page.
    • Continue: Just continue from any position.

    It’s important to note, that some operations might and have to work only once per session (like popups, announcements, settings storing and such), while other features should work from any point.

    Outline each use-case

    Each use case should be outlined, with every action that user should do. Then list expected behaviour under each action, in case of a WordPress blog commenting it might look like this:

    • [Full Stop]
    • Open main page – http://kiichigo.eu
      • Page loads
      • Posts rendered, and sorted by date.
      • Sidebar displayed.
    • Click on any post title.
      • Individual Post loaded.
      • Comment text-field is available
    • Write some text.
      • Spell check is engaged.
      • Post button becomes active
    • Post Comment
      • …and so on.

    Yes it looks excessive, but it’s not. Trust me if you are in Agile or Game Development environment, and this days it seems like it’s either one or the other – you will be testing same application and same use cases over and over again. If R’n'D is fast – even multiple times a day. Unless you some kind of Savant – you will most probably forget small details here and there.

    Print it

    My last advice – is to print it, many copies of it actually, and then tick off each step as you go. That’s faster than command-tab/alt-tab every time you want to check next step, and easier to compare.

    Conclusion

    In my experience, QA is responsible for Deadlines. Good team of programmers can write code pretty fast. But QA can specify functional (requested by client) and non-funcitonal (security and such) features that should be implemented. If QA is unavailable it’s nice to know that software will be stable anyways.

    Written by nirth

    December 26th, 2010 at 11:34 am

    λ-Calculus

    with 4 comments

    I decided that’s it time to learn λ-calculus. I started it as writing simple Scheme REPL which could evaluate simple expressions as:

    var code:Array =
    ["+", ["*", 1, 2, 3], ["-", 4, 2]];
    
    var result:Number = new Scheme().read( code );
    trace( result ); // 8

    And that worked sort of fine, but I needed system to do something more complex. To be honest I never actually new mechanics of λ-calculus intimately, so, I decided to learn it. I found some papers[1][2][3] and started to code:

    // Identity x.x
    var identity:Function = function( x:* ):* { return x; };
    
    // Succ nfx.f ( n f x )
    var succ:Function = function( n:* ):* { return function( f:* ):* { return function( x:* ):* {
    	return f( n( f )( x ) ); } } };
    
    // Plus mnfx.m f (n f x)
    var plus:Function = function( m:* ):* { return function( n:* ):* { return function( f:* ):* { return function( x:* ):* {
    	return m( f )( n( f )( x ) ) } } } };
    
    // Church-Booleans, since true and false are reserved yes and no used instead. wink prolog
    var yes:Function = function( x:* ):* { return function( y:* ):* { return x; }; };
    var no:Function = function( x:* ):* { return function( y:* ):* { return y; }; };
    
    // Numbers
    var zero:Function = no; //Zero is alpha equivalent to false (no).
    var one:Function   = succ( zero );
    var two:Function   = succ( one );
    var three:Function = succ( two );
    var four:Function  = plus( two )( two );
    var five:Function  = plus( three )( two );
    trace( [one, two, three, four, five].map( function( functor:Function, index:int, array:Array ):int {
    	return ( functor( function( n:* ):* { return n + 1} )( 0 ) );
    } ) ); // 1, 2, 3, 4, 5

    Project lacks abstraction at this point, I’ll have to work on that, and learn some stuff about lexical parsing and tokenization before I can actually handle writing Scheme REPL.

    [1]http://www.inf.fu-berlin.de/lehre/WS03/alpi/lambda.pdf
    [2]http://www.cs.bham.ac.uk/~axj/pub/papers/lambda-calculus.pdf
    [3]To Dissect a Mockingbird: A Graphical Notation for the Lambda Calculus with Animated Reduction

    Written by nirth

    December 24th, 2010 at 12:10 pm

    Functional approach to working with Arrays in ActionScript

    without comments

    Actually I’ll be working with Vector but since I’m passing theoretical knowledge – that won’t be a problem.
    Say we want to play my favorite game: Fizz-Buzz[1], first I’ll create two helper methods that will do most list creation and number checking, to remove details from our way:

    /**
     * Utility factory method, creates simple ranges of numbers.
     * @param from	Initial number.
     * @param to	Target number
     * @return 		Vector. of number in range from and to.
     */
    protected function range(from:int, to:int):Vector.
    {
    	var result:Vector. = new Vector.;
    	var current:int = from;
    
    	while(current != to)
    		if(from < to)
    			result.push(current++);
    		else
    			result.push(current--);
    
    	result.fixed = true;
    	return result;
    }
    /**
     * Simple helper method, emulates "Fizz-Buzz" game, returns "Fizz" if number dividable by 3, "Buzz" if by 5, and "Fizz-Buzz" if by both.
     * @param number	Number to check.
     * @return 			"Fizz" if number is dividable by 3, "Buzz" if by 5, and "Fizz-Buzz" if by both.
     */
    		protected function fizzBuzz(number:int):String
    		{
    			if(number % 3 == 0 && number % 5 == 0)
    				return "Fizz-Buzz";
    			else if(number % 3 == 0)
    				return "Fizz";
    			else if(number % 5 == 0)
    				return "Buzz";
    			else
    				return "";
    		}

    First method as you already guessed simply creates ranges of number, while second checks individual number on it's fizz-buzz-ines. Structural approach would be to create a loop:

    protected function structural():void
    {
    	for each(var number:int in range(1, 101))
    		trace(fizzBuzz(number));
    }

    No surprise here I guess, using for instead of for each could be smarter but I was going for shortness here. But there is a functional approach too:

    protected function test():void
    {
    	range(1, 101).forEach(loop);
    }
    /**
     * Used as a callback in Array.forEach or Vector.forEach methods.
     * @param element	Current element.
     * @param index		Current index.
     * @param vec		Reference to the Vector.
     */
    protected function loog(element:int, index:int, vec:Vector.):void
    {
    	trace("[" + index + "] " + fizzBuzz(element));
    }

    This approach does not look short*, but it gives us some flexibility because we've just reached new level of abstraction and went beyond Object Oriented. Here is better example:

    /**
     * Higher order function that creates a loop closure.
     * @param output	Reference to the desired output method, such as "trace".
     * @return 			Function with selected output method.
     *
     */
    protected function looper(output:Function):Function
    {
    	return function(element:int, index:int, vec:Vector.):void
    	{
    		output("[" + index + "] " + fizzBuzz(element));
    	}
    }

    Method looper is a Higher Order Function (hof) instead of doing anything - it creates and returns another function, we also pass closure/function as argument, this gives us ability to change way we want to output information, we can easily switch between trace, ILogger.log or any custom debug method myDebugger.debug, and we can do it fluently:

    range(1, 101).forEach(looper(trace)); //using trace()
    range(1, 101).forEach(looper(myLogger.log)); //using Flex Logger
    range(1, 101).forEach(looper(console)); //my custom debug method that traces items to Firebug Console

    No ActionScript IDE support functional approach to programming, so I wouldn't recommend heavy use of fp, but there is places where FP (Functional Programming) can be very helpful, such as Game AIs, which might need to easily discard unworking tactics and try new ones, without storing whole classes/modules of tactics and plans in memory. I also found that it's quite usable to use FP in small utility and helper functions, just make sure that your team understands what it is.

    * At least it does not look that short in ActionScript, but you might be surprised by it's elegance in languages like Ruby, Scala, Erlang and Haskell.

    [1] Coding Horror: FizzBuzz

    Written by nirth

    October 28th, 2010 at 5:13 pm

    Learning Erlang: Minimalistic Agent Oriented Library

    without comments

    So, I was experimenting with Erlang this week for some more, and decided to start writing simplistic agent oriented[1] library for Erlang. My guess is that Erlang should do just fine, the only concern is – I have no idea how to implement logical reasoning right now, but that’s fixable with research.

    Right now it’s not much of a framework, but a draft/template. Don’t get your hopes up just yet: kiichigo-communique@github

    4> mas:start(main_environment).
    true
    5> main_environment ! {create, agent_smith}.
    {create,agent_smith}
    6> main_environment ! {create, neo}.
    {create,neo}
    7> agent:talk(neo, agent_smith, "Boo Hoo").

    [1] Agent Oriented,Semantic Oriented Agent based Approach towards Engineering Data Management, Web Information Retrieval and User System Communication Problems

    Written by nirth

    September 29th, 2010 at 11:51 pm

    Logical predicates in Declarative MVC

    without comments

    Not long ago, I’ve started to develop Mate-like Event-Driven MVC+S framework. At the same time I was improving my AI skills with Scala, AgentSpeak(L) and Agent0. While I was developing FrontController I noticed that it’s has a lot in common with Agent – it has events, and events have to be handled[1], while it misses Guards[2] and mailbox[3], it still have a lot in common with Agents.

    Main difference between FrontController and Agent as I see it is Usage: Agent is an entity in some network, while FrontController is a bottle-neck in Application. What I wonder is – if I can meet this two concept, and look at application as a Neural Network. It might “learn” to adapt to concrete user ( via Cookies or Shared Objects ), or some user demographic ( via Server ).

    So, that’s how your normal “mate-like” handling might look like:

    
    	
    		
    			ButtonStyles.swf
    			FolioStyles.swf
    			TextStyles.swf
    		
    		
    			
    				
    			
    			
    				
    			
    		
    	
    

    Handling with Guards might look more like if/else or case clauses:

    
    	
    		
    			
    				
    				DebugModule.swf
    			
    	
    	...
    

    You can have as many Guards per handler as you want.

    Next step is to think about and implement FrontController to FrontController communication protocol to make them look more like AI-Agents. ^_^

    That’s just an early idea, but it looks prommising. You can check pre-alpha source code at my git-hub: nirth@github.

    [1] Granted, agent usually have more event types than a FrontController, events represented by Fact and a status ( +some( fact ), -some( fact ), +-some( fact ): fact added, fact deleted, fact updated ).
    [2]Wiki:Guard.
    [3]Wiki:Mailbox.

    Written by nirth

    June 18th, 2010 at 11:10 am