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. |
How would .all works in the example? Phil On Jan 24, 2016 5:13 PM, "Herby Vojčík" <[hidden email]> wrote:
-- Hello! 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. |
[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. |
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:
--
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. |
[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 ] > > > 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 > 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. |
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:
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. |
[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. |
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:
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. |
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:
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. |
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. |
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. |
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:
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. |
[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. |
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:
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. |
[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. |
#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:
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. |
[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 > 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. |
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:
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. |
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 >>> 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 >>> 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 >>> 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. |
On Tue, Jan 26, 2016 at 5:56 PM, Herby Vojčík <[hidden email]> wrote:
JS with promises style.
yes, this looks a nice avenue to go down.
Promise.reject
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. |
Free forum by Nabble | Edit this page |