Function with multiple names - dart

In JavaScript you can do this to assign a function to multiple references:
z = function(){
console.log(1)
}
x = y = z
Now when we call x or y, 1 gets printed to the console.
Is this possible in dart?

Yes, just like in JavaScript, functions are first class citizens and can be assigned to variables.
Also see this somewhat older, but still relevant video Functions are Fun, Pt2.
As Example from the video:
loudPrint(String msg) {
print(msg.toUpperCase());
}
var loudify = loudPrint;
loudify('Dart is fun');
// DART IS FUN

Related

box callback functions returning the same string in Rascal

I'm trying to draw some boxes in Rascal and trying to give each box its own callback function. On entering the box with the mouse the corresponding string should get displayed in the text element (so hovering box1 should display box1 etc.).
However, at the moment the text does pop up but just displays "box3" for each of the 3 boxes.
Any ideas?
strings = ["box1", "box2", "box3"];
boxes = [ box(
size(100, 100),
onMouseEnter(void() {
output = s;
})
) | s <- strings];
render(hcat([
vcat(boxes),
text(str () {return output;})
]));
Good question, classical problem. The essence of the problem is that Rascal uses "non-capturing closures": this means that functions that are returned from another function share the same context. In your case this is the variable s introduced by s <- strings. This nearly always happens when you create function values in a loop (as you do here). The solution is to wrap another function layer around the returned function.
Here is a simple example:
list[int()] makeClosures()
= [ int() {return i;} | i <- [0,1,2]];
void wrong(){
lst = makeClosures();
println(lst[0]());
println(lst[1]());
println(lst[2]());
}
which will print surprisingly the values 2,2and2`. The solution is, as said, to introduce another function level:
int() makeClosure(int i)
= int() { return i;};
list[int()] makeClosuresOK()
= [ makeClosure(i) | i <- [0,1,2]];
void right(){
lst = makeClosuresOK();
println(lst[0]());
println(lst[1]());
println(lst[2]());
}
now calling right() will print 1, 2, and 3 as expected.
I leave it as an exercise how this is done in your example, but I am prepared to give a solution when you ask for it. Good luck!

How to assign results of futures in Dart depending on which future produced them?

In Dart, I want to run several costly functions, which are independent of each other, and assign the results to my variables, depending on which function produced them. Roughly a parallel version of this:
double x = getX();
double y = getY();
I'm thinking of something like this:
double x, y;
Future.wait([
futureGetX(),
futureGetY()
]).then((List results) {
results.foreach((r) {
// if(r is produced by futureGetX) x = r;
// if(r is produced by futureGetY) y = r;
});
});
and I don't know how to implement this is produced by part. A way would be to wrap the result of each function in a different class and, in the then part, check the class of the result:
if(r is wrapperForX) x = r.getValue();
if(r is wrapperForY) y = r.getValue();
but this seems very inelegant to me. Any suggestions?
Untested, but I think I got this. :)
Use closures:
Future.wait([
() => { x = await futureGetX()},
() => { y = await futureGetY()},
]);
Thanks to Randal I found a solution:
Future.wait([
() async { x = await futureGetX(); } (),
() async { y = await futureGetY(); } ()
]);
To wait for Futures in parallel, you use Future.wait, as you already noticed.
The results in the list returned (asynchronously) by Future.wait are in the same order as the original futures, so instead of using forEach you can just do:
x = results[0];
y = results[1];
Another way would be to use FutureGroup from async package, FIFO behavior for the result list is documented: https://www.dartdocs.org/documentation/async/1.13.3/async/FutureGroup-class.html

Why is it the same table even though it is not a prototype

I have this code:
function createRect(x, y, w, h)
local rect = {
type = "rect",
x = x,
y = y,
w = w,
h = h,
translate = function(rect, vector)
assert(vector.type == "vector2d")
local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h)
end,
}
return rect
end
translate = function(rect, vector)
assert(vector.type == "vector2d")
local rect = shapes.createRect(rect.x + vector.x, rect.y + vector.y, rect.w, rect.h)
end
local o = createRect(2,3,4,5)
local q = createRect(2,3,4,5)
print(o.translate, q.translate, translate)
Which is some very easy code and is written to test factory functions in Lua and is very reminiscent of the JS module pattern. Something people usually complain about when talking about factory functions is the memory footprint.
Because o and q are just assigned, of course they have different translate() functions, I assumed.
However I was proven wrong:
function: 0x7fcdbe600d50 function: 0x7fcdbe600d50 function: 0x7fcdbe600d90
Why is this? How can this even be? I assumed to be o.translate and q.translate to be different functions, however they are the same...
How can this even be? I assumed to be o.translate and q.translate to be different functions, however they are the same...
Normally you are correct, however Lua 5.2 introduced an optimization where anonymous functions may be cached if certain conditions are met. Specifically, if the values it references doesn't change between construction then the first created instance of that anonymous function gets reused.
Running your example in repl.it, Lua 5.1, shows this as one possible output:
function: 0xb81f30 function: 0xb81f00 function: 0xb82ca0
But running it under melpon.org/wandbox, Lua 5.2+, shows:
function: 0x14f0650 function: 0x14f0650 function: 0x14efb40
In your example, createRect creates and returns a different rect table for every call but the field rect.translate is being assigned the same anonymous function as the lua value due to this optimization.
Also see
http://lua-users.org/lists/lua-l/2010-07/threads.html#00339
http://lua-users.org/lists/lua-l/2010-07/msg00862.html
http://lua-users.org/lists/lua-l/2010-05/threads.html#00617

How can I print multiple objects to console.log with dart?

In javascript, if I have 3 variables like this:
var x = 1
var y = 'cat'
var z = {color: 'blue'}
I can log all of them like this:
console.log('The values are:', x, y, z)
In dart, you can import 'dart:html' and it will map print to console.log in the compiled javascript. But print only takes one parameter - not 3. This dart will fail when the compiled js runs in the browser:
print('The values are:', x, y, z)
The only thing I can think to do is stringify these arguments and join them into one string, and print that. But then I lose Chrome's ability to expand objects that are printed to the console.
Is it possible to print multiple objects with one print statement (or similar statement)? If so, how?
What about: ?
print('The values are: ${[x, y, z]}')
or
print('The values are: $x, $y, $z')
or
['The values are:', x, y, z].forEach(print);
In Dart, you can import dart:html which gives you access to the window.console. Unfortunately, its log method can only take one argument. You can wrap your objects in a list though:
import 'dart:html';
var x = 1
var y = 'cat'
var z = {color: 'blue'}
window.console.log([x, y, z]);
use
print("$x,$y,$z");
or
stdout.write("$x,$y,$z");

Using array notation instead of NSM on functions deeper then js.context.X

Can all objects after js.context be accessed with array notation from Dart? For example, I'd like to convert the following to use array notation:
var request = js.context.gapi.client.request(js.map(requestData));
Will the following array notation work?
var request = js.context['gapi']['client']['request'](js.map(requestData));
Also, should the following be done if trying to access JavaScript builtin methods?
js.context['JSON']['stringify'](jsonResp);
TL;DR : Starting from r24278 use array notation for properties and noSuchMethod for methods.
Using js.context['gapi']['client'] gives the same result as js.context.gapi.client. The main advantage of Array notation is that it avoids noSuchMethod. Until recently it was the only way to work around an issue in dart2js where minified does not work with noSuchMethod. This issue is fixed, and minification should work with Dart-JS interop.
I did a little benchmark some times ago :
For attribute access : array notation is around 10% faster than noSuchMethod. ( js.context.x vs. js.context['x'] )
For method access : array notation is around 50% slower than noSuchMethod. ( js.context.f() vs. js.context['f']() )
This last result is explained by 2 communications between JS and Dart for js.context['f'](). One to retrieve the function reference ( js.context['f'] ) and an other to call this function.
Last concern, using noSuchMethod can increase your dart2js result size (but not so much where I had tested it).
This works for me:
var hug = new js.Proxy(context['Hug']);
var hugDatabase = new js.Proxy(context['HugDatabase']);
hugDatabase['addHug'](hug);
print(hugDatabase['hugs']['length']);
Which interacts with this JavaScript:
function Hug(strength) {
this.strength = strength;
}
Hug.prototype.embrace = function(length) {
return 'Thanks, that was a good hug for ' + length + ' minutes!';
}
Hug.prototype.patBack = function(onDone) {
onDone('All done.');
}
function HugDatabase() {
this.hugs = [];
}
HugDatabase.prototype.addHug = function(hug) {
this.hugs.push(hug);
}
The full example is here: https://github.com/sethladd/dart-example-js-interop/blob/master/web/dart_js_interop_example.dart

Resources