February achievements 2013-03-02 03:12:06
February achievements
A great deal of work has gone into making Cadre more effective and useful in the past few weeks. Following on the news post from early last month, work into completing Objective Cadre has been the primary focus. Mixed dynamic/lexical scope has also been implemented.


  • new extension for soft descriptions of permissions (summarize_permissions() in soft_controls)


  • new unix_time() (from normal timestamp) and date_diff() operations in date_functions extension.


  • variables can now be used without sigils.


  • functions can now be called from live data.


  • (restriction: functions cannot be called with sigils. @_this.func() will return the function, as if the parentheses were missing.)


  • Modes can now be called as functions. There is a lot to say about this.

  • a) _edit() will call the mode "edit" on the current page if possible, and fail back to searching for a dynamic function of the same name. This style of call is dynamically scoped, so that transactional variables are shared. Changes to $_body will be seen immediately, and inherited from calling modes.

    b) @_this.edit() or @_this._edit() will also work, but with the subtle distinction that there is no context and hence transactional entry property changes are out of scope. Changes to transactional entry properties (e.g. $_title) will not be shared at all.

    c) Calling modes on any other entry (x = import entry 1; x.edit()) will have no context either and hence also will be completely out of scope.


  • Scope is implemented as follows:

  • (a) called modes have dynamic scope only if they're not called as members of a live data object.

    (b) dynamic functions (entries with executability = 4) have dynamic scope with whatever called them. (This keeps the behaviour consistent with (a).)

    (c) a bare function (one defined with the "function" keyword) retains lexical scope, but will fall back to dynamic scope if this fails. Any stack frame asked to check scope dynamically as a result will try to search for meaning lexically before perpetuating the dynamic search, so in:


    var d = "third";

    a = function {[
        var d = "second";
        b = function {[
            var d = "first";
            c = function {[
                d = "replaced";
            ]};
            c;
        ]};
        b;
    ]};

    t = function {[
        var d = "fifth";
        r = function {[
            var d = "fourth";
            m = a();
            m();
        ]};
        r;
    ]};

    q = t();

    q();



    The 'first' occurrence of [t]d[/t] gets replaced; if it were absent, the 'second' would be replaced, and so on. Dynamic scope is considered only when lexical scope is exhausted, and following dynamic scope may replenish the availability of lexical scope.
    Cadre News comment · 11 years ago