Async Programming

classic Classic list List threaded Threaded
81 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

Async Programming

Nicolas Cannasse
Hi,

Thinking about recent talks on short function syntax and async
programming in general, I am thinking about introducing some changes in
next haXe release, which might be a 3.0 version if we roll out the
package changes that have been planned.

Two things that I would like to change :

1) allow access to "this" in local functions, with the same semantic as
the following code :
        var me = this;
        function() me.foo();
    This will also allow for instance to access member variables without
"this." prefix.

2) introduce a short syntax for async programming. Maybe allow something
like :

        before();
        inst.doSomething(function(result) trace("Done"));
        after();

     to be written as :

        {
          before();
          var result = inst->doSomething(); // async call
          trace("Done");
        }
         after();

     This would in fact delay the execution of the current block the
async call is being made until the result is available, and would still
exit the block before it is to continue execution.

Not sure yet if I want to really do it this way, that's why I'll be
happy to get some feedback on this ;)

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
I agree with point one. It makes sense and has always been a pain in my
side not being able to do this in haXe. As for point two, I'm not sure
this works. I'm definitely for async, of course, but the suggested idea
seems a bit quirky. What's wrong with specifying some form of callback,
even if it's in a tidier syntax? For instance, why not this:

var callback = function() { trace("I'm done"); }
before();
inst->doSomething()->callback();
trace( "may execute before callback" );

Might even be useful to pass parameters into callback that get passed
when callback is finally invoked.

Just an idea, and needs far more thought than the two minutes I put into
it, but it flows better than your alternative, I think ;-)

Lee




Nicolas Cannasse wrote:

> Hi,
>
> Thinking about recent talks on short function syntax and async
> programming in general, I am thinking about introducing some changes
> in next haXe release, which might be a 3.0 version if we roll out the
> package changes that have been planned.
>
> Two things that I would like to change :
>
> 1) allow access to "this" in local functions, with the same semantic
> as the following code :
>     var me = this;
>     function() me.foo();
>    This will also allow for instance to access member variables
> without "this." prefix.
>
> 2) introduce a short syntax for async programming. Maybe allow
> something like :
>
>     before();
>     inst.doSomething(function(result) trace("Done"));
>     after();
>
>     to be written as :
>
>     {
>       before();
>       var result = inst->doSomething(); // async call
>       trace("Done");
>     }
>         after();
>
>     This would in fact delay the execution of the current block the
> async call is being made until the result is available, and would
> still exit the block before it is to continue execution.
>
> Not sure yet if I want to really do it this way, that's why I'll be
> happy to get some feedback on this ;)
>
> Best,
> Nicolas
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Benjamin Dasnois
In reply to this post by Nicolas Cannasse
Hello Nicolas,

1) So basically it is just allowing local function to be instance functions and not static functions?Sounds good to me.

2) I'm not sure I do understand. Does it mean that before() would still be executed first, then either trace or result=... and always last after ? The syntax seems a bit strange to me... Although those are interesting features (I wonder how they can be generated on all targets on a side note), I'm not sure they should be implemented this way.

Regards,

On Wed, Aug 18, 2010 at 11:10 PM, Nicolas Cannasse <[hidden email]> wrote:
Hi,

Thinking about recent talks on short function syntax and async programming in general, I am thinking about introducing some changes in next haXe release, which might be a 3.0 version if we roll out the package changes that have been planned.

Two things that I would like to change :

1) allow access to "this" in local functions, with the same semantic as the following code :
       var me = this;
       function() me.foo();
  This will also allow for instance to access member variables without "this." prefix.

2) introduce a short syntax for async programming. Maybe allow something like :

       before();
       inst.doSomething(function(result) trace("Done"));
       after();

   to be written as :

       {
         before();
         var result = inst->doSomething(); // async call
         trace("Done");
       }
       after();

   This would in fact delay the execution of the current block the async call is being made until the result is available, and would still exit the block before it is to continue execution.

Not sure yet if I want to really do it this way, that's why I'll be happy to get some feedback on this ;)

Best,
Nicolas

--
haXe - an open source web programming language
http://haxe.org



--
DASNOIS Benjamin
http://www.benjamindasnois.com

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
Nicolas means the block would stop executing until the async request
returned, but whatever is outside the block would execute, thus after()
would probably execute before the trace.

Lee




Benjamin Dasnois wrote:

> Hello Nicolas,
>
> 1) So basically it is just allowing local function to be instance
> functions and not static functions?Sounds good to me.
>
> 2) I'm not sure I do understand. Does it mean that before() would
> still be executed first, then either trace or result=... and always
> last after ? The syntax seems a bit strange to me... Although those
> are interesting features (I wonder how they can be generated on all
> targets on a side note), I'm not sure they should be implemented this way.
>
> Regards,
>
> On Wed, Aug 18, 2010 at 11:10 PM, Nicolas Cannasse
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     Hi,
>
>     Thinking about recent talks on short function syntax and async
>     programming in general, I am thinking about introducing some
>     changes in next haXe release, which might be a 3.0 version if we
>     roll out the package changes that have been planned.
>
>     Two things that I would like to change :
>
>     1) allow access to "this" in local functions, with the same
>     semantic as the following code :
>            var me = this;
>            function() me.foo();
>       This will also allow for instance to access member variables
>     without "this." prefix.
>
>     2) introduce a short syntax for async programming. Maybe allow
>     something like :
>
>            before();
>            inst.doSomething(function(result) trace("Done"));
>            after();
>
>        to be written as :
>
>            {
>              before();
>              var result = inst->doSomething(); // async call
>              trace("Done");
>            }
>            after();
>
>        This would in fact delay the execution of the current block the
>     async call is being made until the result is available, and would
>     still exit the block before it is to continue execution.
>
>     Not sure yet if I want to really do it this way, that's why I'll
>     be happy to get some feedback on this ;)
>
>     Best,
>     Nicolas
>
>     --
>     haXe - an open source web programming language
>     http://haxe.org
>
>
>
>
> --
> DASNOIS Benjamin
> http://www.benjamindasnois.com


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Nicolas Cannasse
In reply to this post by Lee Sylvester
> seems a bit quirky. What's wrong with specifying some form of callback,
> even if it's in a tidier syntax? For instance, why not this:
>
> var callback = function() { trace("I'm done"); }
> before();
> inst->doSomething()->callback();
> trace( "may execute before callback" );

Well, the issue with local functions is what that your code is being
nested :

inst.wait1(function(a) {
     inst.wait2(function(b) {
        inst.wait3(function(c) {
           trace("Done : "+[a,b,c]);
        });
     });
});

Whereas async calls allow more flat syntax :

var a = inst->wait1();
var b = inst->wait2();
var c = inst->wait3();
trace("Done : "+[a,b,c]);

(please note that this is actually being transformed into local
functions by the compiler itself, so both are interchangable).

Nicolas

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

John A. De Goes
In reply to this post by Nicolas Cannasse
On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
1) allow access to "this" in local functions, with the same semantic as the following code :

+1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.

2) introduce a short syntax for async programming. Maybe allow something like :

-1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.

There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.

There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.

Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.

Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.

Monadic shorthand in HaXe might look something like this for futures:

var imageFuture: Future<Image> = do {
   data <- urlLoader.load('meta.cfg");
   meta <- new Meta(data);
   imageUrl <- meta.get('backgroundImageUrl');
   image <- urlLoader.load(imageUrl);
} yield image; // This is Future<Image>

The same structure would work identically for lists:

var evenIntegersSquared: List<Int> = do {
  integer <- allIntegers;
  if (integer % 2 == 0)
  squared <- x * x
} yield squared; 

Or any other monads!

This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').

For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.

Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.

So in my view, our choice is as follows:

1) Do we add an ad hoc feature to simplify just asynchronous programming, which will make the language more cluttered and not substantially more powerful?

2) Or do we add a powerful rewriting feature (common in functional languages and even scripting languages like Python), based on predictable, deterministic rewrite rules, which simplifies not just asynchronous programming, but many other tasks, giving us list comprehensions, state management, option propagation, and more for free?

I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is. 

Regards,

John


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
In reply to this post by Nicolas Cannasse
Isn't there a difference here? The nested local functions would return
in the reverse order that they were invoked, but the alternative could
be in any order, abstracted from any other call. Is that not so?

Lee


Nicolas Cannasse wrote:

>> seems a bit quirky. What's wrong with specifying some form of
>> callback, even if it's in a tidier syntax? For instance, why not this:
>>
>> var callback = function() { trace("I'm done"); }
>> before();
>> inst->doSomething()->callback();
>> trace( "may execute before callback" );
>
> Well, the issue with local functions is what that your code is being
> nested :
>
> inst.wait1(function(a) {
>     inst.wait2(function(b) {
>        inst.wait3(function(c) {
>        trace("Done : "+[a,b,c]);
>        });
>     });
> });
>
> Whereas async calls allow more flat syntax :
>
> var a = inst->wait1();
> var b = inst->wait2();
> var c = inst->wait3();
> trace("Done : "+[a,b,c]);
>
> (please note that this is actually being transformed into local
> functions by the compiler itself, so both are interchangable).
>
> Nicolas
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Nathan
In reply to this post by John A. De Goes
+1 to John's response from me certainly :)

I'd add..
- allow extension to haxe internal classes
- indeterminate amount of args function( text:String... )
- define what exceptions a function/method throws (on an interface)
- override type of vars via inheritance
- allow typing like: function foo( arg:(EventListener,Event->Void) ) {
- allow constants (static var) on interfaces
- allow definition of primitive types like unsigned long
- package wide constants
- allow for optional params with (String -> ?Int -> Void) syntax <-ex
- associative arrays and bar[foo] access to objects/dynamic (foo:String)
- add a native Object type... which can be for-looped
- short hand way to add static method inheritance (even if just sugar)

probably more, but I forget


John A. De Goes wrote:

> On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
>> 1) allow access to "this" in local functions, with the same semantic as the following code :
>
> +1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.
>
>> 2) introduce a short syntax for async programming. Maybe allow something like :
>
> -1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.
>
> There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.
>
> There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.
>
> Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.
>
> Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.
>
> Monadic shorthand in HaXe might look something like this for futures:
>
> var imageFuture: Future<Image> = do {
>    data <- urlLoader.load('meta.cfg");
>    meta <- new Meta(data);
>    imageUrl <- meta.get('backgroundImageUrl');
>    image <- urlLoader.load(imageUrl);
> } yield image; // This is Future<Image>
>
> The same structure would work identically for lists:
>
> var evenIntegersSquared: List<Int> = do {
>   integer <- allIntegers;
>   if (integer % 2 == 0)
>   squared <- x * x
> } yield squared;
>
> Or any other monads!
>
> This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').
>
> For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.
>
> Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.
>
> So in my view, our choice is as follows:
>
> 1) Do we add an ad hoc feature to simplify just asynchronous programming, which will make the language more cluttered and not substantially more powerful?
>
> 2) Or do we add a powerful rewriting feature (common in functional languages and even scripting languages like Python), based on predictable, deterministic rewrite rules, which simplifies not just asynchronous programming, but many other tasks, giving us list comprehensions, state management, option propagation, and more for free?
>
> I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is.
>
> Regards,
>
> John
>
>
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
In reply to this post by John A. De Goes
Isn't this the same as Nicolas's initial proposal? For example:

    var imageFuture: Future<Image> = do {
       data <- urlLoader.load('meta.cfg");
       meta <- new Meta(data);
       imageUrl <- meta.get('backgroundImageUrl');
       image <- urlLoader.load(imageUrl);
    } yield image; // This is Future<Image>


Would be similar to:

        {
             before();
             var data = async->urlLoader.load( 'meta.cfg' );
             var meta = new Meta( data );
             var imageUrl = meta.get( 'backgroundImageUrl' );
             var image = async->urlLoader.load( imageUrl );
             trace( "Done" );
       }
       after();

The async calls are blocking the further execution of the block.

Excuse me if I missed something :-)  I've no familiarity with monadic
syntax or futures.

Lee




John A. De Goes wrote:

> On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
>> 1) allow access to "this" in local functions, with the same semantic
>> as the following code :
>
> +1. This will eliminate a lot of boilerplate code ('var self =
> this;'). The current limitations of local functions are very confusing
> to developers who are new to HaXe.
>
>> 2) introduce a short syntax for async programming. Maybe allow
>> something like :
>
> -1. This is an ad hoc feature designed to solve a very specific
> problem, and making it work across platforms with a billion different
> syntaxes for callbacks will be difficult. HaXe will grow cluttered if
> too many ad hoc features are added.
>
> There is already a powerful concept for asynchronous programming
> called a "Future". However, it's a little clumsy to use Futures
> because of the verbose lambda syntax.
>
> There's an alternative to a shorter lambda syntax that would
> tremendously improve the power of the HaXe language.
>
> Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax
> for compactly interacting with monads, it would be useful not just for
> Futures, but for all monads -- lists, options, state, etc. Therefore,
> instead of adding a feature specific to support just asynchronous
> programming, I suggest adding syntactic sugar for monads. This will
> keep HaXe from acquiring too many ad hoc features that only solve very
> specific problems.
>
> Many people have asked for "list comprehensions". In fact, monadic
> shorthand is exactly what is needed for "list comprehensions", "easy
> asynchronous programming", "easy option programming", and much more.
> We can bring the power of all these to the language with a single
> general purpose feature that merely adds syntactic sugar.
>
> Monadic shorthand in HaXe might look something like this for futures:
>
>     var imageFuture: Future<Image> = do {
>        data <- urlLoader.load('meta.cfg");
>        meta <- new Meta(data);
>        imageUrl <- meta.get('backgroundImageUrl');
>        image <- urlLoader.load(imageUrl);
>     } yield image; // This is Future<Image>
>
>
> The same structure would work identically for lists:
>
>     var evenIntegersSquared: List<Int> = do {
>       integer <- allIntegers;
>       if (integer % 2 == 0)
>       squared <- x * x
>     } yield squared;
>
>
> Or any other monads!
>
> This syntax is very similar to Haskell, Scala, and list comprehensions
> in other languages (although if you don't like this syntax, there are
> plenty of others to choose from). The above is rewritten by the
> compiler into combinations of map, flatMap, and filter (if a
> conditional is used) -- therefore, it works not just for library
> classes that have these methods, but also for user-defined classes
> that have these methods (and even enums and such, which have the
> corresponding extension methods with 'using').
>
> For exact rewrite rules, see Daniel's response
> at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.
>
> Stax already has futures, options, and other monads. They're better
> than the alternatives, but with monadic notation, they would be a real
> pleasure to use. And monadic notation would not be an ad hoc feature
> designed to solve a very specific problem -- it would be a core,
> general purpose rewriting feature baked into the language, which could
> solve many problems we can't even imagine right now.
>
> So in my view, our choice is as follows:
>
>     1) Do we add an ad hoc feature to simplify just asynchronous
>     programming, which will make the language more cluttered and not
>     substantially more powerful?
>
>     2) Or do we add a powerful rewriting feature (common in functional
>     languages and even scripting languages like Python), based on
>     predictable, deterministic rewrite rules, which simplifies not
>     just asynchronous programming, but many other tasks, giving us
>     list comprehensions, state management, option propagation, and
>     more for free?
>
>
> I've talked to many HaXe programmers about this and I speak for most
> of them when I say that HaXe + monadic shorthand would seriously kick
> ass. It would also bring more functional programmers to HaXe, who
> currently consider HaXe too verbose for true functional programming.
> And the average person who uses "future comprehensions" or "list
> comprehensions" doesn't need to understand the rewrite rules, how they
> work, or what a monad is.
>
> Regards,
>
> John
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
In reply to this post by Nathan
Is this your list to Santa?  Get it in early, buddy. Christmas may
follow ;-)

Lee



Nathan wrote:

> +1 to John's response from me certainly :)
>
> I'd add..
> - allow extension to haxe internal classes
> - indeterminate amount of args function( text:String... )
> - define what exceptions a function/method throws (on an interface)
> - override type of vars via inheritance
> - allow typing like: function foo( arg:(EventListener,Event->Void) ) {
> - allow constants (static var) on interfaces
> - allow definition of primitive types like unsigned long
> - package wide constants
> - allow for optional params with (String -> ?Int -> Void) syntax <-ex
> - associative arrays and bar[foo] access to objects/dynamic (foo:String)
> - add a native Object type... which can be for-looped
> - short hand way to add static method inheritance (even if just sugar)
>
> probably more, but I forget
>
>
> John A. De Goes wrote:
>> On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
>>> 1) allow access to "this" in local functions, with the same semantic
>>> as the following code :
>>
>> +1. This will eliminate a lot of boilerplate code ('var self =
>> this;'). The current limitations of local functions are very
>> confusing to developers who are new to HaXe.
>>
>>> 2) introduce a short syntax for async programming. Maybe allow
>>> something like :
>>
>> -1. This is an ad hoc feature designed to solve a very specific
>> problem, and making it work across platforms with a billion different
>> syntaxes for callbacks will be difficult. HaXe will grow cluttered if
>> too many ad hoc features are added.
>>
>> There is already a powerful concept for asynchronous programming
>> called a "Future". However, it's a little clumsy to use Futures
>> because of the verbose lambda syntax.
>>
>> There's an alternative to a shorter lambda syntax that would
>> tremendously improve the power of the HaXe language.
>>
>> Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax
>> for compactly interacting with monads, it would be useful not just
>> for Futures, but for all monads -- lists, options, state, etc.
>> Therefore, instead of adding a feature specific to support just
>> asynchronous programming, I suggest adding syntactic sugar for
>> monads. This will keep HaXe from acquiring too many ad hoc features
>> that only solve very specific problems.
>>
>> Many people have asked for "list comprehensions". In fact, monadic
>> shorthand is exactly what is needed for "list comprehensions", "easy
>> asynchronous programming", "easy option programming", and much more.
>> We can bring the power of all these to the language with a single
>> general purpose feature that merely adds syntactic sugar.
>>
>> Monadic shorthand in HaXe might look something like this for futures:
>>
>> var imageFuture: Future<Image> = do {
>>    data <- urlLoader.load('meta.cfg");
>>    meta <- new Meta(data);
>>    imageUrl <- meta.get('backgroundImageUrl');
>>    image <- urlLoader.load(imageUrl);
>> } yield image; // This is Future<Image>
>>
>> The same structure would work identically for lists:
>>
>> var evenIntegersSquared: List<Int> = do {
>>   integer <- allIntegers;
>>   if (integer % 2 == 0)
>>   squared <- x * x
>> } yield squared;
>> Or any other monads!
>>
>> This syntax is very similar to Haskell, Scala, and list
>> comprehensions in other languages (although if you don't like this
>> syntax, there are plenty of others to choose from). The above is
>> rewritten by the compiler into combinations of map, flatMap, and
>> filter (if a conditional is used) -- therefore, it works not just for
>> library classes that have these methods, but also for user-defined
>> classes that have these methods (and even enums and such, which have
>> the corresponding extension methods with 'using').
>>
>> For exact rewrite rules, see Daniel's response at:
>> http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.
>>
>>
>> Stax already has futures, options, and other monads. They're better
>> than the alternatives, but with monadic notation, they would be a
>> real pleasure to use. And monadic notation would not be an ad hoc
>> feature designed to solve a very specific problem -- it would be a
>> core, general purpose rewriting feature baked into the language,
>> which could solve many problems we can't even imagine right now.
>>
>> So in my view, our choice is as follows:
>>
>> 1) Do we add an ad hoc feature to simplify just asynchronous
>> programming, which will make the language more cluttered and not
>> substantially more powerful?
>>
>> 2) Or do we add a powerful rewriting feature (common in functional
>> languages and even scripting languages like Python), based on
>> predictable, deterministic rewrite rules, which simplifies not just
>> asynchronous programming, but many other tasks, giving us list
>> comprehensions, state management, option propagation, and more for free?
>>
>> I've talked to many HaXe programmers about this and I speak for most
>> of them when I say that HaXe + monadic shorthand would seriously kick
>> ass. It would also bring more functional programmers to HaXe, who
>> currently consider HaXe too verbose for true functional programming.
>> And the average person who uses "future comprehensions" or "list
>> comprehensions" doesn't need to understand the rewrite rules, how
>> they work, or what a monad is.
>> Regards,
>>
>> John
>>
>>
>>
>
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

John A. De Goes
In reply to this post by Lee Sylvester

It's nothing like the initial proposal.

Monadic shorthand is rewritten in a deterministic, predictable way into the ordinary method calls 'map', 'flatMap', and 'filter'. Therefore, the feature applies to all monads -- not just "Future" monads. 

Thus, you get list comprehensions (along with lots of other stuff) for free:

var squaredGreaterThan3 = do {
  x <- 0...100;
  if (Math.pow(x, 2) > 3)
} yield x * x;

The above is just sugar for:

var squaredGreaterThan3 = (0...100).filter(function(x) return Math.pow(x, 2) > 3).map(function(e) return e * e);

The feature is not an "asynchronous programming" feature or a "list comprehensions" feature or a "null-safe" feature, etc. (even though it does all that!), but instead, it's a general purpose feature that applies to all structures that have the appropriate methods.

Regards,

John

On Aug 18, 2010, at 4:05 PM, Lee McColl Sylvester wrote:

Isn't this the same as Nicolas's initial proposal? For example:

  var imageFuture: Future<Image> = do {
     data <- urlLoader.load('meta.cfg");
     meta <- new Meta(data);
     imageUrl <- meta.get('backgroundImageUrl');
     image <- urlLoader.load(imageUrl);
  } yield image; // This is Future<Image>


Would be similar to:

      {
           before();
           var data = async->urlLoader.load( 'meta.cfg' );
           var meta = new Meta( data );
           var imageUrl = meta.get( 'backgroundImageUrl' );
           var image = async->urlLoader.load( imageUrl );
           trace( "Done" );
     }
     after();

The async calls are blocking the further execution of the block.

Excuse me if I missed something :-)  I've no familiarity with monadic syntax or futures.

Lee




John A. De Goes wrote:
On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
1) allow access to "this" in local functions, with the same semantic as the following code :

+1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.

2) introduce a short syntax for async programming. Maybe allow something like :

-1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.

There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.

There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.

Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.

Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.

Monadic shorthand in HaXe might look something like this for futures:

   var imageFuture: Future<Image> = do {
      data <- urlLoader.load('meta.cfg");
      meta <- new Meta(data);
      imageUrl <- meta.get('backgroundImageUrl');
      image <- urlLoader.load(imageUrl);
   } yield image; // This is Future<Image>


The same structure would work identically for lists:

   var evenIntegersSquared: List<Int> = do {
     integer <- allIntegers;
     if (integer % 2 == 0)
     squared <- x * x
   } yield squared;

Or any other monads!

This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').

For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.

Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.

So in my view, our choice is as follows:

   1) Do we add an ad hoc feature to simplify just asynchronous
   programming, which will make the language more cluttered and not
   substantially more powerful?

   2) Or do we add a powerful rewriting feature (common in functional
   languages and even scripting languages like Python), based on
   predictable, deterministic rewrite rules, which simplifies not
   just asynchronous programming, but many other tasks, giving us
   list comprehensions, state management, option propagation, and
   more for free?


I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is.
Regards,

John



--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

singmajesty
In reply to this post by Nicolas Cannasse
1.) I think that's a good idea. This surprised me the first time I wrote a  
generic function (while I was testing something). Having to save a "this"  
reference reminds me of parsing XML in Actionscript 1

2.) Working with both HXCPP and Flash, I wish there was an easier way to  
share the same code for bitmaps. I assume I can't use the Embed meta-tag  
(or can I?) for Flash content, so it needs to be loaded asynchronously,  
but with HXCPP it can be loaded directly. Especially when using Flash to  
develop locally, it would be nice to be able to force bitmaps to load  
synchronously in Flash.

Your idea on syntax for asynchronous calls kind of reminds me of how  
transitions work in webOS:


var transition = this.controller.prepareTransition  
(Mojo.Transition.crossFade);

// do stuff

transition.run ();


Once you create the transition instance, the screen is frozen. Everything  
that follows occurs without updating the display, then it transitions to  
whatever state its at when you call transition.run ();

However, if it is a language feature, it obviously wouldn't require any  
instantiation, just so long as the syntax makes enough sense.


var loader:Loader = new Loader ();
addChild (loader);
async.begin (loader.addEventListener, Event.COMPLETE, async.complete);



async.begin ();

var loader:Loader = new Loader ();
addChild (loader);

loader.addEventListener (Event.COMPLETE, function (event:Event):Void {

async.end ();

} );


It might be cool if it could be used as a callback, like in the first  
example, for when you don't have anything else you need to do with an  
async call, other than listening for the callback.




On Wed, 18 Aug 2010 14:33:20 -0700, Nicolas Cannasse  
<[hidden email]> wrote:

>> seems a bit quirky. What's wrong with specifying some form of callback,  
>> even if it's in a tidier syntax? For instance, why not this:
>>  var callback = function() { trace("I'm done"); }
>> before();
>> inst->doSomething()->callback();
>> trace( "may execute before callback" );
>
> Well, the issue with local functions is what that your code is being  
> nested :
>
> inst.wait1(function(a) {
>      inst.wait2(function(b) {
>         inst.wait3(function(c) {
>   trace("Done : "+[a,b,c]);
>         });
>      });
> });
>
> Whereas async calls allow more flat syntax :
>
> var a = inst->wait1();
> var b = inst->wait2();
> var c = inst->wait3();
> trace("Done : "+[a,b,c]);
>
> (please note that this is actually being transformed into local  
> functions by the compiler itself, so both are interchangable).
>
> Nicolas
>


--
Joshua Granick
Owner / Lead Developer
[ eclecticdesignstudio ]
P: (916) 889-7306

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Nicolas Cannasse
In reply to this post by Lee Sylvester
Lee McColl Sylvester a écrit :
> Is this your list to Santa?  Get it in early, buddy. Christmas may
> follow ;-)

It's fine since I don't like to dress in Red ;)

PS : please let's not make this thread a haxe wishlist one, or nothing
constructive will come out of it, please stick to the original subject
which is syntax for functional/async programming.

Nicolas


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Lee Sylvester
lol



Nicolas Cannasse wrote:

> Lee McColl Sylvester a écrit :
>> Is this your list to Santa?  Get it in early, buddy. Christmas may
>> follow ;-)
>
> It's fine since I don't like to dress in Red ;)
>
> PS : please let's not make this thread a haxe wishlist one, or nothing
> constructive will come out of it, please stick to the original subject
> which is syntax for functional/async programming.
>
> Nicolas
>
>


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Justin Donaldson-2
In reply to this post by John A. De Goes
This sounds interesting, but I'm not seeing how would this map onto Nicolas's earlier asynchronous example...
say you have three functions, the latter two which relay on the prior's return:

var a = function(){return 1;}
var b = function(a_result){return a_result+1;}
var c = function(b_result){return b_result+1;}

a();
b(***result from a***);
c(***result from b***);

Assuming a, b, and c all fire asynchronously somehow, How would "do" manage the results and order of operation?

I think "do" syntax is useful.  However, it seems more appropriate for order-insensitive batch operations, rather than for functions which must wait on each other. 


-Justin

On Wed, Aug 18, 2010 at 3:17 PM, John A. De Goes <[hidden email]> wrote:

It's nothing like the initial proposal.

Monadic shorthand is rewritten in a deterministic, predictable way into the ordinary method calls 'map', 'flatMap', and 'filter'. Therefore, the feature applies to all monads -- not just "Future" monads. 

Thus, you get list comprehensions (along with lots of other stuff) for free:

var squaredGreaterThan3 = do {
  x <- 0...100;
  if (Math.pow(x, 2) > 3)
} yield x * x;

The above is just sugar for:

var squaredGreaterThan3 = (0...100).filter(function(x) return Math.pow(x, 2) > 3).map(function(e) return e * e);

The feature is not an "asynchronous programming" feature or a "list comprehensions" feature or a "null-safe" feature, etc. (even though it does all that!), but instead, it's a general purpose feature that applies to all structures that have the appropriate methods.

Regards,

John

On Aug 18, 2010, at 4:05 PM, Lee McColl Sylvester wrote:

Isn't this the same as Nicolas's initial proposal? For example:

  var imageFuture: Future<Image> = do {
     data <- urlLoader.load('meta.cfg");
     meta <- new Meta(data);
     imageUrl <- meta.get('backgroundImageUrl');
     image <- urlLoader.load(imageUrl);
  } yield image; // This is Future<Image>


Would be similar to:

      {
           before();
           var data = async->urlLoader.load( 'meta.cfg' );
           var meta = new Meta( data );
           var imageUrl = meta.get( 'backgroundImageUrl' );
           var image = async->urlLoader.load( imageUrl );
           trace( "Done" );
     }
     after();

The async calls are blocking the further execution of the block.

Excuse me if I missed something :-)  I've no familiarity with monadic syntax or futures.

Lee




John A. De Goes wrote:
On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
1) allow access to "this" in local functions, with the same semantic as the following code :

+1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.

2) introduce a short syntax for async programming. Maybe allow something like :

-1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.

There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.

There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.

Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.

Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.

Monadic shorthand in HaXe might look something like this for futures:

   var imageFuture: Future<Image> = do {
      data <- urlLoader.load('meta.cfg");
      meta <- new Meta(data);
      imageUrl <- meta.get('backgroundImageUrl');
      image <- urlLoader.load(imageUrl);
   } yield image; // This is Future<Image>


The same structure would work identically for lists:

   var evenIntegersSquared: List<Int> = do {
     integer <- allIntegers;
     if (integer % 2 == 0)
     squared <- x * x
   } yield squared;

Or any other monads!

This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').

For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.

Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.

So in my view, our choice is as follows:

   1) Do we add an ad hoc feature to simplify just asynchronous
   programming, which will make the language more cluttered and not
   substantially more powerful?

   2) Or do we add a powerful rewriting feature (common in functional
   languages and even scripting languages like Python), based on
   predictable, deterministic rewrite rules, which simplifies not
   just asynchronous programming, but many other tasks, giving us
   list comprehensions, state management, option propagation, and
   more for free?


I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is.
Regards,

John



--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org



--
blog: http://www.scwn.net
aim: iujjd
twitter: jjdonald


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

MarcWeber
In reply to this post by John A. De Goes
Excerpts from John A. De Goes's message of Wed Aug 18 23:45:15 +0200 2010:
> I've talked to many HaXe programmers about this and I speak for most
> of them when I say that HaXe + monadic shorthand would seriously kick
> ass.
+2.

That's true. Monads could solve this all.

Nicolas: I thought about something like your idea as well


  {                
    before();
    var result = inst->doSomething(); // async call                  
    trace("Done");                                
  }


I'd add this:
- doSomething must return Void.
- doSomething's last parameter must be a function of type: result -> something
- I don't like it because it looks like being usual code - but its not.
  So I'd at least change the = operator to =f or such (f = future)


> It would also bring more functional programmers to HaXe, who currently
> consider HaXe too verbose for true functional programming. And the
> average person who uses "future comprehensions" or "list comprehensions"
> doesn't need to understand the rewrite rules, how they work, or what a
> monad is.
:-) Well. You start liking features like "compiler, give me the type of
this monad / var please - I'm lost.. But you can abuse every technology
to a degree it gets unreadable. This is not going to happen here.

If HaXe wants to stay kick ass and being ahead of time (if something can
be so) then we must have Monads.

Does someone reading the list wants to have see explanations or examples
about how monads are written and used?
I'd like to join efforts with John and work examples out maybe even
proposing implementation details if John wants to do so as well.

If HaXe should stay ahead of time being kick ass we don't have
a choice IMHO. Let's design Monads carefully and go.

I'll start a new thread talking about my newest lambda proposal.

Marc Weber

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Mark de Bruijn | Dykam
Monads are indeed very useful, and I actually imagine they are even very useful in haXe, as it will extend flexibility and enable better custom-domain-languages aswel.
--
Mark


On Wed, Aug 18, 2010 at 11:48 PM, Marc Weber <[hidden email]> wrote:
Excerpts from John A. De Goes's message of Wed Aug 18 23:45:15 +0200 2010:
> I've talked to many HaXe programmers about this and I speak for most
> of them when I say that HaXe + monadic shorthand would seriously kick
> ass.
+2.

That's true. Monads could solve this all.

Nicolas: I thought about something like your idea as well


 {
   before();
   var result = inst->doSomething(); // async call
   trace("Done");
 }


I'd add this:
- doSomething must return Void.
- doSomething's last parameter must be a function of type: result -> something
- I don't like it because it looks like being usual code - but its not.
 So I'd at least change the = operator to =f or such (f = future)


> It would also bring more functional programmers to HaXe, who currently
> consider HaXe too verbose for true functional programming. And the
> average person who uses "future comprehensions" or "list comprehensions"
> doesn't need to understand the rewrite rules, how they work, or what a
> monad is.
:-) Well. You start liking features like "compiler, give me the type of
this monad / var please - I'm lost.. But you can abuse every technology
to a degree it gets unreadable. This is not going to happen here.

If HaXe wants to stay kick ass and being ahead of time (if something can
be so) then we must have Monads.

Does someone reading the list wants to have see explanations or examples
about how monads are written and used?
I'd like to join efforts with John and work examples out maybe even
proposing implementation details if John wants to do so as well.

If HaXe should stay ahead of time being kick ass we don't have
a choice IMHO. Let's design Monads carefully and go.

I'll start a new thread talking about my newest lambda proposal.

Marc Weber

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

MarcWeber
In reply to this post by Nathan
Excerpts from Nathan's message of Thu Aug 19 00:02:38 +0200 2010:
> - allow constants (static var) on interfaces
Is this like traits in Scala then?

> - add a native Object type... which can be for-looped
can't you already do so ? All you have to do is provide hasNext() and
next().  foreach consumes iterator like interfaces. Those two functions
are enough to make it work.

I'm not sure I understood all of your points.
> - define what exceptions a function/method throws (on an interface)
define or derive automatically? (can this be done?)

> - override type of vars via inheritance
Example? Why?

> - package wide constants
What is a wide constant?

> - allow for optional params with (String -> ?Int -> Void) syntax <-ex
How is that different from
(String -> Null<Int> -> Void)

Marc Weber

--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

John A. De Goes
In reply to this post by Justin Donaldson-2

It's quite simple. For some function, asynchMethod that returns a Future<Int>, we can write:

var result: Future<Int> = do {
  a <- asynchMethod();
  b <- a + 1;
  c <- b + 1;
} yield c;

This would be translated by deterministic, predictable rules into the following:

var result: Future<Int> = asynchMethod().map(function(a) return a + 1).map(function(b) return b + 1);

By definition of Future.map, the mapping functions are not executed until the result of the Future is available. Therefore, proper sequencing is guaranteed!

You can already write the above code (not monadic shorthand, but the full expression) using Stax.

Futures makes asynchronous programming quite easy because you can treat results like they're available immediately, even though there may be an indefinite delay between operations.

Regards,

John

On Aug 18, 2010, at 4:46 PM, Justin Donaldson wrote:

This sounds interesting, but I'm not seeing how would this map onto Nicolas's earlier asynchronous example...
say you have three functions, the latter two which relay on the prior's return:

var a = function(){return 1;}
var b = function(a_result){return a_result+1;}
var c = function(b_result){return b_result+1;}

a();
b(***result from a***);
c(***result from b***);

Assuming a, b, and c all fire asynchronously somehow, How would "do" manage the results and order of operation?

I think "do" syntax is useful.  However, it seems more appropriate for order-insensitive batch operations, rather than for functions which must wait on each other. 


-Justin

On Wed, Aug 18, 2010 at 3:17 PM, John A. De Goes <[hidden email]> wrote:

It's nothing like the initial proposal.

Monadic shorthand is rewritten in a deterministic, predictable way into the ordinary method calls 'map', 'flatMap', and 'filter'. Therefore, the feature applies to all monads -- not just "Future" monads. 

Thus, you get list comprehensions (along with lots of other stuff) for free:

var squaredGreaterThan3 = do {
  x <- 0...100;
  if (Math.pow(x, 2) > 3)
} yield x * x;

The above is just sugar for:

var squaredGreaterThan3 = (0...100).filter(function(x) return Math.pow(x, 2) > 3).map(function(e) return e * e);

The feature is not an "asynchronous programming" feature or a "list comprehensions" feature or a "null-safe" feature, etc. (even though it does all that!), but instead, it's a general purpose feature that applies to all structures that have the appropriate methods.

Regards,

John

On Aug 18, 2010, at 4:05 PM, Lee McColl Sylvester wrote:

Isn't this the same as Nicolas's initial proposal? For example:

  var imageFuture: Future<Image> = do {
     data <- urlLoader.load('meta.cfg");
     meta <- new Meta(data);
     imageUrl <- meta.get('backgroundImageUrl');
     image <- urlLoader.load(imageUrl);
  } yield image; // This is Future<Image>


Would be similar to:

      {
           before();
           var data = async->urlLoader.load( 'meta.cfg' );
           var meta = new Meta( data );
           var imageUrl = meta.get( 'backgroundImageUrl' );
           var image = async->urlLoader.load( imageUrl );
           trace( "Done" );
     }
     after();

The async calls are blocking the further execution of the block.

Excuse me if I missed something :-)  I've no familiarity with monadic syntax or futures.

Lee




John A. De Goes wrote:
On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
1) allow access to "this" in local functions, with the same semantic as the following code :

+1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.

2) introduce a short syntax for async programming. Maybe allow something like :

-1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.

There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.

There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.

Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.

Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.

Monadic shorthand in HaXe might look something like this for futures:

   var imageFuture: Future<Image> = do {
      data <- urlLoader.load('meta.cfg");
      meta <- new Meta(data);
      imageUrl <- meta.get('backgroundImageUrl');
      image <- urlLoader.load(imageUrl);
   } yield image; // This is Future<Image>


The same structure would work identically for lists:

   var evenIntegersSquared: List<Int> = do {
     integer <- allIntegers;
     if (integer % 2 == 0)
     squared <- x * x
   } yield squared;

Or any other monads!

This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').

For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.

Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.

So in my view, our choice is as follows:

   1) Do we add an ad hoc feature to simplify just asynchronous
   programming, which will make the language more cluttered and not
   substantially more powerful?

   2) Or do we add a powerful rewriting feature (common in functional
   languages and even scripting languages like Python), based on
   predictable, deterministic rewrite rules, which simplifies not
   just asynchronous programming, but many other tasks, giving us
   list comprehensions, state management, option propagation, and
   more for free?


I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is.
Regards,

John



--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org



--
blog: http://www.scwn.net
aim: iujjd
twitter: jjdonald

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org
Reply | Threaded
Open this post in threaded view
|

Re: Async Programming

Justin Donaldson-2
Does it look something like this with the current syntax?

import Prelude;
class Test {

    public static function main(){
        var asynchMethod = function(){
            var k = new Future<Int>();
            k.deliver(4);
            return k;
        }
        var result: Future<Int> = asynchMethod().map(function(a) return a + 1).map(function(b) return b + 1);
        trace(result.value());

    }
}






On Wed, Aug 18, 2010 at 3:56 PM, John A. De Goes <[hidden email]> wrote:

It's quite simple. For some function, asynchMethod that returns a Future<Int>, we can write:

var result: Future<Int> = do {
  a <- asynchMethod();
  b <- a + 1;
  c <- b + 1;
} yield c;

This would be translated by deterministic, predictable rules into the following:

var result: Future<Int> = asynchMethod().map(function(a) return a + 1).map(function(b) return b + 1);

By definition of Future.map, the mapping functions are not executed until the result of the Future is available. Therefore, proper sequencing is guaranteed!

You can already write the above code (not monadic shorthand, but the full expression) using Stax.

Futures makes asynchronous programming quite easy because you can treat results like they're available immediately, even though there may be an indefinite delay between operations.

Regards,

John

On Aug 18, 2010, at 4:46 PM, Justin Donaldson wrote:

This sounds interesting, but I'm not seeing how would this map onto Nicolas's earlier asynchronous example...
say you have three functions, the latter two which relay on the prior's return:

var a = function(){return 1;}
var b = function(a_result){return a_result+1;}
var c = function(b_result){return b_result+1;}

a();
b(***result from a***);
c(***result from b***);

Assuming a, b, and c all fire asynchronously somehow, How would "do" manage the results and order of operation?

I think "do" syntax is useful.  However, it seems more appropriate for order-insensitive batch operations, rather than for functions which must wait on each other. 


-Justin

On Wed, Aug 18, 2010 at 3:17 PM, John A. De Goes <[hidden email]> wrote:

It's nothing like the initial proposal.

Monadic shorthand is rewritten in a deterministic, predictable way into the ordinary method calls 'map', 'flatMap', and 'filter'. Therefore, the feature applies to all monads -- not just "Future" monads. 

Thus, you get list comprehensions (along with lots of other stuff) for free:

var squaredGreaterThan3 = do {
  x <- 0...100;
  if (Math.pow(x, 2) > 3)
} yield x * x;

The above is just sugar for:

var squaredGreaterThan3 = (0...100).filter(function(x) return Math.pow(x, 2) > 3).map(function(e) return e * e);

The feature is not an "asynchronous programming" feature or a "list comprehensions" feature or a "null-safe" feature, etc. (even though it does all that!), but instead, it's a general purpose feature that applies to all structures that have the appropriate methods.

Regards,

John

On Aug 18, 2010, at 4:05 PM, Lee McColl Sylvester wrote:

Isn't this the same as Nicolas's initial proposal? For example:

  var imageFuture: Future<Image> = do {
     data <- urlLoader.load('meta.cfg");
     meta <- new Meta(data);
     imageUrl <- meta.get('backgroundImageUrl');
     image <- urlLoader.load(imageUrl);
  } yield image; // This is Future<Image>


Would be similar to:

      {
           before();
           var data = async->urlLoader.load( 'meta.cfg' );
           var meta = new Meta( data );
           var imageUrl = meta.get( 'backgroundImageUrl' );
           var image = async->urlLoader.load( imageUrl );
           trace( "Done" );
     }
     after();

The async calls are blocking the further execution of the block.

Excuse me if I missed something :-)  I've no familiarity with monadic syntax or futures.

Lee




John A. De Goes wrote:
On Aug 18, 2010, at 3:10 PM, Nicolas Cannasse wrote:
1) allow access to "this" in local functions, with the same semantic as the following code :

+1. This will eliminate a lot of boilerplate code ('var self = this;'). The current limitations of local functions are very confusing to developers who are new to HaXe.

2) introduce a short syntax for async programming. Maybe allow something like :

-1. This is an ad hoc feature designed to solve a very specific problem, and making it work across platforms with a billion different syntaxes for callbacks will be difficult. HaXe will grow cluttered if too many ad hoc features are added.

There is already a powerful concept for asynchronous programming called a "Future". However, it's a little clumsy to use Futures because of the verbose lambda syntax.

There's an alternative to a shorter lambda syntax that would tremendously improve the power of the HaXe language.

Future's form a monad (flatMap and 'unit'). So if HaXe had a syntax for compactly interacting with monads, it would be useful not just for Futures, but for all monads -- lists, options, state, etc. Therefore, instead of adding a feature specific to support just asynchronous programming, I suggest adding syntactic sugar for monads. This will keep HaXe from acquiring too many ad hoc features that only solve very specific problems.

Many people have asked for "list comprehensions". In fact, monadic shorthand is exactly what is needed for "list comprehensions", "easy asynchronous programming", "easy option programming", and much more. We can bring the power of all these to the language with a single general purpose feature that merely adds syntactic sugar.

Monadic shorthand in HaXe might look something like this for futures:

   var imageFuture: Future<Image> = do {
      data <- urlLoader.load('meta.cfg");
      meta <- new Meta(data);
      imageUrl <- meta.get('backgroundImageUrl');
      image <- urlLoader.load(imageUrl);
   } yield image; // This is Future<Image>


The same structure would work identically for lists:

   var evenIntegersSquared: List<Int> = do {
     integer <- allIntegers;
     if (integer % 2 == 0)
     squared <- x * x
   } yield squared;

Or any other monads!

This syntax is very similar to Haskell, Scala, and list comprehensions in other languages (although if you don't like this syntax, there are plenty of others to choose from). The above is rewritten by the compiler into combinations of map, flatMap, and filter (if a conditional is used) -- therefore, it works not just for library classes that have these methods, but also for user-defined classes that have these methods (and even enums and such, which have the corresponding extension methods with 'using').

For exact rewrite rules, see Daniel's response at: http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield.

Stax already has futures, options, and other monads. They're better than the alternatives, but with monadic notation, they would be a real pleasure to use. And monadic notation would not be an ad hoc feature designed to solve a very specific problem -- it would be a core, general purpose rewriting feature baked into the language, which could solve many problems we can't even imagine right now.

So in my view, our choice is as follows:

   1) Do we add an ad hoc feature to simplify just asynchronous
   programming, which will make the language more cluttered and not
   substantially more powerful?

   2) Or do we add a powerful rewriting feature (common in functional
   languages and even scripting languages like Python), based on
   predictable, deterministic rewrite rules, which simplifies not
   just asynchronous programming, but many other tasks, giving us
   list comprehensions, state management, option propagation, and
   more for free?


I've talked to many HaXe programmers about this and I speak for most of them when I say that HaXe + monadic shorthand would seriously kick ass. It would also bring more functional programmers to HaXe, who currently consider HaXe too verbose for true functional programming. And the average person who uses "future comprehensions" or "list comprehensions" doesn't need to understand the rewrite rules, how they work, or what a monad is.
Regards,

John



--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org



--
blog: http://www.scwn.net
aim: iujjd
twitter: jjdonald

--
haXe - an open source web programming language
http://haxe.org


--
haXe - an open source web programming language
http://haxe.org



--
blog: http://www.scwn.net
aim: iujjd
twitter: jjdonald


--
haXe - an open source web programming language
http://haxe.org
12345