Promise API

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Promise API

Herby Vojčík
Hello!

I have found a few APIs for Promise/Future thing in other Smalltalks,
but they were all synchronous, based on green threads and locking
(obviously). I found none that would capture the asynchronous nature of
JS Promises.

So, first question, if you know of an established API for asynchronous
Promises for Smalltalk, let me know.

Second, I would like you to comment this proposal for Promise class that
wraps the native (or polyfilled, but aimed at the native ES2015 one) JS
Promise class (it's API consists of new Promise, Promise.all,
Promise.race, Promise.resolve, Promise.reject, aPromise.then and
aPromise.catch):

Object >> asPromise
   "returns a Promise resolved to self"
   <return JS_Promise.resolve(self)>

Promise class >> forBlock: aBlock
   "Inspired by GNU Smalltalk API.
   Returns a Promise fulfilled or rejected by `aBlock value`.
   Only usable for synchronous operations in aBlock."
   <return JS_Promise.resolve().then(function () {return aBlock._value()})>

Promise class >> asyncForBlock: aBlock
   "aBlock is called with two parameters,
   first being setValue (aka resolve) block,
   second being setError (aka reject) block.
   Returns a Promise that eventually
   succeeds or fails, asynchronously."
   <return new JS_Promise(function (resolve, reject) {
     return aBlock._value_value_(resolve, reject);
   })>

Promise class >> all: aCollection
   "Returns a collection that succeeds
   when all promises in aCollection succeed.
   It is resolved with array of their results."
   <return JS_Promise.all(aCollection._asArray())>

Promise class >> any: aCollection
   "Returns a collection that succeeds
   when any of the promises in aCollection succeed.
   It is resolved with result of the first one that resolves."
   <return JS_Promise.all(aCollection._asArray())>

Promise >> newChain
   "Returns new PromiseHandlerChain for self."

PromiseHandlerChain >> asPromise
   "Returns a promise that self represents."
   ^ promise

PromiseHandlerChain >> ifValue: aBlock
   "Chains aBlock to process successful value.
   Passes return value / error of aBlock down the chain."
   <self["@promise"] = self["@promise"].then(
     function (x) { return aBlock._value(x); }
   )>

PromiseHandlerChain >> ifError: aBlock
   "Chains aBlock to process error.
   Passes return value / error of aBlock down the chain."
   <self["@promise"] = self["@promise"].catch(
     function (x) { return aBlock._value(x); }
   )>

PromiseHandlerChain >> ifValue: aBlock ifError: anotherBlock
   "Chains aBlock to process successful value
   and anotherBlock to process error value.
   Passes return value / error of respective block down the chain."
   <self["@promise"] = self["@promise"].then(
     function (x) { return aBlock._value(x); },
     function (x) { return anotherBlock._value(x); }
   )>

As you can see, Promise.reject API is not wrapped, but I don't think
it's needed than often and can always be done with `Promise forBlock: [
errorValue signal ]` (at least I hope).

I used the PromiseHandlerChain class so that one can chain JS .then and
.catch handler nicely in Smalltalk itself. If I just wrapped .then and
.catch calls, lots of parenthesising would be needed, but with this, it
is just something like:

   (fetch value: url) newChain
     ifValue: [ :data | JSON parse: data ];
     ifValue: [ :parsed |
       parsed at: #id ifAbsent: [ Error signal: "Missing name."].
       parsed ];
     ...;
     ifError: [ :e | self handleError: e ofUrl: url ].

And if you wanted to hold to the promise _with_ the handlers attached,
you would just end the chain with asPromise.

Opinions?

Thanks, Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippe.back@highoctane.be

How would .all works in  the example?

Phil

On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]> wrote:
Hello!

I have found a few APIs for Promise/Future thing in other Smalltalks, but they were all synchronous, based on green threads and locking (obviously). I found none that would capture the asynchronous nature of JS Promises.

So, first question, if you know of an established API for asynchronous Promises for Smalltalk, let me know.

Second, I would like you to comment this proposal for Promise class that wraps the native (or polyfilled, but aimed at the native ES2015 one) JS Promise class (it's API consists of new Promise, Promise.all, Promise.race, Promise.resolve, Promise.reject, aPromise.then and aPromise.catch):

Object >> asPromise
  "returns a Promise resolved to self"
  <return JS_Promise.resolve(self)>

Promise class >> forBlock: aBlock
  "Inspired by GNU Smalltalk API.
  Returns a Promise fulfilled or rejected by `aBlock value`.
  Only usable for synchronous operations in aBlock."
  <return JS_Promise.resolve().then(function () {return aBlock._value()})>

Promise class >> asyncForBlock: aBlock
  "aBlock is called with two parameters,
  first being setValue (aka resolve) block,
  second being setError (aka reject) block.
  Returns a Promise that eventually
  succeeds or fails, asynchronously."
  <return new JS_Promise(function (resolve, reject) {
    return aBlock._value_value_(resolve, reject);
  })>

Promise class >> all: aCollection
  "Returns a collection that succeeds
  when all promises in aCollection succeed.
  It is resolved with array of their results."
  <return JS_Promise.all(aCollection._asArray())>

Promise class >> any: aCollection
  "Returns a collection that succeeds
  when any of the promises in aCollection succeed.
  It is resolved with result of the first one that resolves."
  <return JS_Promise.all(aCollection._asArray())>

Promise >> newChain
  "Returns new PromiseHandlerChain for self."

PromiseHandlerChain >> asPromise
  "Returns a promise that self represents."
  ^ promise

PromiseHandlerChain >> ifValue: aBlock
  "Chains aBlock to process successful value.
  Passes return value / error of aBlock down the chain."
  <self["@promise"] = self["@promise"].then(
    function (x) { return aBlock._value(x); }
  )>

PromiseHandlerChain >> ifError: aBlock
  "Chains aBlock to process error.
  Passes return value / error of aBlock down the chain."
  <self["@promise"] = self["@promise"].catch(
    function (x) { return aBlock._value(x); }
  )>

PromiseHandlerChain >> ifValue: aBlock ifError: anotherBlock
  "Chains aBlock to process successful value
  and anotherBlock to process error value.
  Passes return value / error of respective block down the chain."
  <self["@promise"] = self["@promise"].then(
    function (x) { return aBlock._value(x); },
    function (x) { return anotherBlock._value(x); }
  )>

As you can see, Promise.reject API is not wrapped, but I don't think it's needed than often and can always be done with `Promise forBlock: [ errorValue signal ]` (at least I hope).

I used the PromiseHandlerChain class so that one can chain JS .then and .catch handler nicely in Smalltalk itself. If I just wrapped .then and .catch calls, lots of parenthesising would be needed, but with this, it is just something like:

  (fetch value: url) newChain
    ifValue: [ :data | JSON parse: data ];
    ifValue: [ :parsed |
      parsed at: #id ifAbsent: [ Error signal: "Missing name."].
      parsed ];
    ...;
    ifError: [ :e | self handleError: e ofUrl: url ].

And if you wanted to hold to the promise _with_ the handlers attached, you would just end the chain with asPromise.

Opinions?

Thanks, Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:
> How would .all works in  the example?

Something like:

   (Promise all: {
     (fetch value: userDataUrl) newChain
       ifValue: [ :data | JSON parse: data ];
       asPromise.
     (fetch value: cartUrl) newChain
       ifValue: [ :data | JSON parse: data ];
       asPromise
   }) newChain
     ifValue: [ :array | | user cart |
       user := array first.
       cart := array second.
       "Do something" ];
     ifError: [ :e | self handleError: e ]

At least with this implementation where it simply wraps JS .all call.
Maybe there should be some easing in the API. For example, collect:
#asPromise may be called on the array prior to passing it to native
.all. And / or there should be an API for all:and:, all:and:and:,
either:or:, either:or:or:, ...

> Phil
>
> On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Promise class >> asyncForBlock: aBlock
>     "aBlock is called with two parameters,
>        first being setValue (aka resolve) block,
>        second being setError (aka reject) block.
>        Returns a Promise that eventually
>        succeeds or fails, asynchronously."
>     <return new JS_Promise(function (resolve, reject) {
>          return aBlock._value_value_(resolve, reject);
>        })>

Also, here the `new Promise` is naively wrapped. There should proabably
be helper object (PromiseValueModel) passed into the block, so that you
don't need to do `Promise asyncForBlock: [ :good :bad | good value: 3
]`, resp. `Promise asyncForBlock: [ :good :bad | bad value: 10 ]` but
instead `Promise asyncForBlock: [ :model | model value: 3 ]` or `Promise
asyncForBlock: [ :model | model signal: 10 ]`

Overall, I am aiming at achieving "Smalltalk-feeling" API.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippe.back@highoctane.be

I see.

Need to try this out on a real case to see how it goes.

Thx for making this!

On Jan 25, 2016 3:36 PM, "Herby Vojčík" <[hidden email]> wrote:


[hidden email] wrote:
How would .all works in  the example?

Something like:

  (Promise all: {
    (fetch value: userDataUrl) newChain
      ifValue: [ :data | JSON parse: data ];
      asPromise.
    (fetch value: cartUrl) newChain
      ifValue: [ :data | JSON parse: data ];
      asPromise
  }) newChain
    ifValue: [ :array | | user cart |
      user := array first.
      cart := array second.
      "Do something" ];
    ifError: [ :e | self handleError: e ]

At least with this implementation where it simply wraps JS .all call. Maybe there should be some easing in the API. For example, collect: #asPromise may be called on the array prior to passing it to native .all. And / or there should be an API for all:and:, all:and:and:, either:or:, either:or:or:, ...

Phil

On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]
<mailto:[hidden email]>> wrote:

    Promise class >> asyncForBlock: aBlock
    "aBlock is called with two parameters,
       first being setValue (aka resolve) block,
       second being setError (aka reject) block.
       Returns a Promise that eventually
       succeeds or fails, asynchronously."
    <return new JS_Promise(function (resolve, reject) {
         return aBlock._value_value_(resolve, reject);
       })>

Also, here the `new Promise` is naively wrapped. There should proabably be helper object (PromiseValueModel) passed into the block, so that you don't need to do `Promise asyncForBlock: [ :good :bad | good value: 3 ]`, resp. `Promise asyncForBlock: [ :good :bad | bad value: 10 ]` but instead `Promise asyncForBlock: [ :model | model value: 3 ]` or `Promise asyncForBlock: [ :model | model signal: 10 ]`

Overall, I am aiming at achieving "Smalltalk-feeling" API.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:
> I see.
>
> Need to try this out on a real case to see how it goes.
>
> Thx for making this!

I did not _make_ it yet. It's just the sketch of API, there is not real code (except where it was trivial, I included it).

> On Jan 25, 2016 3:36 PM, "Herby Vojčík" <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>
>
>     [hidden email] <mailto:[hidden email]>
>     wrote:
>
>         How would .all works in  the example?
>
>
>     Something like:
>
>       (Promise all: {
>         (fetch value: userDataUrl) newChain
>           ifValue: [ :data | JSON parse: data ];
>           asPromise.
>         (fetch value: cartUrl) newChain
>           ifValue: [ :data | JSON parse: data ];
>           asPromise
>       }) newChain
>         ifValue: [ :array | | user cart |
>           user := array first.
>           cart := array second.
>     "Do something" ];
>         ifError: [ :e | self handleError: e ]
>
>  
   At least with this implementation where it simply wraps JS .all

>     call. Maybe there should be some easing in the API. For example,
>     collect: #asPromise may be called on the array prior to passing it
>     to native .all. And / or there should be an API for all:and:,
>     all:and:and:, either:or:, either:or:or:, ...
>
>         Phil
>
>         On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]
>         <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>
>             Promise class >> asyncForBlock: aBlock
>         "aBlock is called with two parameters,
>                first being setValue (aka resolve) block,
>                second being setError (aka reject) block.
>                Returns a Promise that eventually
>                succeeds or fails, asynchronously."
>         <return new JS_Promise(function (resolve, reject) {
>                  return aBlock._value_value_(resolve, reject);
>          
     })>

>
>
>     Also, here the `new Promise` is naively wrapped. There should
>     proabably be helper object (PromiseValueModel) passed into the
>     block, so that you don't need to do `Promise asyncForBlock: [
>     :good :bad | good value: 3 ]`, resp. `Promise asyncForBlock: [
>     :good :bad | bad value: 10 ]` but instead `Promise asyncForBlock:
>     [ :model | model value: 3 ]` or `Promise asyncForBlock: [ :model |
>     model signal: 10 ]`
>
>     Overall, I am aiming at achieving "Smalltalk-feeling" API.
>
>     Herby
>
>     --
>     You received this message because you are subscribed to the Google
>     Groups "amber-lang" group.
>     To unsubscribe from this group and stop receiving emails from it,
>     send an email to [hidden email]
>     <mailto:amber-lang%[hidden email]>.
>     For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Goog
le
> Groups "amber-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email]
> <mailto:[hidden email]>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
Ok.

Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is more Smalltalkish than newChain onSuccess: aBloc onError: aBlock.

The async promises style is quite JS specific in the way it works today in browsers and node.
Wouldn't it be better (in the marketing sense) to mimic that instead of going the way of ifTrue: ifFalse: style?

With exceptions, we have on BlockClosure (in Pharo):

aBlock on: exception do: handlerAction.

aBlock ifError: errorHandlerBlock

Looking in Announcement (amongst others), there we have when: anEvent do: aBlock (the on: anEvent do: aBlock being deprectated).

ifValue: is not intention revealing to me when looking to the newChain thing. 

But then, is 

     newChain ifValue: [ :value | ... ] 

making more sense than:

    newChain onSuccess: [ :data | ... ]

I'd say that the onSuccess: idiom makes it easier to add other event types than ifValue:  

Names don't come easy...

Best,
Phil







On Mon, Jan 25, 2016 at 4:10 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
I see.

Need to try this out on a real case to see how it goes.

Thx for making this!

I did not _make_ it yet. It's just the sketch of API, there is not real code (except where it was trivial, I included it).

On Jan 25, 2016 3:36 PM, "Herby Vojčík" <[hidden email] <mailto:[hidden email]>> wrote:



    [hidden email] <mailto:[hidden email]>
    wrote:

        How would .all works in  the example?


    Something like:

      (Promise all: {
        (fetch value: userDataUrl) newChain
          ifValue: [ :data | JSON parse: data ];
          asPromise.
        (fetch value: cartUrl) newChain
          ifValue: [ :data | JSON parse: data ];
          asPromise
      }) newChain
        ifValue: [ :array | | user cart |
          user := array first.
          cart := array second.
    "Do something" ];
        ifError: [ :e | self handleError: e ]

 
  At least with this implementation where it simply wraps JS .all
    call. Maybe there should be some easing in the API. For example,
    collect: #asPromise may be called on the array prior to passing it
    to native .all. And / or there should be an API for all:and:,
    all:and:and:, either:or:, either:or:or:, ...

        Phil

        On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]
        <mailto:[hidden email]>
        <mailto:[hidden email] <mailto:[hidden email]>>> wrote:

            Promise class >> asyncForBlock: aBlock
        "aBlock is called with two parameters,
               first being setValue (aka resolve) block,
               second being setError (aka reject) block.
               Returns a Promise that eventually
               succeeds or fails, asynchronously."
        <return new JS_Promise(function (resolve, reject) {
                 return aBlock._value_value_(resolve, reject);
         
    })>


    Also, here the `new Promise` is naively wrapped. There should
    proabably be helper object (PromiseValueModel) passed into the
    block, so that you don't need to do `Promise asyncForBlock: [
    :good :bad | good value: 3 ]`, resp. `Promise asyncForBlock: [
    :good :bad | bad value: 10 ]` but instead `Promise asyncForBlock:
    [ :model | model value: 3 ]` or `Promise asyncForBlock: [ :model |
    model signal: 10 ]`

    Overall, I am aiming at achieving "Smalltalk-feeling" API.

    Herby

    --     You received this message because you are subscribed to the Google
    Groups "amber-lang" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [hidden email]
    <mailto:[hidden email]>.
    For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Goog
le
Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email] <mailto:[hidden email]>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:
> Ok.
>
> Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is more
> Smalltalkish than newChain onSuccess: aBloc onError: aBlock.

I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty:
families. I would really want to know which message is capturing the
spirit of Smalltalk best way.

> The async promises style is quite JS specific in the way it works today
> in browsers and node.

It will work this way for some time, though, as it is part of ES2015
spec. If TC39 spirit of "don't break the Web" persist, then forever. ;-)
And as far as I can tell, implementing "synchronous" pattern used in
other Smalltalks is not feasible (the whole Amber would need to include
its own green thread simulator).

> Wouldn't it be better (in the marketing sense) to mimic that instead of
> going the way of ifTrue: ifFalse: style?

I want to stay true to Smalltalk style. I care much more for consistency
(and some pedagogical value) then short-term marketing. That said, I
started this thread to get feedback on precisely that - what API would
look most natural for Smalltalk.

> With exceptions, we have on BlockClosure (in Pharo):
>
> aBlock on: exception do: handlerAction.
>
> aBlock ifError: errorHandlerBlock
>
> Looking in Announcement (amongst others), there we have when: anEvent
> do: aBlock (the on: anEvent do: aBlock being deprectated).
>
> ifValue: is not intention revealing to me when looking to the newChain
> thing.

Could you elaborate more?

Would ifOk:ifError: be better?

> But then, is
>
>       newChain ifValue: [ :value | ... ]
>
> making more sense than:
>
>      newChain onSuccess: [ :data | ... ]
>
> I'd say that the onSuccess: idiom makes it easier to add other event
> types than ifValue:

I don't know if there will be ones... the native API tries to be minimal.

> Names don't come easy...
>
> Best,
> Phil

Yeah.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
x newChain ifSuccess: [:data | ...  ] ifError: [ ... ] may be closer IMHO.

BTW, is the ifSuccess: block monadic only? What about ifError: ?

Best,
Phil


On Mon, Jan 25, 2016 at 10:04 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
Ok.

Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is more
Smalltalkish than newChain onSuccess: aBloc onError: aBlock.

I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty: families. I would really want to know which message is capturing the spirit of Smalltalk best way.

The async promises style is quite JS specific in the way it works today
in browsers and node.

It will work this way for some time, though, as it is part of ES2015 spec. If TC39 spirit of "don't break the Web" persist, then forever. ;-) And as far as I can tell, implementing "synchronous" pattern used in other Smalltalks is not feasible (the whole Amber would need to include its own green thread simulator).

Wouldn't it be better (in the marketing sense) to mimic that instead of
going the way of ifTrue: ifFalse: style?

I want to stay true to Smalltalk style. I care much more for consistency (and some pedagogical value) then short-term marketing. That said, I started this thread to get feedback on precisely that - what API would look most natural for Smalltalk.

With exceptions, we have on BlockClosure (in Pharo):

aBlock on: exception do: handlerAction.

aBlock ifError: errorHandlerBlock

Looking in Announcement (amongst others), there we have when: anEvent
do: aBlock (the on: anEvent do: aBlock being deprectated).

ifValue: is not intention revealing to me when looking to the newChain
thing.

Could you elaborate more?

Would ifOk:ifError: be better?

But then, is

      newChain ifValue: [ :value | ... ]

making more sense than:

     newChain onSuccess: [ :data | ... ]

I'd say that the onSuccess: idiom makes it easier to add other event
types than ifValue:

I don't know if there will be ones... the native API tries to be minimal.

Names don't come easy...

Best,
Phil

Yeah.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
In reply to this post by Herby Vojčík
x newChain ifSuccess: [:data | ...  ] ifError: [ ... ] may be closer IMHO.

BTW, is the ifSuccess: block monadic only? What about ifError: ?

Best,
Phil


On Mon, Jan 25, 2016 at 10:04 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
Ok.

Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is more
Smalltalkish than newChain onSuccess: aBloc onError: aBlock.

I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty: families. I would really want to know which message is capturing the spirit of Smalltalk best way.

The async promises style is quite JS specific in the way it works today
in browsers and node.

It will work this way for some time, though, as it is part of ES2015 spec. If TC39 spirit of "don't break the Web" persist, then forever. ;-) And as far as I can tell, implementing "synchronous" pattern used in other Smalltalks is not feasible (the whole Amber would need to include its own green thread simulator).

Wouldn't it be better (in the marketing sense) to mimic that instead of
going the way of ifTrue: ifFalse: style?

I want to stay true to Smalltalk style. I care much more for consistency (and some pedagogical value) then short-term marketing. That said, I started this thread to get feedback on precisely that - what API would look most natural for Smalltalk.

With exceptions, we have on BlockClosure (in Pharo):

aBlock on: exception do: handlerAction.

aBlock ifError: errorHandlerBlock

Looking in Announcement (amongst others), there we have when: anEvent
do: aBlock (the on: anEvent do: aBlock being deprectated).

ifValue: is not intention revealing to me when looking to the newChain
thing.

Could you elaborate more?

Would ifOk:ifError: be better?

But then, is

      newChain ifValue: [ :value | ... ]

making more sense than:

     newChain onSuccess: [ :data | ... ]

I'd say that the onSuccess: idiom makes it easier to add other event
types than ifValue:

I don't know if there will be ones... the native API tries to be minimal.

Names don't come easy...

Best,
Phil

Yeah.

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík
In reply to this post by philippeback


Dňa 25. januára 2016 23:31:12 CET používateľ "[hidden email]" <[hidden email]> napísal:
>x newChain ifSuccess: [:data | ...  ] ifError: [ ... ] may be closer
>IMHO.

Ok.

>BTW, is the ifSuccess: block monadic only? What about ifError: ?

Yes, both only accept one value, as JS native promises are only resolved/rejected with one value (which is an array in case of Promise.all; for that case, single ifSuccesses: can be created that spreads the array to arguments od the block).

>Best,
>Phil
>
>
>On Mon, Jan 25, 2016 at 10:04 PM, Herby Vojčík <[hidden email]>
>wrote:
>
>>
>>
>> [hidden email] wrote:
>>
>>> Ok.
>>>
>>> Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is
>more
>>> Smalltalkish than newChain onSuccess: aBloc onError: aBlock.
>>>
>>
>> I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty:
>> families. I would really want to know which message is capturing the
>spirit
>> of Smalltalk best way.
>>
>> The async promises style is quite JS specific in the way it works
>today
>>> in browsers and node.
>>>
>>
>> It will work this way for some time, though, as it is part of ES2015
>spec.
>> If TC39 spirit of "don't break the Web" persist, then forever. ;-)
>And as
>> far as I can tell, implementing "synchronous" pattern used in other
>> Smalltalks is not feasible (the whole Amber would need to include its
>own
>> green thread simulator).
>>
>> Wouldn't it be better (in the marketing sense) to mimic that instead
>of
>>> going the way of ifTrue: ifFalse: style?
>>>
>>
>> I want to stay true to Smalltalk style. I care much more for
>consistency
>> (and some pedagogical value) then short-term marketing. That said, I
>> started this thread to get feedback on precisely that - what API
>would look
>> most natural for Smalltalk.
>>
>> With exceptions, we have on BlockClosure (in Pharo):
>>>
>>> aBlock on: exception do: handlerAction.
>>>
>>> aBlock ifError: errorHandlerBlock
>>>
>>> Looking in Announcement (amongst others), there we have when:
>anEvent
>>> do: aBlock (the on: anEvent do: aBlock being deprectated).
>>>
>>> ifValue: is not intention revealing to me when looking to the
>newChain
>>> thing.
>>>
>>
>> Could you elaborate more?
>>
>> Would ifOk:ifError: be better?
>>
>> But then, is
>>>
>>>       newChain ifValue: [ :value | ... ]
>>>
>>> making more sense than:
>>>
>>>      newChain onSuccess: [ :data | ... ]
>>>
>>> I'd say that the onSuccess: idiom makes it easier to add other event
>>> types than ifValue:
>>>
>>
>> I don't know if there will be ones... the native API tries to be
>minimal.
>>
>> Names don't come easy...
>>>
>>> Best,
>>> Phil
>>>
>>
>> Yeah.
>>
>> Herby
>>
>> --
>> You received this message because you are subscribed to the Google
>Groups
>> "amber-lang" group.
>> To unsubscribe from this group and stop receiving emails from it,
>send an
>> email to [hidden email].
>> For more options, visit https://groups.google.com/d/optout.
>>

--
Odoslané z môjho Android zariadenia pomocou K-9 Mail.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


Herby Vojčík wrote:
>
> Dňa 25. januára 2016 23:31:12 CET používateľ "[hidden email]"<[hidden email]>  napísal:
>> x newChain ifSuccess: [:data | ...  ] ifError: [ ... ] may be closer
>> IMHO.
>
> Ok.

Giving this second thought.

Primo, #ifSuccess: / #onSuccess: wording gives the impression that
promise is a "process" that can succeed. Even if it is,
implementation-wise, its semantic is different - it is a value which is
not accessible immediately, but ultimately will (or something may break
in the way).

So, #ifValue: tried to reflect this semantics.

Maybe #ifPresent:ifError: could grasp it better. Or something similar,
that hints on it as a 'future value' not a 'process with result'.

Secundo, #ifXxx:ifAlternativeToXxx: families of messages are all
executed immediately. So, for promise, they should not be used.
Something like #whenPresent:whenFailed: may be less misleading.

Tertio, there is grawlixy binary op option here as well, which I did not
though of. This allows natural chaining, possibly wrapping directly
.then and .catch API, without need of newChain, like in:

   (fetch value: url)
     ++ [ :data | JSON parse: data ]
     ++ [ :parsed |
       parsed at: #id ifAbsent: [ Error signal: "Missing name."].
       parsed ]
     ...
     -- [ :e | self handleError: e ofUrl: url ].

(there may be a +++ for accepting an array into parameters when all: is
used, even +- [ :error :value | ... ] to wrap two-param .then).

>> BTW, is the ifSuccess: block monadic only? What about ifError: ?
>
> Yes, both only accept one value, as JS native promises are only resolved/rejected with one value (which is an array in case of Promise.all; for that case, single ifSuccesses: can be created that spreads the array to arguments od the block).
>
>> Best,
>> Phil
>>
>>
>> On Mon, Jan 25, 2016 at 10:04 PM, Herby Vojčík<[hidden email]>
>> wrote:
>>
>>>
>>> [hidden email] wrote:
>>>
>>>> Ok.
>>>>
>>>> Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is
>> more
>>>> Smalltalkish than newChain onSuccess: aBloc onError: aBlock.
>>>>
>>> I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty:
>>> families. I would really want to know which message is capturing the
>> spirit
>>> of Smalltalk best way.
>>>
>>> The async promises style is quite JS specific in the way it works
>> today
>>>> in browsers and node.
>>>>
>>> It will work this way for some time, though, as it is part of ES2015
>> spec.
>>> If TC39 spirit of "don't break the Web" persist, then forever. ;-)
>> And as
>>> far as I can tell, implementing "synchronous" pattern used in other
>>> Smalltalks is not feasible (the whole Amber would need to include its
>> own
>>> green thread simulator).
>>>
>>> Wouldn't it be better (in the marketing sense) to mimic that instead
>> of
>>>> going the way of ifTrue: ifFalse: style?
>>>>
>>> I want to stay true to Smalltalk style. I care much more for
>> consistency
>>> (and some pedagogical value) then short-term marketing. That said, I
>>> started this thread to get feedback on precisely that - what API
>> would look
>>> most natural for Smalltalk.
>>>
>>> With exceptions, we have on BlockClosure (in Pharo):
>>>> aBlock on: exception do: handlerAction.
>>>>
>>>> aBlock ifError: errorHandlerBlock
>>>>
>>>> Looking in Announcement (amongst others), there we have when:
>> anEvent
>>>> do: aBlock (the on: anEvent do: aBlock being deprectated).
>>>>
>>>> ifValue: is not intention revealing to me when looking to the
>> newChain
>>>> thing.
>>>>
>>> Could you elaborate more?
>>>
>>> Would ifOk:ifError: be better?
>>>
>>> But then, is
>>>>        newChain ifValue: [ :value | ... ]
>>>>
>>>> making more sense than:
>>>>
>>>>       newChain onSuccess: [ :data | ... ]
>>>>
>>>> I'd say that the onSuccess: idiom makes it easier to add other event
>>>> types than ifValue:
>>>>
>>> I don't know if there will be ones... the native API tries to be
>> minimal.
>>> Names don't come easy...
>>>> Best,
>>>> Phil
>>>>
>>> Yeah.
>>>
>>> Herby
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>> Groups
>>> "amber-lang" group.
>>> To unsubscribe from this group and stop receiving emails from it,
>> send an
>>> email to [hidden email].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
Hi,

++ and -- look like autoincrement/decrement in other languages.  Hurts my eyes.

Gave it some tought as well.

As you say, conveying the async nature is significant, so why not do the #then: thing 

(fetch url: anUrl)
    then: [ :data | JSON parse: data ]
    then: [ :parsed | .... ]
    on: SomeException do: [ :ex | ... ]

Still need a way to do a .all(...)

Phil



    


On Tue, Jan 26, 2016 at 1:46 PM, Herby Vojčík <[hidden email]> wrote:


Herby Vojčík wrote:

Dňa 25. januára 2016 23:31:12 CET používateľ "[hidden email]"<[hidden email]>  napísal:
x newChain ifSuccess: [:data | ...  ] ifError: [ ... ] may be closer
IMHO.

Ok.

Giving this second thought.

Primo, #ifSuccess: / #onSuccess: wording gives the impression that promise is a "process" that can succeed. Even if it is, implementation-wise, its semantic is different - it is a value which is not accessible immediately, but ultimately will (or something may break in the way).

So, #ifValue: tried to reflect this semantics.

Maybe #ifPresent:ifError: could grasp it better. Or something similar, that hints on it as a 'future value' not a 'process with result'.

Secundo, #ifXxx:ifAlternativeToXxx: families of messages are all executed immediately. So, for promise, they should not be used. Something like #whenPresent:whenFailed: may be less misleading.

Tertio, there is grawlixy binary op option here as well, which I did not though of. This allows natural chaining, possibly wrapping directly .then and .catch API, without need of newChain, like in:

  (fetch value: url)
    ++ [ :data | JSON parse: data ]
    ++ [ :parsed |
      parsed at: #id ifAbsent: [ Error signal: "Missing name."].
      parsed ]
    ...
    -- [ :e | self handleError: e ofUrl: url ].

(there may be a +++ for accepting an array into parameters when all: is used, even +- [ :error :value | ... ] to wrap two-param .then).

BTW, is the ifSuccess: block monadic only? What about ifError: ?

Yes, both only accept one value, as JS native promises are only resolved/rejected with one value (which is an array in case of Promise.all; for that case, single ifSuccesses: can be created that spreads the array to arguments od the block).

Best,
Phil


On Mon, Jan 25, 2016 at 10:04 PM, Herby Vojčík<[hidden email]>
wrote:


[hidden email] wrote:

Ok.

Then, I guess you feel newChain ifValue: aBlock ifError: aBlock is
more
Smalltalkish than newChain onSuccess: aBloc onError: aBlock.

I drew from ifTrue:ifFalse:, ifNil:ifNotNil:, ifEmpty:ifNotEmpty:
families. I would really want to know which message is capturing the
spirit
of Smalltalk best way.

The async promises style is quite JS specific in the way it works
today
in browsers and node.

It will work this way for some time, though, as it is part of ES2015
spec.
If TC39 spirit of "don't break the Web" persist, then forever. ;-)
And as
far as I can tell, implementing "synchronous" pattern used in other
Smalltalks is not feasible (the whole Amber would need to include its
own
green thread simulator).

Wouldn't it be better (in the marketing sense) to mimic that instead
of
going the way of ifTrue: ifFalse: style?

I want to stay true to Smalltalk style. I care much more for
consistency
(and some pedagogical value) then short-term marketing. That said, I
started this thread to get feedback on precisely that - what API
would look
most natural for Smalltalk.

With exceptions, we have on BlockClosure (in Pharo):
aBlock on: exception do: handlerAction.

aBlock ifError: errorHandlerBlock

Looking in Announcement (amongst others), there we have when:
anEvent
do: aBlock (the on: anEvent do: aBlock being deprectated).

ifValue: is not intention revealing to me when looking to the
newChain
thing.

Could you elaborate more?

Would ifOk:ifError: be better?

But then, is
       newChain ifValue: [ :value | ... ]

making more sense than:

      newChain onSuccess: [ :data | ... ]

I'd say that the onSuccess: idiom makes it easier to add other event
types than ifValue:

I don't know if there will be ones... the native API tries to be
minimal.
Names don't come easy...
Best,
Phil

Yeah.

Herby

--
You received this message because you are subscribed to the Google
Groups
"amber-lang" group.
To unsubscribe from this group and stop receiving emails from it,
send an
email to [hidden email].
For more options, visit https://groups.google.com/d/optout.



--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:
> Hi,
>
> ++ and -- look like autoincrement/decrement in other languages.  Hurts
> my eyes.

+ and -? Or += and -= (conveying the fact that value is transformed and
new promised is created)? I know people don't like grawlixes much, but
binary ops have this very useful property of left associativity.

> Gave it some tought as well.
>
> As you say, conveying the async nature is significant, so why not do the
> #then: thing
>
> (fetch url: anUrl)
>      then: [ :data | JSON parse: data ]
>      then: [ :parsed | .... ]
>      on: SomeException do: [ :ex | ... ]

You can (and are encouraged to) mix many .then and .catch calls, in any
order. It is not said the only good way is to do
.then(..).then(..)...catch(..), though it is the usual case. How many
combos of then:then:on:do: do you want to include (there's still the
newChain approach with then:, catch: and on:do:, eventually also
thenObserve:/passingThen: and catchObserve:/passingCatch: to for
automatically passing value / error down the chain)?

(Desperate solution begin to appear in my mind like:

   (fetch url: anUrl) then: {
       #ok -> [ :data | JSON parse: data ].
       #ok -> [ :parsed | .... ].
       #error -> [ :ex | ... ] }

(possibly allowing more pattern to catch .then/2 as well as possibility
of on:do: functionality)
)


Also, promise can be rejected with any reason. That's why I don't know
if on:do: is the right approach (though many times, it is).

> Still need a way to do a .all(...)

.all produces promise like any other. Just it's resolved value is an
array of sub-resolves. In "composing" version, just things like +++ /
thenMany: / #many can be added. In combining scenario, it's harder
(though you always say you only destructure array of results in first
keyword and the rest should use single result.

> Phil

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
The only somewhat decent experience I have with promises is the $q in angular where I had a ton of things to fetch before doing a .all and initializing some components.
The API made sense.


On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
Hi,

++ and -- look like autoincrement/decrement in other languages.  Hurts
my eyes.

+ and -? Or += and -= (conveying the fact that value is transformed and new promised is created)? I know people don't like grawlixes much, but binary ops have this very useful property of left associativity.

Gave it some tought as well.

As you say, conveying the async nature is significant, so why not do the
#then: thing

(fetch url: anUrl)
     then: [ :data | JSON parse: data ]
     then: [ :parsed | .... ]
     on: SomeException do: [ :ex | ... ]

You can (and are encouraged to) mix many .then and .catch calls, in any order. It is not said the only good way is to do .then(..).then(..)...catch(..), though it is the usual case. How many combos of then:then:on:do: do you want to include (there's still the newChain approach with then:, catch: and on:do:, eventually also thenObserve:/passingThen: and catchObserve:/passingCatch: to for automatically passing value / error down the chain)?

(Desperate solution begin to appear in my mind like:

  (fetch url: anUrl) then: {
      #ok -> [ :data | JSON parse: data ].
      #ok -> [ :parsed | .... ].
      #error -> [ :ex | ... ] }

(possibly allowing more pattern to catch .then/2 as well as possibility of on:do: functionality)
)


Also, promise can be rejected with any reason. That's why I don't know if on:do: is the right approach (though many times, it is).

Still need a way to do a .all(...)

.all produces promise like any other. Just it's resolved value is an array of sub-resolves. In "composing" version, just things like +++ / thenMany: / #many can be added. In combining scenario, it's harder (though you always say you only destructure array of results in first keyword and the rest should use single result.

Phil

Herby

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:
> The only somewhat decent experience I have with promises is the $q in
> angular where I had a ton of things to fetch before doing a .all and
> initializing some components.
> The API made sense.

Yeah, but there you could chain, while in Smalltalk it would end up
parethesizing... that was my main concern. And maybe the most scenarios
do not end up chaining more than three .then call and then doing a
.catch, so maybe then:then:then:on:do: could actually work.

Don't know.

>
> https://docs.angularjs.org/api/ng/service/$q
>
> Best,
> Phil
>
> On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>
>
>     [hidden email] <mailto:[hidden email]> wrote:
>
>         Hi,
>
>         ++ and -- look like autoincrement/decrement in other languages.
>         Hurts
>         my eyes.
>
>
>     + and -? Or += and -= (conveying the fact that value is transformed
>     and new promised is created)? I know people don't like grawlixes
>     much, but binary ops have this very useful property of left
>     associativity.
>
>         Gave it some tought as well.
>
>         As you say, conveying the async nature is significant, so why
>         not do the
>         #then: thing
>
>         (fetch url: anUrl)
>               then: [ :data | JSON parse: data ]
>               then: [ :parsed | .... ]
>               on: SomeException do: [ :ex | ... ]
>
>
>     You can (and are encouraged to) mix many .then and .catch calls, in
>     any order. It is not said the only good way is to do
>     .then(..).then(..)...catch(..), though it is the usual case. How
>     many combos of then:then:on:do: do you want to include (there's
>     still the newChain approach with then:, catch: and on:do:,
>     eventually also thenObserve:/passingThen: and
>     catchObserve:/passingCatch: to for automatically passing value /
>     error down the chain)?
>
>     (Desperate solution begin to appear in my mind like:
>
>        (fetch url: anUrl) then: {
>            #ok -> [ :data | JSON parse: data ].
>            #ok -> [ :parsed | .... ].
>            #error -> [ :ex | ... ] }
>
>     (possibly allowing more pattern to catch .then/2 as well as
>     possibility of on:do: functionality)
>     )
>
>
>     Also, promise can be rejected with any reason. That's why I don't
>     know if on:do: is the right approach (though many times, it is).
>
>         Still need a way to do a .all(...)
>
>
>     .all produces promise like any other. Just it's resolved value is an
>     array of sub-resolves. In "composing" version, just things like +++
>     / thenMany: / #many can be added. In combining scenario, it's harder
>     (though you always say you only destructure array of results in
>     first keyword and the rest should use single result.
>
>         Phil
>
>
>     Herby
>
>     --
>     You received this message because you are subscribed to the Google
>     Groups "amber-lang" group.
>     To unsubscribe from this group and stop receiving emails from it,
>     send an email to [hidden email]
>     <mailto:amber-lang%[hidden email]>.
>     For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "amber-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email]
> <mailto:[hidden email]>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
#then: aBlockOrCollectionOfBlocks ?

like:

(fetch url: anUrl) 
   then: { 
        [ :value | ... ]. 
        [:parsed | ... ]
        } 
   all: aBlock
   on: Error do: [:ex | ... ]

with a couple of helpers to cover the "common", "simpler" cases ?

This start to get a bit out of hand :-)

On Tue, Jan 26, 2016 at 4:20 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
The only somewhat decent experience I have with promises is the $q in
angular where I had a ton of things to fetch before doing a .all and
initializing some components.
The API made sense.

Yeah, but there you could chain, while in Smalltalk it would end up parethesizing... that was my main concern. And maybe the most scenarios do not end up chaining more than three .then call and then doing a .catch, so maybe then:then:then:on:do: could actually work.

Don't know.


https://docs.angularjs.org/api/ng/service/$q

Best,
Phil

On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík <[hidden email]
<mailto:[hidden email]>> wrote:



    [hidden email] <mailto:[hidden email]> wrote:

        Hi,

        ++ and -- look like autoincrement/decrement in other languages.
        Hurts
        my eyes.


    + and -? Or += and -= (conveying the fact that value is transformed
    and new promised is created)? I know people don't like grawlixes
    much, but binary ops have this very useful property of left
    associativity.

        Gave it some tought as well.

        As you say, conveying the async nature is significant, so why
        not do the
        #then: thing

        (fetch url: anUrl)
              then: [ :data | JSON parse: data ]
              then: [ :parsed | .... ]
              on: SomeException do: [ :ex | ... ]


    You can (and are encouraged to) mix many .then and .catch calls, in
    any order. It is not said the only good way is to do
    .then(..).then(..)...catch(..), though it is the usual case. How
    many combos of then:then:on:do: do you want to include (there's
    still the newChain approach with then:, catch: and on:do:,
    eventually also thenObserve:/passingThen: and
    catchObserve:/passingCatch: to for automatically passing value /
    error down the chain)?

    (Desperate solution begin to appear in my mind like:

       (fetch url: anUrl) then: {
           #ok -> [ :data | JSON parse: data ].
           #ok -> [ :parsed | .... ].
           #error -> [ :ex | ... ] }

    (possibly allowing more pattern to catch .then/2 as well as
    possibility of on:do: functionality)
    )


    Also, promise can be rejected with any reason. That's why I don't
    know if on:do: is the right approach (though many times, it is).

        Still need a way to do a .all(...)


    .all produces promise like any other. Just it's resolved value is an
    array of sub-resolves. In "composing" version, just things like +++
    / thenMany: / #many can be added. In combining scenario, it's harder
    (though you always say you only destructure array of results in
    first keyword and the rest should use single result.

        Phil


    Herby

    --
    You received this message because you are subscribed to the Google
    Groups "amber-lang" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [hidden email]
    <mailto:[hidden email]>.
    For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google
Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [hidden email]
<mailto:[hidden email]>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


[hidden email] wrote:

> #then: aBlockOrCollectionOfBlocks ?
>
> like:
>
> (fetch url: anUrl)
>     then: {
>          [ :value | ... ].
>          [:parsed | ... ]
>          }
>     all: aBlock
>     on: Error do: [:ex | ... ]

My first instinct is "all: should go first, then: blocks should be
chained to it". OTOH, you can resolve something in between with .all,
which ... makes it really hairy.

Or maybe not, you'll just need paretheses before all: or after on:do:
(if you wanted to catch _any_ error, should it be on:do: be changed to
catch: ?).

I feel the need to integrate Promise, as I need it there, in couple of
cases, during loading as well. Now that it is part of spec, it needs to
be embraced.


> with a couple of helpers to cover the "common", "simpler" cases ?
>
> This start to get a bit out of hand :-)
>
> On Tue, Jan 26, 2016 at 4:20 PM, Herby Vojčík <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>
>
>     [hidden email] <mailto:[hidden email]> wrote:
>
>         The only somewhat decent experience I have with promises is the
>         $q in
>         angular where I had a ton of things to fetch before doing a .all and
>         initializing some components.
>         The API made sense.
>
>
>     Yeah, but there you could chain, while in Smalltalk it would end up
>     parethesizing... that was my main concern. And maybe the most
>     scenarios do not end up chaining more than three .then call and then
>     doing a .catch, so maybe then:then:then:on:do: could actually work.
>
>     Don't know.
>
>
>         https://docs.angularjs.org/api/ng/service/$q
>
>         Best,
>         Phil
>
>         On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík <[hidden email]
>         <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>
>
>
>         [hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>> wrote:
>
>                  Hi,
>
>                  ++ and -- look like autoincrement/decrement in other
>         languages.
>                  Hurts
>                  my eyes.
>
>
>              + and -? Or += and -= (conveying the fact that value is
>         transformed
>              and new promised is created)? I know people don't like
>         grawlixes
>              much, but binary ops have this very useful property of left
>              associativity.
>
>                  Gave it some tought as well.
>
>                  As you say, conveying the async nature is significant,
>         so why
>                  not do the
>                  #then: thing
>
>                  (fetch url: anUrl)
>                        then: [ :data | JSON parse: data ]
>                        then: [ :parsed | .... ]
>                        on: SomeException do: [ :ex | ... ]
>
>
>              You can (and are encouraged to) mix many .then and .catch
>         calls, in
>              any order. It is not said the only good way is to do
>              .then(..).then(..)...catch(..), though it is the usual
>         case. How
>              many combos of then:then:on:do: do you want to include (there's
>              still the newChain approach with then:, catch: and on:do:,
>              eventually also thenObserve:/passingThen: and
>              catchObserve:/passingCatch: to for automatically passing
>         value /
>              error down the chain)?
>
>              (Desperate solution begin to appear in my mind like:
>
>                 (fetch url: anUrl) then: {
>                     #ok -> [ :data | JSON parse: data ].
>                     #ok -> [ :parsed | .... ].
>                     #error -> [ :ex | ... ] }
>
>              (possibly allowing more pattern to catch .then/2 as well as
>              possibility of on:do: functionality)
>              )
>
>
>              Also, promise can be rejected with any reason. That's why I
>         don't
>              know if on:do: is the right approach (though many times, it
>         is).
>
>                  Still need a way to do a .all(...)
>
>
>              .all produces promise like any other. Just it's resolved
>         value is an
>              array of sub-resolves. In "composing" version, just things
>         like +++
>              / thenMany: / #many can be added. In combining scenario,
>         it's harder
>              (though you always say you only destructure array of results in
>              first keyword and the rest should use single result.
>
>                  Phil
>
>
>              Herby
>
>              --
>              You received this message because you are subscribed to the
>         Google
>              Groups "amber-lang" group.
>              To unsubscribe from this group and stop receiving emails
>         from it,
>              send an email to [hidden email]
>         <mailto:amber-lang%[hidden email]>
>         <mailto:amber-lang%[hidden email]
>         <mailto:amber-lang%[hidden email]>>.
>              For more options, visit https://groups.google.com/d/optout.
>
>
>         --
>         You received this message because you are subscribed to the Google
>         Groups "amber-lang" group.
>         To unsubscribe from this group and stop receiving emails from
>         it, send
>         an email to [hidden email]
>         <mailto:amber-lang%[hidden email]>
>         <mailto:[hidden email]
>         <mailto:amber-lang%[hidden email]>>.
>         For more options, visit https://groups.google.com/d/optout.
>
>
>     --
>     You received this message because you are subscribed to the Google
>     Groups "amber-lang" group.
>     To unsubscribe from this group and stop receiving emails from it,
>     send an email to [hidden email]
>     <mailto:amber-lang%[hidden email]>.
>     For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "amber-lang" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to [hidden email]
> <mailto:[hidden email]>.
> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
I faced internal resistance at first when meeting promises but as it is what makes the "modern" web what it (e.g. angular style coding), we need to embrace that.

Otherwise, it is nightmarish to use all of the APIs etc.

Parens are no problem for me FWIW.

How would you see reject used?

Phil



On Tue, Jan 26, 2016 at 4:44 PM, Herby Vojčík <[hidden email]> wrote:


[hidden email] wrote:
#then: aBlockOrCollectionOfBlocks ?

like:

(fetch url: anUrl)
    then: {
         [ :value | ... ].
         [:parsed | ... ]
         }
    all: aBlock
    on: Error do: [:ex | ... ]

My first instinct is "all: should go first, then: blocks should be chained to it". OTOH, you can resolve something in between with .all, which ... makes it really hairy.

Or maybe not, you'll just need paretheses before all: or after on:do: (if you wanted to catch _any_ error, should it be on:do: be changed to catch: ?).

I feel the need to integrate Promise, as I need it there, in couple of cases, during loading as well. Now that it is part of spec, it needs to be embraced.


with a couple of helpers to cover the "common", "simpler" cases ?

This start to get a bit out of hand :-)

On Tue, Jan 26, 2016 at 4:20 PM, Herby Vojčík <[hidden email]
<mailto:[hidden email]>> wrote:



    [hidden email] <mailto:[hidden email]> wrote:

        The only somewhat decent experience I have with promises is the
        $q in
        angular where I had a ton of things to fetch before doing a .all and
        initializing some components.
        The API made sense.


    Yeah, but there you could chain, while in Smalltalk it would end up
    parethesizing... that was my main concern. And maybe the most
    scenarios do not end up chaining more than three .then call and then
    doing a .catch, so maybe then:then:then:on:do: could actually work.

    Don't know.


        https://docs.angularjs.org/api/ng/service/$q

        Best,
        Phil

        On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík <[hidden email]
        <mailto:[hidden email]>
        <mailto:[hidden email] <mailto:[hidden email]>>> wrote:



        [hidden email] <mailto:[hidden email]>
        <mailto:[hidden email] <mailto:[hidden email]>> wrote:

                 Hi,

                 ++ and -- look like autoincrement/decrement in other
        languages.
                 Hurts
                 my eyes.


             + and -? Or += and -= (conveying the fact that value is
        transformed
             and new promised is created)? I know people don't like
        grawlixes
             much, but binary ops have this very useful property of left
             associativity.

                 Gave it some tought as well.

                 As you say, conveying the async nature is significant,
        so why
                 not do the
                 #then: thing

                 (fetch url: anUrl)
                       then: [ :data | JSON parse: data ]
                       then: [ :parsed | .... ]
                       on: SomeException do: [ :ex | ... ]


             You can (and are encouraged to) mix many .then and .catch
        calls, in
             any order. It is not said the only good way is to do
             .then(..).then(..)...catch(..), though it is the usual
        case. How
             many combos of then:then:on:do: do you want to include (there's
             still the newChain approach with then:, catch: and on:do:,
             eventually also thenObserve:/passingThen: and
             catchObserve:/passingCatch: to for automatically passing
        value /
             error down the chain)?

             (Desperate solution begin to appear in my mind like:

                (fetch url: anUrl) then: {
                    #ok -> [ :data | JSON parse: data ].
                    #ok -> [ :parsed | .... ].
                    #error -> [ :ex | ... ] }

             (possibly allowing more pattern to catch .then/2 as well as
             possibility of on:do: functionality)
             )


             Also, promise can be rejected with any reason. That's why I
        don't
             know if on:do: is the right approach (though many times, it
        is).

                 Still need a way to do a .all(...)


             .all produces promise like any other. Just it's resolved
        value is an
             array of sub-resolves. In "composing" version, just things
        like +++
             / thenMany: / #many can be added. In combining scenario,
        it's harder
             (though you always say you only destructure array of results in
             first keyword and the rest should use single result.

                 Phil


             Herby

             --
             You received this message because you are subscribed to the
        Google
             Groups "amber-lang" group.
             To unsubscribe from this group and stop receiving emails
        from it,
             send an email to [hidden email]
        <mailto:[hidden email]>
        <mailto:[hidden email]
        <mailto:[hidden email]>>.
             For more options, visit https://groups.google.com/d/optout.


        --
        You received this message because you are subscribed to the Google
        Groups "amber-lang" group.
        To unsubscribe from this group and stop receiving emails from
        it, send
        an email to [hidden email]
        <mailto:[hidden email]>
        <mailto:[hidden email]
        <mailto:[hidden email]>>.
        For more options, visit https://groups.google.com/d/optout.


    --
    You received this message because you are subscribed to the Google
    Groups "amber-lang" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to [hidden email]
    <mailto:[hidden email]>.
    For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to the Google
Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [hidden email]
<mailto:[hidden email]>.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

Herby Vojčík


Dňa 26. januára 2016 16:54:51 CET používateľ "[hidden email]" <[hidden email]> napísal:
>I faced internal resistance at first when meeting promises but as it is
>what makes the "modern" web what it (e.g. angular style coding), we

I don't know what you mean by angular style coding. I do not use angular but use promises (and ES6 ones, not q, bluebird or any other lib).

>need to
>embrace that.
>
>Otherwise, it is nightmarish to use all of the APIs etc.
>
>Parens are no problem for me FWIW.

In JS, I find it ok. In Amber, parentheses would make me mad (hence, chaining helper of this or that sort). But as I said, I find 8 members of [all:]then:[on:do:][catch:] family with array in then: feasible (or 6 members of
[all:]then:[on:do:|catch:]).

>How would you see reject used?

I don't understand. You mean Promise.reject convenience API or reject in executor?

>Phil
>
>
>
>On Tue, Jan 26, 2016 at 4:44 PM, Herby Vojčík <[hidden email]> wrote:
>
>>
>>
>> [hidden email] wrote:
>>
>>> #then: aBlockOrCollectionOfBlocks ?
>>>
>>> like:
>>>
>>> (fetch url: anUrl)
>>>     then: {
>>>          [ :value | ... ].
>>>          [:parsed | ... ]
>>>          }
>>>     all: aBlock
>>>     on: Error do: [:ex | ... ]
>>>
>>
>> My first instinct is "all: should go first, then: blocks should be
>chained
>> to it". OTOH, you can resolve something in between with .all, which
>...
>> makes it really hairy.
>>
>> Or maybe not, you'll just need paretheses before all: or after on:do:
>(if
>> you wanted to catch _any_ error, should it be on:do: be changed to
>catch:
>> ?).
>>
>> I feel the need to integrate Promise, as I need it there, in couple
>of
>> cases, during loading as well. Now that it is part of spec, it needs
>to be
>> embraced.
>>
>>
>> with a couple of helpers to cover the "common", "simpler" cases ?
>>>
>>> This start to get a bit out of hand :-)
>>>
>>> On Tue, Jan 26, 2016 at 4:20 PM, Herby Vojčík <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>
>>>
>>>
>>>     [hidden email] <mailto:[hidden email]> wrote:
>>>
>>>         The only somewhat decent experience I have with promises is
>the
>>>         $q in
>>>         angular where I had a ton of things to fetch before doing a
>.all
>>> and
>>>         initializing some components.
>>>         The API made sense.
>>>
>>>
>>>     Yeah, but there you could chain, while in Smalltalk it would end
>up
>>>     parethesizing... that was my main concern. And maybe the most
>>>     scenarios do not end up chaining more than three .then call and
>then
>>>     doing a .catch, so maybe then:then:then:on:do: could actually
>work.
>>>
>>>     Don't know.
>>>
>>>
>>>         https://docs.angularjs.org/api/ng/service/$q
>>>
>>>         Best,
>>>         Phil
>>>
>>>         On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík
><[hidden email]
>>>         <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>
>>>
>>>         [hidden email] <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>
>wrote:
>>>
>>>                  Hi,
>>>
>>>                  ++ and -- look like autoincrement/decrement in
>other
>>>         languages.
>>>                  Hurts
>>>                  my eyes.
>>>
>>>
>>>              + and -? Or += and -= (conveying the fact that value is
>>>         transformed
>>>              and new promised is created)? I know people don't like
>>>         grawlixes
>>>              much, but binary ops have this very useful property of
>left
>>>              associativity.
>>>
>>>                  Gave it some tought as well.
>>>
>>>                  As you say, conveying the async nature is
>significant,
>>>         so why
>>>                  not do the
>>>                  #then: thing
>>>
>>>                  (fetch url: anUrl)
>>>                        then: [ :data | JSON parse: data ]
>>>                        then: [ :parsed | .... ]
>>>                        on: SomeException do: [ :ex | ... ]
>>>
>>>
>>>              You can (and are encouraged to) mix many .then and
>.catch
>>>         calls, in
>>>              any order. It is not said the only good way is to do
>>>              .then(..).then(..)...catch(..), though it is the usual
>>>         case. How
>>>              many combos of then:then:on:do: do you want to include
>>> (there's
>>>              still the newChain approach with then:, catch: and
>on:do:,
>>>              eventually also thenObserve:/passingThen: and
>>>              catchObserve:/passingCatch: to for automatically
>passing
>>>         value /
>>>              error down the chain)?
>>>
>>>              (Desperate solution begin to appear in my mind like:
>>>
>>>                 (fetch url: anUrl) then: {
>>>                     #ok -> [ :data | JSON parse: data ].
>>>                     #ok -> [ :parsed | .... ].
>>>                     #error -> [ :ex | ... ] }
>>>
>>>              (possibly allowing more pattern to catch .then/2 as
>well as
>>>              possibility of on:do: functionality)
>>>              )
>>>
>>>
>>>              Also, promise can be rejected with any reason. That's
>why I
>>>         don't
>>>              know if on:do: is the right approach (though many
>times, it
>>>         is).
>>>
>>>                  Still need a way to do a .all(...)
>>>
>>>
>>>              .all produces promise like any other. Just it's
>resolved
>>>         value is an
>>>              array of sub-resolves. In "composing" version, just
>things
>>>         like +++
>>>              / thenMany: / #many can be added. In combining
>scenario,
>>>         it's harder
>>>              (though you always say you only destructure array of
>results
>>> in
>>>              first keyword and the rest should use single result.
>>>
>>>                  Phil
>>>
>>>
>>>              Herby
>>>
>>>              --
>>>              You received this message because you are subscribed to
>the
>>>         Google
>>>              Groups "amber-lang" group.
>>>              To unsubscribe from this group and stop receiving
>emails
>>>         from it,
>>>              send an email to
>[hidden email]
>>>         <mailto:amber-lang%[hidden email]>
>>>         <mailto:amber-lang%[hidden email]
>>>         <mailto:amber-lang%[hidden email]>>.
>>>              For more options, visit
>https://groups.google.com/d/optout.
>>>
>>>
>>>         --
>>>         You received this message because you are subscribed to the
>Google
>>>         Groups "amber-lang" group.
>>>         To unsubscribe from this group and stop receiving emails
>from
>>>         it, send
>>>         an email to [hidden email]
>>>         <mailto:amber-lang%[hidden email]>
>>>         <mailto:[hidden email]
>>>         <mailto:amber-lang%[hidden email]>>.
>>>         For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>     --
>>>     You received this message because you are subscribed to the
>Google
>>>     Groups "amber-lang" group.
>>>     To unsubscribe from this group and stop receiving emails from
>it,
>>>     send an email to [hidden email]
>>>     <mailto:amber-lang%[hidden email]>.
>>>     For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "amber-lang" group.
>>> To unsubscribe from this group and stop receiving emails from it,
>send
>>> an email to [hidden email]
>>> <mailto:[hidden email]>.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>Groups
>> "amber-lang" group.
>> To unsubscribe from this group and stop receiving emails from it,
>send an
>> email to [hidden email].
>> For more options, visit https://groups.google.com/d/optout.
>>

--
Odoslané z môjho Android zariadenia pomocou K-9 Mail.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Promise API

philippeback
On Tue, Jan 26, 2016 at 5:56 PM, Herby Vojčík <[hidden email]> wrote:


Dňa 26. januára 2016 16:54:51 CET používateľ "[hidden email]" <[hidden email]> napísal:
>I faced internal resistance at first when meeting promises but as it is
>what makes the "modern" web what it (e.g. angular style coding), we

I don't know what you mean by angular style coding. I do not use angular but use promises (and ES6 ones, not q, bluebird or any other lib).

JS with promises style. 

>need to
>embrace that.
>
>Otherwise, it is nightmarish to use all of the APIs etc.
>
>Parens are no problem for me FWIW.

In JS, I find it ok. In Amber, parentheses would make me mad (hence, chaining helper of this or that sort). But as I said, I find 8 members of [all:]then:[on:do:][catch:] family with array in then: feasible (or 6 members of
[all:]then:[on:do:|catch:]).

yes, this looks a nice avenue to go down. 

>How would you see reject used?

I don't understand. You mean Promise.reject convenience API or reject in executor?

Promise.reject
 

>Phil
>
>
>
>On Tue, Jan 26, 2016 at 4:44 PM, Herby Vojčík <[hidden email]> wrote:
>
>>
>>
>> [hidden email] wrote:
>>
>>> #then: aBlockOrCollectionOfBlocks ?
>>>
>>> like:
>>>
>>> (fetch url: anUrl)
>>>     then: {
>>>          [ :value | ... ].
>>>          [:parsed | ... ]
>>>          }
>>>     all: aBlock
>>>     on: Error do: [:ex | ... ]
>>>
>>
>> My first instinct is "all: should go first, then: blocks should be
>chained
>> to it". OTOH, you can resolve something in between with .all, which
>...
>> makes it really hairy.
>>
>> Or maybe not, you'll just need paretheses before all: or after on:do:
>(if
>> you wanted to catch _any_ error, should it be on:do: be changed to
>catch:
>> ?).
>>
>> I feel the need to integrate Promise, as I need it there, in couple
>of
>> cases, during loading as well. Now that it is part of spec, it needs
>to be
>> embraced.
>>
>>
>> with a couple of helpers to cover the "common", "simpler" cases ?
>>>
>>> This start to get a bit out of hand :-)
>>>
>>> On Tue, Jan 26, 2016 at 4:20 PM, Herby Vojčík <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>
>>>
>>>
>>>     [hidden email] <mailto:[hidden email]> wrote:
>>>
>>>         The only somewhat decent experience I have with promises is
>the
>>>         $q in
>>>         angular where I had a ton of things to fetch before doing a
>.all
>>> and
>>>         initializing some components.
>>>         The API made sense.
>>>
>>>
>>>     Yeah, but there you could chain, while in Smalltalk it would end
>up
>>>     parethesizing... that was my main concern. And maybe the most
>>>     scenarios do not end up chaining more than three .then call and
>then
>>>     doing a .catch, so maybe then:then:then:on:do: could actually
>work.
>>>
>>>     Don't know.
>>>
>>>
>>>         https://docs.angularjs.org/api/ng/service/$q
>>>
>>>         Best,
>>>         Phil
>>>
>>>         On Tue, Jan 26, 2016 at 3:04 PM, Herby Vojčík
><[hidden email]
>>>         <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>>>
>>>
>>>
>>>         [hidden email] <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>
>wrote:
>>>
>>>                  Hi,
>>>
>>>                  ++ and -- look like autoincrement/decrement in
>other
>>>         languages.
>>>                  Hurts
>>>                  my eyes.
>>>
>>>
>>>              + and -? Or += and -= (conveying the fact that value is
>>>         transformed
>>>              and new promised is created)? I know people don't like
>>>         grawlixes
>>>              much, but binary ops have this very useful property of
>left
>>>              associativity.
>>>
>>>                  Gave it some tought as well.
>>>
>>>                  As you say, conveying the async nature is
>significant,
>>>         so why
>>>                  not do the
>>>                  #then: thing
>>>
>>>                  (fetch url: anUrl)
>>>                        then: [ :data | JSON parse: data ]
>>>                        then: [ :parsed | .... ]
>>>                        on: SomeException do: [ :ex | ... ]
>>>
>>>
>>>              You can (and are encouraged to) mix many .then and
>.catch
>>>         calls, in
>>>              any order. It is not said the only good way is to do
>>>              .then(..).then(..)...catch(..), though it is the usual
>>>         case. How
>>>              many combos of then:then:on:do: do you want to include
>>> (there's
>>>              still the newChain approach with then:, catch: and
>on:do:,
>>>              eventually also thenObserve:/passingThen: and
>>>              catchObserve:/passingCatch: to for automatically
>passing
>>>         value /
>>>              error down the chain)?
>>>
>>>              (Desperate solution begin to appear in my mind like:
>>>
>>>                 (fetch url: anUrl) then: {
>>>                     #ok -> [ :data | JSON parse: data ].
>>>                     #ok -> [ :parsed | .... ].
>>>                     #error -> [ :ex | ... ] }
>>>
>>>              (possibly allowing more pattern to catch .then/2 as
>well as
>>>              possibility of on:do: functionality)
>>>              )
>>>
>>>
>>>              Also, promise can be rejected with any reason. That's
>why I
>>>         don't
>>>              know if on:do: is the right approach (though many
>times, it
>>>         is).
>>>
>>>                  Still need a way to do a .all(...)
>>>
>>>
>>>              .all produces promise like any other. Just it's
>resolved
>>>         value is an
>>>              array of sub-resolves. In "composing" version, just
>things
>>>         like +++
>>>              / thenMany: / #many can be added. In combining
>scenario,
>>>         it's harder
>>>              (though you always say you only destructure array of
>results
>>> in
>>>              first keyword and the rest should use single result.
>>>
>>>                  Phil
>>>
>>>
>>>              Herby
>>>
>>>              --
>>>              You received this message because you are subscribed to
>the
>>>         Google
>>>              Groups "amber-lang" group.
>>>              To unsubscribe from this group and stop receiving
>emails
>>>         from it,
>>>              send an email to
>[hidden email]
>>>         <mailto:[hidden email]>
>>>         <mailto:[hidden email]
>>>         <mailto:[hidden email]>>.
>>>              For more options, visit
>https://groups.google.com/d/optout.
>>>
>>>
>>>         --
>>>         You received this message because you are subscribed to the
>Google
>>>         Groups "amber-lang" group.
>>>         To unsubscribe from this group and stop receiving emails
>from
>>>         it, send
>>>         an email to [hidden email]
>>>         <mailto:[hidden email]>
>>>         <mailto:[hidden email]
>>>         <mailto:[hidden email]>>.
>>>         For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>>     --
>>>     You received this message because you are subscribed to the
>Google
>>>     Groups "amber-lang" group.
>>>     To unsubscribe from this group and stop receiving emails from
>it,
>>>     send an email to [hidden email]
>>>     <mailto:[hidden email]>.
>>>     For more options, visit https://groups.google.com/d/optout.
>>>
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "amber-lang" group.
>>> To unsubscribe from this group and stop receiving emails from it,
>send
>>> an email to [hidden email]
>>> <mailto:[hidden email]>.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>Groups
>> "amber-lang" group.
>> To unsubscribe from this group and stop receiving emails from it,
>send an
>> email to [hidden email].
>> For more options, visit https://groups.google.com/d/optout.
>>

--
Odoslané z môjho Android zariadenia pomocou K-9 Mail.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "amber-lang" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
12