> We've found the need for serializable functions in AmbientTalk, which,  
> like JS, encourages a style of programming that makes significant use  
> of lexical nesting. We have found that this programming style makes  
> that requiring serializable functions to be closed is indeed too  
> restrictive.
>
> Translated to JS, our solution looks like: 
>  
> var z = 42; 
> var f = function(x,y) (z) { 
> // x and y are locals, z refers to (a copy of) the upvar 
> } 
>  
> Here, f is a pass-by-copy function. The second parameter list captures  
> the upvars that should be serialized together with the function.



That seems a syntax sugar for something along those lines:

|    var z = 42;
|    var f = function(x,y):safe(z){
|        
|        ...
|        
|    };

becoming

|    var z = 42;
|    var f = function(x,y):safe{
|        const z = 42;
|        
|        ...
|        
|    }

where 42 is actually replaced by the value of 'z' at the time of construction. 
Did I understand correctly?

I think the idea is good, but in practice this could be emulated by using 
eval("function(x,y):safe { var z = " + uneval(z) + " ... }")




Any other kind of non-serialization transfer (like transferring an object to 
another thread) can be done using standards arguments of the safe function 
(and, if necessary, a library on top of it), it doesn't have to be dealt with 
at the safe-function level.

Any kind of special serialization can be handled on the platform separately. We 
could even define an object with an @unserialize serializable function, which 
would finally enable to serialize properly cyclic graphs of objects:

|    function serializeAsFunction(o){
    |        var source = [o]; var destin = ['o']; var instructions = [];
    |        var jso=Object.mapPropertiesRecursively(o, function(object, 
property, path){
|            var v = property.value; if(!v) return;
        |            if (typeof v =='object') {
            |                var index = source.indexOf(v);
            |                if(index !== -1) { 
|                    instructions.push("o"+path+"=o"destin[index]);
|                    return null;
|                } else {
|                    source.push(v);
|                    destin.push(path);
|                }
        |            }
|            return v;
    |        });
    |        return function():safe(o,instructions) { 
|            ... execute all instructions in order ...
|            return o;
|        };
|    };

I could obviously already achieve something like that using simple functions, 
but safe functions are much better because the person executing the code can be 
sure that, whatever the function does, it is not having a single pointer to the 
current environment and therefore cannot do more harm that just eating the CPU 
(and the calling code could setup some kind of "abort in X seconds" system if 
needed).

This also opens the way to more compressed data messages, since you could for 
instance define functions for serializing purposes:

|    function():safe {
|        var row = function StockActionUpdate(name,oldPrice,newPrice){
|            return { name: name, oldPrice: oldPrice, newPrice: newPrice, 
variation: (newPrice-oldPrice)/oldPrice, isUp:(newPrice>oldPrice), 
isDown:(oldPrice>newPrice), toSpeakAloudString: function():safe{ return 
this.name+' ('+this.newPrice+')'+(this.isDown?' is down':' is up')+' since 
yesterday ('+this.oldPrice+')'} }
|        };
|        return {
|            'MSFT':row('Microsoft Corporation', 30, 31),
|            'GOOG':row('Google Inc', 490, 491),
|            'AAPL':row('Apple Inc', 480, 481),
|            ...
|        };
|    }

This is more compact than a traditional JSON channel, and safer than a 
traditional "eval" code channel. I didn't say "totally safe" because the 
browser can have a security bug, which even a "safe" function could use, but 
this is very unlikely in pure JS functions, and you cannot protect reliably 
your application from browser bugs anyway.


The beauty of all this, is that all code coming out of the safe function as a 
return value cannot possibly be unsafe, because it cannot possibly have got any 
reference to the outside world (at least not any you didn't give them).         
                            
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to