Protego - smart way to manage NIL's in business calculations

10 messages
Open this post in threaded view
|

Protego - smart way to manage NIL's in business calculations

 Imagine, you have some object with amount and price variables.And you want to calculate total, put this totals to collection and calculate grand total.Naive implementation will be something liketotal := amount * price for the first taskand something likegrandTotal := totals sum for the latter one.But what if amount or price are nil's?You can add nil checks, of course: total := (amount ifNil:[0]) * (price ifNil: [0]).And then what if totals will be empty? More checks.Is it really wise to have total to be zero if amount is nil? More ifTrue:ifFalse: code.And then you want to add amount := total / price calculation, and you realize that both total and price may be nil, and price may be zero.More and more and more checks.Protego (http://www.smalltalkhub.com/#!/~assargadon/Protego) adds "protected" versions of common operators and methods.So, you just puttotal := amount *@ priceandgrandTotal := totals sum_protectedinto your code - and everything just works.total will be nil if any of the operands are nil. grandTotal will be calculated normally, even for empty totals collection (will return nil for empty collection).Collection can hold nil's and it will work anyway. If all elements of the collection is nil, result will be nil.Protected version of addition and subtraction will treat nil's as zeros until both operands are nil - then it will return nil.There are protected versions of comparisions, too.It's quite simple idea, which is still very useful, and it makes code much more readable, clean and self-commenting.That's why I have extracted this part of SmallPOS framework, and have published it as separate package to use it in other, non-SmallPOS applications.
Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

 Hi Yuri, Long time not seeing you ! welcome back :)Nice framework !EstebanOn 18 Dec 2016, at 11:45, Юрий Мироненко <[hidden email]> wrote:Imagine, you have some object with amount and price variables.And you want to calculate total, put this totals to collection and calculate grand total.Naive implementation will be something liketotal := amount * price for the first taskand something likegrandTotal := totals sum for the latter one.But what if amount or price are nil's?You can add nil checks, of course: total := (amount ifNil:[0]) * (price ifNil: [0]).And then what if totals will be empty? More checks.Is it really wise to have total to be zero if amount is nil? More ifTrue:ifFalse: code.And then you want to add amount := total / price calculation, and you realize that both total and price may be nil, and price may be zero.More and more and more checks.Protego (http://www.smalltalkhub.com/#!/~assargadon/Protego) adds "protected" versions of common operators and methods.So, you just puttotal := amount *@ priceandgrandTotal := totals sum_protectedinto your code - and everything just works.total will be nil if any of the operands are nil. grandTotal will be calculated normally, even for empty totals collection (will return nil for empty collection).Collection can hold nil's and it will work anyway. If all elements of the collection is nil, result will be nil.Protected version of addition and subtraction will treat nil's as zeros until both operands are nil - then it will return nil.There are protected versions of comparisions, too.It's quite simple idea, which is still very useful, and it makes code much more readable, clean and self-commenting.That's why I have extracted this part of SmallPOS framework, and have published it as separate package to use it in other, non-SmallPOS applications.
Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

 In reply to this post by Yuriy Mironenko Thanks for sharing.  A similar thing might be useful for dealing with "quality" of Process Variable measurement in industrial situations - where instruments fail from time to time. I'm not sure of all the pros and cons, but btw an alternative to hanging special behaviour on a method, would be to hang special behaviour on a MissingValue class that you could #initialize any instance variable to.   Object subclass: #MissingValue     instanceVariableNames: ''     classVariableNames: ''     package: 'AAAA'    MissingValue >> * dummyValue       self inform: 'debug trace - got here'.       ^self    MissingValue >> adaptToNumber: rcvr andSend: selector        ^self perform: selector with: rcvr   Collection >> sumProtected     ^ self         inject: 0         into: [ :sum :each |  sum + each value] Usage... c := {1.1 * MissingValue new.   1.2 * 10.   MissingValue new * 1.3.   10 * 1.4}.  "==> an Array(aMissingValue 12.0 aMissingValue 14.0)" c sumExcludeMissing  "==> 26.0" cheers -ben On Sun, Dec 18, 2016 at 6:45 PM, Юрий Мироненко <[hidden email]> wrote: > Imagine, you have some object with amount and price variables. > And you want to calculate total, put this totals to collection and calculate > grand total. > > Naive implementation will be something like > total := amount * price for the first task > and something like > grandTotal := totals sum for the latter one. > > But what if amount or price are nil's? > You can add nil checks, of course: total := (amount ifNil:[0]) * (price > ifNil: [0]). > And then what if totals will be empty? More checks. > Is it really wise to have total to be zero if amount is nil? More > ifTrue:ifFalse: code. > And then you want to add amount := total / price calculation, and you > realize that both total and price may be nil, and price may be zero. > More and more and more checks. > > Protego (http://www.smalltalkhub.com/#!/~assargadon/Protego) adds > "protected" versions of common operators and methods. > > So, you just put > total := amount *@ price > and > grandTotal := totals sum_protected > into your code - and everything just works. > > total will be nil if any of the operands are nil. grandTotal will be > calculated normally, even for empty totals collection (will return nil for > empty collection). > Collection can hold nil's and it will work anyway. If all elements of the > collection is nil, result will be nil. > > Protected version of addition and subtraction will treat nil's as zeros > until both operands are nil - then it will return nil. > There are protected versions of comparisions, too. > > It's quite simple idea, which is still very useful, and it makes code much > more readable, clean and self-commenting. > > That's why I have extracted this part of SmallPOS framework, and have > published it as separate package to use it in other, non-SmallPOS > applications.
Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

 In reply to this post by Yuriy Mironenko thanks for sharing it with us.Now in Moose we have metrics and when a metrics value is not available giving 0 is not the solution. We should probably have Value that wraps the real value for normal case and Unvalued for the case where there is no value. StefOn Sun, 18 Dec 2016 11:45:30 +0100, Юрий Мироненко <[hidden email]> wrote:Imagine, you have some object with amount and price variables.And you want to calculate total, put this totals to collection and calculate grand total.Naive implementation will be something liketotal := amount * price for the first taskand something likegrandTotal := totals sum for the latter one.But what if amount or price are nil's?You can add nil checks, of course: total := (amount ifNil:[0]) * (price ifNil: [0]).And then what if totals will be empty? More checks.Is it really wise to have total to be zero if amount is nil? More ifTrue:ifFalse: code.And then you want to add amount := total / price calculation, and you realize that both total and price may be nil, and price may be zero.More and more and more checks.Protego (http://www.smalltalkhub.com/#!/~assargadon/Protego) adds "protected" versions of common operators and methods.So, you just puttotal := amount *@ priceandgrandTotal := totals sum_protectedinto your code - and everything just works.total will be nil if any of the operands are nil. grandTotal will be calculated normally, even for empty totals collection (will return nil for empty collection).Collection can hold nil's and it will work anyway. If all elements of the collection is nil, result will be nil.Protected version of addition and subtraction will treat nil's as zeros until both operands are nil - then it will return nil.There are protected versions of comparisions, too.It's quite simple idea, which is still very useful, and it makes code much more readable, clean and self-commenting.That's why I have extracted this part of SmallPOS framework, and have published it as separate package to use it in other, non-SmallPOS applications. -- Using Opera's mail client: http://www.opera.com/mail/
Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

 2016-12-18 19:43 GMT+01:00 Юрий Мироненко :Sorry, I'm not sure I fully understand your idea.It looks like trying to make another implementation of UndefinedObject, is it?What is the main difference between proposed MissingValue and UndefinedObject?MissingValue you will set up according to your business logic. While nil is just default value of variable which could be in your object by some incident, bug of application.
Open this post in threaded view
|

Re: Protego - smart way to manage NIL's in business calculations

 2016-12-18 20:19 GMT+01:00 Denis Kudriashov :What is the main difference between proposed MissingValue and UndefinedObject?MissingValue you will set up according to your business logic. While nil is just default value of variable which could be in your object by some incident, bug of application. And it makes impossible to distinguish bug from normal application state related to missing value