Multi-return and multi-assignment in TIScript.

October 31, 2009

Filed under: Sciter, Script, Web Application Techologies — Andrew @ 11:42 pm

As we know parameters of functions are passed by value in languages like TIScript and JavaScript. Inside the function we can modify paramaters and their new values will not be seen outside the function.

Let’s say we need to implement function expand(rect, dx, dy) : rect that should increase dimensions of the rectangle.

If the rect is an object then we will write something like this:

function expand(rect, dx, dy)
{
   return {
     x: rect.x - dx,
     y: rect.y - dy,
     w: rect.w + 2*dx,
     h: rect.h + 2*dy };
}

Problem with this implementation: it allocates brand new object on each call. That is not desirable if the function is used frequently.

If TIScript would support pass-by-reference for parameters then this function will have signature like this: inset(&x, &y, &w, &h, dx, dy) but no such thing as pass-by-reference in JS and TIScript for many good reasons.

As a solution: in TIScript we can use so called multi-return and multi-assignment feature – function is allowed to return multiple values.

Using this feature we can rewrite our function as:

function expand( x, y, w, h , dx, dy)
{
   return ( rect.x - dx, rect.y - dy, rect.w + 2*dx, rect.h + 2*dy );
          // returns "list" or tuple if you wish of four values.
}

To call such function and to get multiple values from it we will use list of values as an l-value expression:

var x = 10, y = 10, w = 100, h = 100;
(x,y,w,h) = expand(x,y,w,h, 20, 20 );

Parameters and return values are passed using stack of the VM so this will not create additional payload for the heap manager.

And yet it is pretty convenient for other cases too. For example this:

var a = 10, b = 5;
(a,b) = (b,a);

is how you can swap values of two variables.

Small feature but quite usefull.

Main challenge was to plug value lists into existing syntax of JavaScript. Implementation is quite simple.

Stringizer functions in TIScript

October 24, 2009

Filed under: Sciter, Script — Andrew @ 4:28 pm

Motivation.

Tasks of defining string expressions and textual fragments in script code are pretty common.

Typical example in JS/browser is:

someelement.innerHTML = 
"<span style=\"color:#ffffff\">" + somestuff + "</span>";

As you see this could be quite noisy and complex to be comprehensible by human.

Various scripting languages are trying to reduce syntax noise in various ways. Scala for example allows to define XML literals http://programming-scala.labs.oreilly.com/ch10.html inline without need of "mangling" it by quotes. This feature appears as quite neat but is limited by XML only. E.g. it will not work for HTML ("HTML is not XML"™) or for things like CSS selectors, etc.

Another example is string templates in Ruby. They allow to define string literals with embedded code:

template = 'Dear #{customer},\nPlease pay us #{amount} now.\n'

but this still needs string literal. One more problem with such approach: various types of strings need different escapement rules applied to values being embedded in the string. E.g. for HTML it should be String.htmlEscape() call, for URLs – String.urlEscape(), etc.

So there is a need to have some syntax construction that will allow to define various ways to define string compostions.

Solution.

As a solution I’ve implemented in TIScript so called stringizer functions.

Stringizer function is a function (or method) with the name starting from ‘$’ character and with variable number of parameters.

Call of such function is written in the form:

$name( ... some text here... )

Where the text inside ‘(’ and ‘)’ is not required to be enclosed in quotes. Characters ‘(’ and ‘)’ are serving role of quotes by themselves.

Example of such stringizer call:

var firstDiv = self.$( #content > div:first-child );

$ here a stringizer method that accepts CSS selector expressions. The sample above is a direct equivalent of this:

var firstDiv = self.select( "#content > div:first-child" );

Text inside ‘(’ and ‘)’ may contain expressions enclosed in curly brackets ‘{’ and ‘}’. Result of the expression in such brackets will be passed into the stringizer function as is.

Having all this in place the very first example of the article can be written in Sciter simply as:

someelement.html
    = $html( <span style="color:#ffffff">{ somestuff }</span> );

TIScript will de facto compile this call as:

someelement.html
    = $html( "<span style="color:#ffffff">",
               somestuff,
               "</span>" );

The only thing left is an implementation of the $html() function that we can define like this:

function $html(params..)
{
  for( var (n,v) in params )
    if( n & 1 ) // each odd paramter is a
                    // value of expression inside '{' and '}'
      params[n] = v.toHtmlString(); // calling method
                    // that will do HTML escapement
  return params.join(""); //return composed string
}

Some ideas

Here are some ideas for such stringizer functions we can use in the Sciter:

  • function Element.$append( ... inline html ... ) – method of the DOM element class – appends the html after last child of the element.
  • function Element.$prepend( ... inline html ... ) – prepends the html before first child of the element.
  • function $text( ... some text ... ) – simple way of composing texts.
  • function Stream.$print(... some text ... ) – simply prints text with possible { } inclusions.
  • function $xml( ... some xml... ) – to compose XML string and create XML tree using built-in XML parser.
  • you name it…

Achtung, minen!

July 11, 2009

Filed under: Script, Web Application Techologies — Andrew @ 11:20 pm

One more “cool” thing about JS:

somevar = 100;

      function test()
      {
        somevar = 1;
        return somevar;
        if(false) { var somevar; }
      }

      alert(test());
      alert(somevar);

Try to guess first what these two alert()s will output in JS.

You did?

Then try to see this code running alive: js-mine.

That is what Web2 is supposed to be based on… Huh?

[update] Here is a link on Doug’s Crockford talk at Google about JS.

Doug Crockford is behind JSON spec and ECMAScript 3.1.

Probably Doug’s speech may explain why I decided to go with TIScript rather than implementing JS as it is.

CSS Flexible Flow Module

April 10, 2009

Filed under: HTML and CSS, Web Application Techologies — Andrew @ 6:05 pm

We have published official proposal about ‘flow’ and flex units used in h-smile core:
CSS Flexible Flow Module

With the hope that the Web will benefit from them.

TIScript vs. JavaScript

February 25, 2009

Filed under: Sciter, Script — Andrew @ 7:12 pm

I have published article comparing TIScript and JavaScript on CodeProject. That is a “big picture” if you wish.

I have written this article completely in the ScApp (Sciter Application) named BlockNote for the Net:

Screenshot of BlockNote ScApp

Screenshot of BlockNote ScApp

It is a part of Sciter SDK and reside in sdk/scapps/blocknote.net/ folder.

Eventually this will replace outdated BlockNote v.1.8 application. Plan is to create platform for comfortable content editing in Internet. E.g. as an editor it is already more convenient than built-in editor of the WordPress application I am using here.

Decorators in TIScript, fun of UI programming is back.

January 26, 2009

Filed under: Sciter, Script — Andrew @ 10:21 pm

Latest builds of the Sciter have decorators implemented. My implementation of decorators ideologically derived from the same decorator feature in Python of Guido van Rossum.

Decorators is a meta/macro-programming feature that allows to transform or update function or class defined in source code.

Here is an example: say we are designing some dialog with various input elements and buttons. Usually code behind such dialogs is a collection of simple “if-we’ve-got-some-event-here-then-update-state-over-there” blocks. First part (if-we’ve-got-some-event-here…) of the task is repeating again and again. The desire is to make it as short and clear as possible. With decorators this could be written as:

@when Event.BUTTON_CLICK @on "button#add-new" :
   {
      this.select("#list").insert( new Element( "option", "new item") );
   }
@when Event.SELECT_SELECTION_CHANGED @on "select#list" :
   {
      this.select("#delete-current").state.enabled = true;
   }
...

This makes such sequence of blocks to look more like a table of records: when (event) on (where) (then do this). That is more declarative approach if you wish. This code is better maintainable I think.

@when and @on here are decorators of anonymous function that follow them. ( Sequence :{ ... } declares anonymous function in TIScript ).

Decorator in TIScript is an ordinary function with the name starting ‘@’ and at least one parameter. This first parameter is a reference to function that is being decorated. Decorator-function in its turn can dynamically create another function that will wrap call of original function.

Here is how our @when and @on decorators might look like:

// decorator '@when' - filters event by type
function @when(func, evtType)
    {
      return self.onControlEvent = function(evt)
         {
           if( evt.type == evtType)
              return func.call(this,evt);
         }
    }

// decorator '@on' - filters evt.target by the selector
function @on(func, selector)
    {
      return function(evt)
      {
        if( evt.target.match(selector) ) // if target element matches
          return func.call(this,evt);       // the selector call the func.
      }
    }

Chain of decoratorsAs you may see both decorators simply create wrapper functions that filter the event using different criteria. Thus following statement:

@when Event.BUTTON_CLICK @on "button#add" :{...code...}

simply establishes chain of filters that ends up with the call of code that handles the event.

Syntax of decorators in TIScript is described here.

« Previous PageNext Page »