www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Null references

reply "bearophile" <bearophileHUGS lycos.com> writes:
The very good Mark C. Chu-Carroll has written a little blog post 
about the lack of null-related errors in his Scala code:

http://scientopia.org/blogs/goodmath/2012/08/20/nulls/

Bye,
bearophile
Aug 21 2012
next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 21 Aug 2012 12:32:31 +0100, bearophile <bearophileHUGS lycos.com>  
wrote:

 The very good Mark C. Chu-Carroll has written a little blog post about  
 the lack of null-related errors in his Scala code:

 http://scientopia.org/blogs/goodmath/2012/08/20/nulls/

This article links to: http://beust.com/weblog/2012/08/19/a-note-on-null-pointers/ very early on. Which is also a good read, and has parallels with the NaN discussion as well :p I really like the Groovy/Fantom/Kotlin syntax shown: [quote] For example, here is how Kotlin lets you ignore null values encountered along a chain of invocations: bob?.department?.head?.name If either of these accesses returns null, the result of this expression will be null. No need to put your values into monadic boxes nor mapping through them, just use the standard composition operator you are familiar with if you are using a C family language. [/quote] I think this would be a neat D feature. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Aug 21 2012
prev sibling next sibling parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 21 Aug 2012 12:32:31 +0100, bearophile <bearophileHUGS lycos.com>  
wrote:

 The very good Mark C. Chu-Carroll has written a little blog post about  
 the lack of null-related errors in his Scala code:

 http://scientopia.org/blogs/goodmath/2012/08/20/nulls/

It's prob no obvious from my other reply, but you might have guessed, I'm of the opinion that Otaku, Cedric's blog post is spot on and Mark C is wrong. Well, not wrong exactly but not right either. A Null pointer exception in Java will give you a stack trace, meaning you can be sure which method triggered it, meaning you don't have to examine "everything", just those method calls/objects used therein. If your method is so large that this is a daunting task, then you're already doing something wrong. Plus, I don't buy the argument that having to explicitly type ".get" will stop anyone from automatically coding statements like: val g: Option[T] = f.doSomething() g.get.doSomethingElse() and suffering the exact same null pointer exception/error despite using Option and boxing into a Not-Null type. Like checked exceptions people will simply ignore the possibility of error and type the above anyway. So, end result, it's just more typing for no real gain. On the other hand, the suggested syntax of "bob?.department?.head?.name" from Kotlin is pure genius, and has a good chance of actually being used. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Aug 21 2012
next sibling parent reply Nick Treleaven <nospam example.net> writes:
On 21/08/2012 14:30, Simen Kjaeraas wrote:
 On Tue, 21 Aug 2012 13:55:58 +0200, Regan Heath <regan netmail.co.nz>
 wrote:

 I don't buy the argument that having to explicitly type ".get" will
 stop anyone from automatically coding statements like:

 val g: Option[T] = f.doSomething()
 g.get.doSomethingElse()

So don't give them that access?

Yes, or force conversion of the Option, handling the invalid case: g.valueOrElse(null).doSomethingElse(); The above being explicit that null might be returned. The code is no safer, but it is much clearer. Also sometimes the caller has a better alternative value than null to use which is actually valid.
 I have an Option struct on my home computer that only allows access to
 the held value if the error case is simultaneously handled:

 Option!int a = foo();

 int n = a.match!(
      (int x) => x,
      (None n) => 0 // or throw, or what have you.
      );

 The same solution is perfectly adaptable to MaybeNull, MaybeNan, and
 probably
 a host of others of the same family.

 With some clever use of opDispatch, one could write an Option struct that
 lets you call methods and acces members of the wrapped type, and return
 Option!ReturnType.

Apart from the opDispatch bit, I've been slowly working on something similar (Boost license): https://github.com/ntrel/d-maybe/blob/master/maybe.d I'm still working on it, but the basic ideas are there. I think the best bit is apply(), which supports passing multiple Maybe values, calling the delegate only if all Maybes are valid. In fact Maybe.map() is unnecessary due to apply(). Nick
Aug 21 2012
next sibling parent reply Nick Treleaven <nospam example.net> writes:
On 21/08/2012 21:17, Nick Treleaven wrote:
 I have an Option struct on my home computer that only allows access to
 the held value if the error case is simultaneously handled:

 Option!int a = foo();

 int n = a.match!(
      (int x) => x,
      (None n) => 0 // or throw, or what have you.
      );


I've now implemented match, similar to the above: https://github.com/ntrel/d-maybe/blob/master/maybe.d#L222 My match() always returns Maybe!T, because for pointers the lambdas could return null. Taken from the unittest: assert(match!(to!string, ()=>"<invalid>")(maybe(2)) == "2"); assert(match!(to!string, ()=>"<invalid>")(Maybe!int()) == "<invalid>"); assert(match!((x, y)=>text(x, y), {})(maybe(2), maybe(34)) == "234"); assert(match!((x, y)=>text(x, y), {})(Maybe!int(), maybe(34)) == null); assert(match!((x, y)=>text(x, y), ()=>"none")(Maybe!int(), maybe(34)) == "none"); I'd be interested to see your Option code. Nick
Aug 23 2012
parent Nick Treleaven <nospam example.net> writes:
On 23/08/2012 18:27, Namespace wrote:
 Is there any special reason why these functions doesn't get "Maybe" as
 (const) ref?

 void show(T)(Maybe!T m)
 bool opEquals(Maybe!T m)
 void opAssign(Maybe!T m)

No special reason. The Maybe struct is usually pretty small so using ref didn't occur to me, but if it's good practice I should do so. I suppose ref would be necessary because T could be a struct. I hadn't thought about const at all yet. BTW show is just a test function, I recently made it private. Nick
Aug 24 2012
prev sibling parent Nick Treleaven <nospam example.net> writes:
On 22/08/2012 16:42, Philippe Sigaud wrote:
 Then, both Simen and you could code a generic algebraic datatype
 generator, with the associated matching functions (and probably
 mapping / reducing) Here come the whole Haskell / ML menagerie of
 types:)

 mixin(ADT("
 Tree(T):
      Leaf(T)
    | Branch(Tree, Tree)
 "));

 or something like that... And then encode JSON like this.

 Or update std.typecons.Algebraic to make it deal with recursive definitions...

Sounds interesting. I haven't really thought about modelling sum types yet - but I'm probably not the best person as I haven't actually used them in a functional language. I expect that D's meta-programming abilities will allow for some interesting things. BTW thanks for your template tutorial, it's been very helpful.
Aug 24 2012
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/21/2012 06:30 AM, Simen Kjaeraas wrote:
 On Tue, 21 Aug 2012 13:55:58 +0200, Regan Heath <regan netmail.co.nz>
 wrote:

 On the other hand, the suggested syntax of
 "bob?.department?.head?.name" from Kotlin is pure genius, and has a
 good chance of actually being used.

Absolutely. Probably hard to include in D though, as a ? .b is the beginning of a conditional expression.

There are many characters that has been neglected by D: bob⸮.department⸮.head⸮.name :p (If not visible on your screen, that character is U+2E2E.) Ali
Aug 21 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 21 Aug 2012 13:55:58 +0200, Regan Heath <regan netmail.co.nz>  
wrote:

 I don't buy the argument that having to explicitly type ".get" will stop  
 anyone from automatically coding statements like:

 val g: Option[T] = f.doSomething()
 g.get.doSomethingElse()

So don't give them that access? I have an Option struct on my home computer that only allows access to the held value if the error case is simultaneously handled: Option!int a = foo(); int n = a.match!( (int x) => x, (None n) => 0 // or throw, or what have you. ); The same solution is perfectly adaptable to MaybeNull, MaybeNan, and probably a host of others of the same family. With some clever use of opDispatch, one could write an Option struct that lets you call methods and acces members of the wrapped type, and return Option!ReturnType.
 On the other hand, the suggested syntax of "bob?.department?.head?.name"  
  from Kotlin is pure genius, and has a good chance of actually being  
 used.

Absolutely. Probably hard to include in D though, as a ? .b is the beginning of a conditional expression. -- Simen
Aug 21 2012
prev sibling next sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
 On the other hand, the suggested syntax of 
 "bob?.department?.head?.name" from Kotlin is pure genius, and 
 has a
 good chance of actually being used.

Absolutely. Probably hard to include in D though, as a ? .b is the beginning of a conditional expression.

How about bob??.department??.head??.name
Aug 21 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Tue, 21 Aug 2012 16:08:23 +0200, Carl Sturtivant <sturtivant gmail.com>  
wrote:

 On the other hand, the suggested syntax of  
 "bob?.department?.head?.name" from Kotlin is pure genius, and has a
 good chance of actually being used.

beginning of a conditional expression.

How about bob??.department??.head??.name

I guess that could work. Still won't happen though, but for other reasons. Also, reminded me of C's WTF operator: foo ??!??! exit(1); -- Simen
Aug 21 2012
prev sibling next sibling parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 21 Aug 2012 15:08:23 +0100, Carl Sturtivant <sturtivant gmail.com>  
wrote:

 On the other hand, the suggested syntax of  
 "bob?.department?.head?.name" from Kotlin is pure genius, and has a
 good chance of actually being used.

beginning of a conditional expression.

How about bob??.department??.head??.name

Hmm.. c# has another nice use for ?? http://msdn.microsoft.com/en-us/library/ms173224.aspx R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Aug 21 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Tuesday, 21 August 2012 at 14:29:56 UTC, Simen Kjaeraas wrote:
 On Tue, 21 Aug 2012 16:08:23 +0200, Carl Sturtivant 
 <sturtivant gmail.com> wrote:

 On the other hand, the suggested syntax of 
 "bob?.department?.head?.name" from Kotlin is pure genius, 
 and has a
 good chance of actually being used.

is the beginning of a conditional expression.

How about bob??.department??.head??.name

I guess that could work. Still won't happen though, but for other reasons. Also, reminded me of C's WTF operator: foo ??!??! exit(1);

That's brilliant. Surprised I haven't seen that before.
Aug 21 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Regan Heath:

 Plus, I don't buy the argument that having to explicitly type 
 ".get" will stop anyone from automatically coding statements 
 like:

 val g: Option[T] = f.doSomething()
 g.get.doSomethingElse()

 and suffering the exact same null pointer exception/error 
 despite using Option and boxing into a Not-Null type.

 Like checked exceptions people will simply ignore the 
 possibility of error and type the above anyway.  So, end 
 result, it's just more typing for no real gain.

Mark C. Chu-Carroll is very intelligent and well read, most times he's right. My Scala experience is limited, so I don't first-hand how much Mark is right this time. I think having a type for a reference/pointer that can't be null is useful. With it in many situations you need no "get", because there no risk of it being null. So the discussion here is for the other cases where you need a reference that can be null too. Such cases are surely just part of the cases where in D now you receive a generic nullable reference/pointer. So even if "get" is about as dangerous as normal references, the situation is better still. Time ago I have suggested a syntax like Foo to represent in D the subtype of Foo references that can't be null. Bye, bearophile
Aug 21 2012
prev sibling next sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
 There are many characters that has been neglected by D:

   bob⸮.department⸮.head⸮.name

 :p (If not visible on your screen, that character is U+2E2E.)

 Ali

Nice! No-one of the Ascii-Trapped would miss that: self documentation indeed.
Aug 21 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
On Tue, Aug 21, 2012 at 10:17 PM, Nick Treleaven <nospam example.net> wrote:
 On 21/08/2012 14:30, Simen Kjaeraas wrote:

 I have an Option struct on my home computer that only allows access to
 the held value if the error case is simultaneously handled:

 Option!int a = foo();

 int n = a.match!(
      (int x) => x,
      (None n) => 0 // or throw, or what have you.
      );

 The same solution is perfectly adaptable to MaybeNull, MaybeNan, and
 probably
 a host of others of the same family.

 With some clever use of opDispatch, one could write an Option struct that
 lets you call methods and acces members of the wrapped type, and return
 Option!ReturnType.

Apart from the opDispatch bit, I've been slowly working on something similar (Boost license): https://github.com/ntrel/d-maybe/blob/master/maybe.d I'm still working on it, but the basic ideas are there. I think the best bit is apply(), which supports passing multiple Maybe values, calling the delegate only if all Maybes are valid. In fact Maybe.map() is unnecessary due to apply().

Then, both Simen and you could code a generic algebraic datatype generator, with the associated matching functions (and probably mapping / reducing) Here come the whole Haskell / ML menagerie of types :) mixin(ADT(" Tree(T): Leaf(T) | Branch(Tree, Tree) ")); or something like that... And then encode JSON like this. Or update std.typecons.Algebraic to make it deal with recursive definitions...
Aug 22 2012
prev sibling next sibling parent Ziad Hatahet <hatahet gmail.com> writes:
--20cf3071c6f00aaea304c7de334a
Content-Type: text/plain; charset=ISO-8859-1

On Tue, Aug 21, 2012 at 4:55 AM, Regan Heath <regan netmail.co.nz> wrote:

 Plus, I don't buy the argument that having to explicitly type ".get" will
 stop anyone from automatically coding statements like:

 val g: Option[T] = f.doSomething()
 g.get.doSomethingElse()

 and suffering the exact same null pointer exception/error despite using
 Option and boxing into a Not-Null type.


 R

immutability, does that mean we have to do away with the concept just because there is a way around it? -- Ziad --20cf3071c6f00aaea304c7de334a Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable <br><div class=3D"gmail_quote">On Tue, Aug 21, 2012 at 4:55 AM, Regan Heath= <span dir=3D"ltr">&lt;<a href=3D"mailto:regan netmail.co.nz" target=3D"_bl= ank">regan netmail.co.nz</a>&gt;</span> wrote:<br><blockquote class=3D"gmai= l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left= :1ex"> <div class=3D"im">Plus, I don&#39;t buy the argument that having to explici= tly type &quot;.get&quot; will stop anyone from automatically coding statem= ents like:</div> <br> val g: Option[T] =3D f.doSomething()<br> g.get.doSomethingElse()<br> <br> and suffering the exact same null pointer exception/error despite using Opt= ion and boxing into a Not-Null type.<br> <br><span class=3D"HOEnZb"><font color=3D"#888888"><br> R<br> <br></font></span></blockquote><div><br></div><div>C++ and D have language = constructs to allow you to cast away const-ness and immutability, does that= mean we have to do away with the concept just because there is a way aroun= d it?</div> <div><br></div><div>=A0</div></div>--<br>Ziad --20cf3071c6f00aaea304c7de334a--
Aug 22 2012
prev sibling next sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
On Wed, 22 Aug 2012 19:37:09 +0200, Ziad Hatahet <hatahet gmail.com> wrote:

 C++ and D have language constructs to allow you to cast away const-ness  
 and
 immutability, does that mean we have to do away with the concept just
 because there is a way around it?

No, but a cast sticks out like a sore thumb. foo.get().bar() does not. -- Simen
Aug 22 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
 Time ago I have suggested a syntax like Foo  to represent in D 
 the subtype of Foo references that can't be null.

That would be nice. Anyhow a lot better as any library solution. But I think it will be resulting in a NotNullable struct in std.typecons...
Aug 22 2012
prev sibling next sibling parent "Namespace" <rswhite4 googlemail.com> writes:
Is there any special reason why these functions doesn't get 
"Maybe" as (const) ref?

void show(T)(Maybe!T m)
bool opEquals(Maybe!T m)
void opAssign(Maybe!T m)
Aug 23 2012
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
------------40urufvAXXMimgUFXTTUjc
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes
Content-Transfer-Encoding: 7bit

On Thu, 23 Aug 2012 18:27:41 +0200, Nick Treleaven <nospam example.net>  
wrote:

 I'd be interested to see your Option code.

Here you go. After looking at your code, and with Modern C++ Design fresh in mind, I see that match and hasValue might have worked better as free functions. I took the liberty of implementing the optional function calls discussed earlier. If your eyes glaze over or you feel an urge to kill, you are likely looking at that part of the code. -- Simen ------------40urufvAXXMimgUFXTTUjc Content-Disposition: attachment; filename=Option.d Content-Type: application/octet-stream; name="Option.d" Content-Transfer-Encoding: Base64 77u/aW1wb3J0IHN0ZC50cmFpdHM7DQoNCnN0cnVjdCBOb25lIHt9DQoNCg0KLy8N Ci8vIFBvc3NpYmxlIHBvaW50IG9mIHNwZWNpYWxpemF0aW9uIGZvciB0aGUgZnV0 dXJlIC0gdXNlIG51bGwgb3IgTmFOIHZhbHVlDQovLyB0byBkaXNjZXJuIG5vbmUt bmVzcy4NCi8vDQp0ZW1wbGF0ZSBoYXNOdWxsKCBUICkgew0KICAgIGVudW0gaGFz TnVsbCA9IF9fdHJhaXRzKCBjb21waWxlcywgKFQgdCkgPT4gdCBpcyBudWxsICk7 DQp9DQoNCi8vLw0KLy8vIEFuIG9wdGlvbmFsIHZhbHVlLg0KLy8vDQpzdHJ1Y3Qg T3B0aW9uKCBUICkgaWYgKCAhaGFzTnVsbCFUICkgew0KCXByaXZhdGUgYm9vbCBu b25lID0gdHJ1ZTsNCglwcml2YXRlIFQgcGF5bG9hZDsNCgkNCgl0aGlzKCBUIHQg KSB7DQoJCXBheWxvYWQgPSB0Ow0KCQlub25lID0gZmFsc2U7DQoJfQ0KCQ0KCXRo aXMoIE5vbmUgbiApIHsNCgkJbm9uZSA9IHRydWU7DQoJfQ0KCQ0KCXJlZiBPcHRp b24gb3BBc3NpZ24oIE5vbmUgbiApIHsNCgkJbm9uZSA9IHRydWU7DQoJCXJldHVy biB0aGlzOw0KCX0NCgkNCglyZWYgT3B0aW9uIG9wQXNzaWduKCBUIHQgKSB7DQoJ CXBheWxvYWQgPSB0Ow0KCQlub25lID0gZmFsc2U7DQoJCXJldHVybiB0aGlzOw0K CX0NCiAgICANCiAgICByZWYgT3B0aW9uIG9wQXNzaWduKCBPcHRpb24gb3RoZXIg KSB7DQogICAgICAgIG5vbmUgPSBvdGhlci5ub25lOw0KICAgICAgICBpZiAoIG5v bmUgKSB7DQogICAgICAgICAgICBwYXlsb2FkID0gb3RoZXIucGF5bG9hZDsNCiAg ICAgICAgfQ0KICAgICAgICByZXR1cm4gdGhpczsNCiAgICB9DQogICAgDQogICAg QHByb3BlcnR5IGNvbnN0DQogICAgYm9vbCBoYXNWYWx1ZSggKSB7DQogICAgICAg IHJldHVybiAhbm9uZTsNCiAgICB9DQogICAgDQogICAgLy8vDQogICAgLy8vIFBh dHRlcm4gbWF0Y2hpbmcuIFJlcXVpcmVzIHRoYXQgdGhlIHByb2dyYW1tZXIgaGFu ZGxlIGJvdGggdGhlIG5vcm1hbCBhbmQgdGhlIE5vbmUgY2FzZS4NCiAgICAvLy8N CiAgICBAcHJvcGVydHkNCglhdXRvIG1hdGNoKCBhbGlhcyBmbk5vbmUsIGFsaWFz IGZuUGF5bG9hZCApKCApDQogICAgaWYgKGlzKCB0eXBlb2YoIGZuTm9uZSggTm9u ZSggKSApICkgKSAmJiBpcyggdHlwZW9mKCBmblBheWxvYWQoIHBheWxvYWQgKSAp ICkgKSB7DQoJCWlmICggbm9uZSApIHsNCgkJCXJldHVybiBmbk5vbmUoIE5vbmUo ICkgKTsNCgkJfSBlbHNlIHsNCgkJCXJldHVybiBmblBheWxvYWQoIHBheWxvYWQg KTsNCgkJfQ0KCX0NCgkNCiAgICAvLy8gZGl0dG8NCiAgICBAcHJvcGVydHkNCglh dXRvIG1hdGNoKCBhbGlhcyBmblBheWxvYWQsIGFsaWFzIGZuTm9uZSApKCApDQog ICAgaWYgKGlzKCB0eXBlb2YoIGZuTm9uZSggTm9uZSggKSApICkgKSAmJiBpcygg dHlwZW9mKCBmblBheWxvYWQoIHBheWxvYWQgKSApICkgKSB7DQoJCWlmICggbm9u ZSApIHsNCgkJCXJldHVybiBmbk5vbmUoIE5vbmUoICkgKTsNCgkJfSBlbHNlIHsN CgkJCXJldHVybiBmblBheWxvYWQoIHBheWxvYWQgKTsNCgkJfQ0KCX0NCiAgICAN CiAgICAvLyBIZWxwZXIgdGVtcGxhdGUNCiAgICBwcml2YXRlIHRlbXBsYXRlIGlz UHJvcGVydHlJbXBsKCBUICkgew0KICAgICAgICBzdGF0aWMgaWYgKCAvKmlzRnVu Y3Rpb25Qb2ludGVyIVQgfHwgaXNEZWxlZ2F0ZSFUIHx8Ki8gaXMoVCA9PSBmdW5j dGlvbikgKSB7DQogICAgICAgICAgICBlbnVtIGlzUHJvcGVydHlJbXBsID0gZnVu Y3Rpb25BdHRyaWJ1dGVzIVQgJiBGdW5jdGlvbkF0dHJpYnV0ZS5wcm9wZXJ0eTsN CiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGVudW0gaXNQcm9wZXJ0eUlt cGwgPSB0cnVlOw0KICAgICAgICB9DQogICAgfQ0KICAgIA0KICAgIC8vIEhlbHBl ciB0ZW1wbGF0ZQ0KICAgIHByaXZhdGUgdGVtcGxhdGUgaXNQcm9wZXJ0eSggc3Ry aW5nIG5hbWUgKSB7DQogICAgICAgIGVudW0gaXNQcm9wZXJ0eSA9IGlzUHJvcGVy dHlJbXBsISh0eXBlb2YoX190cmFpdHMoIGdldE1lbWJlciwgVCwgbmFtZSApKSk7 DQogICAgfQ0KICAgIA0KICAgIC8vIEhlbHBlciB0ZW1wbGF0ZQ0KICAgIHByaXZh dGUgdGVtcGxhdGUgUHJvcGVydHlUeXBlKCBzdHJpbmcgbmFtZSApIHsNCiAgICAg ICAgc3RhdGljIGlmICggaXMoIHR5cGVvZiggX190cmFpdHMoIGdldE1lbWJlciwg VCwgbmFtZSApICkgPT0gZnVuY3Rpb24gKSApIHsNCiAgICAgICAgICAgIGFsaWFz IFJldHVyblR5cGUhKCBfX3RyYWl0cyggZ2V0TWVtYmVyLCBULCBuYW1lICkgKSBQ cm9wZXJ0eVR5cGU7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBhbGlh cyB0eXBlb2YoIF9fdHJhaXRzKCBnZXRNZW1iZXIsIFQsIG5hbWUgKSApIFByb3Bl cnR5VHlwZTsNCiAgICAgICAgfQ0KICAgIH0NCiAgICANCiAgICAvLyBIZWxwZXIg dGVtcGxhdGUNCiAgICBwcml2YXRlIHRlbXBsYXRlIGhhc1ZvaWRBc3NpZ25SZXN1 bHQoIHN0cmluZyBuYW1lICkgew0KICAgICAgICBhbGlhcyBQcm9wZXJ0eVR5cGUh bmFtZSBWOw0KICAgICAgICBlbnVtIGhhc1ZvaWRBc3NpZ25SZXN1bHQgPSBpcygg dHlwZW9mKCBfX3RyYWl0cyggZ2V0TWVtYmVyLCBULCBuYW1lICkgPSBWLmluaXQg KSA9PSB2b2lkKTsNCiAgICB9DQogICAgDQogICAgLy8vDQogICAgLy8vIEFjY2Vz c2VzIGZpZWxkcyBhbmQgcHJvcGVydGllcyBvZiB0aGUgd3JhcHBlZCB0eXBlLg0K ICAgIC8vLyBUaGUgcmV0dXJuZWQgdmFsdWUgd2lsbCBiZSBhbiBPcHRpb24sIG9y IHZvaWQgaW4gdGhlIGNhc2Ugb2Ygc2V0dGVycyByZXR1cm5pbmcgdm9pZC4NCiAg ICAvLy8gDQogICAgLy8vDQogICAgQHByb3BlcnR5DQogICAgYXV0byBvcERpc3Bh dGNoKCBzdHJpbmcgbmFtZSwgVS4uLiApKCBVIGFyZ3MgKQ0KICAgIGlmICggaXNQ cm9wZXJ0eSFuYW1lICYmIFUubGVuZ3RoIDwgMiApIHsNCiAgICAgICAgc3RhdGlj IGlmICggVS5sZW5ndGggPT0gMCApIHsNCiAgICAgICAgICAgIE9wdGlvbiEoIFBy b3BlcnR5VHlwZSFuYW1lICkgcmVzdWx0Ow0KICAgICAgICAgICAgaWYgKCAhbm9u ZSApIHsNCiAgICAgICAgICAgICAgICBtaXhpbiggInJlc3VsdCA9IHBheWxvYWQu IiB+IG5hbWUgfiAiOyIgKTsNCiAgICAgICAgICAgICAgICAvL3Jlc3VsdCA9IF9f dHJhaXRzKCBnZXRNZW1iZXIsIHBheWxvYWQsIG5hbWUgKTsNCiAgICAgICAgICAg IH0NCiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICAgIH0gZWxzZSAg ew0KICAgICAgICAgICAgc3RhdGljIGlmICggaGFzVm9pZEFzc2lnblJlc3VsdCFu YW1lICkgew0KICAgICAgICAgICAgICAgIGlmICggIW5vbmUgKSB7DQogICAgICAg ICAgICAgICAgICAgIG1peGluKCAicGF5bG9hZC4iIH4gbmFtZSB+ICIgPSBhcmdz WzBdOyIgKTsNCiAgICAgICAgICAgICAgICAgICAgLy9fX3RyYWl0cyggZ2V0TWVt YmVyLCBwYXlsb2FkLCBuYW1lICkgPSBhcmdzWzBdOw0KICAgICAgICAgICAgICAg IH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgT3B0aW9u ISggUHJvcGVydHlUeXBlIW5hbWUgKSByZXN1bHQ7DQogICAgICAgICAgICAgICAg aWYgKCAhbm9uZSApIHsNCiAgICAgICAgICAgICAgICAgICAgbWl4aW4oICJyZXN1 bHQgPSBwYXlsb2FkLiIgfiBuYW1lIH4gIiA9IGFyZ3NbMF07IiApOw0KICAgICAg ICAgICAgICAgICAgICAvL3Jlc3VsdCA9IF9fdHJhaXRzKCBnZXRNZW1iZXIsIHBh eWxvYWQsIG5hbWUgKSA9IGFyZ3NbMF07DQogICAgICAgICAgICAgICAgfQ0KICAg ICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7DQogICAgICAgICAgICB9DQogICAg ICAgIH0NCiAgICB9DQogICAgDQogICAgLy8vDQogICAgLy8vIEFjY2VzcyBtZW1i ZXIgZnVuY3Rpb25zIG9mIHRoZSB3cmFwcGVkIHR5cGUuDQogICAgLy8vIEluIHRo ZSBjYXNlIG9mIE5vbmUsIG5vIGZ1bmN0aW9uIGNhbGwgd2lsbCB0YWtlIHBsYWNl LCBhbmQgdGhlIHJldHVybiB2YWx1ZQ0KICAgIC8vLyB3aWxsIGJlIE9wdGlvbiFV LCB3aXRoIFUgYmVpbmcgdGhlIG9yaWdpbmFsIHJldHVybiB0eXBlLg0KICAgIC8v LyBJZiB0aGUgZnVuY3Rpb24gcmV0dXJucyB2b2lkLCB2b2lkIHdpbGwgYmUgcmV0 dXJuZWQgaGVyZSB0b28uDQogICAgLy8vDQogICAgYXV0byBvcERpc3BhdGNoKCBz dHJpbmcgbmFtZSwgVS4uLiApKCBVIGFyZ3MgKQ0KICAgIGlmICggIWlzUHJvcGVy dHkhbmFtZSApew0KICAgICAgICBhbGlhcyB0eXBlb2YoIG1peGluKCAicGF5bG9h ZC4iIH4gbmFtZSB+ICIoIGFyZ3MgKSIgKSApIFJldHVyblR5cGU7DQogICAgICAg IHN0YXRpYyBpZiAoIGlzKCBSZXR1cm5UeXBlID09IHZvaWQgKSApIHsNCiAgICAg ICAgICAgIGlmICggIW5vbmUgKSB7DQogICAgICAgICAgICAgICAgbWl4aW4oICJw YXlsb2FkLiIgfiBuYW1lIH4gIiggYXJncyApOyIgKTsNCiAgICAgICAgICAgICAg ICAvLyBfX3RyYWl0cyggZ2V0TWVtYmVyLCBwYXlsb2FkLCBuYW1lICkoIGFyZ3Mg KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAg IE9wdGlvbiFSZXR1cm5UeXBlIHJlc3VsdDsNCiAgICAgICAgICAgIGlmICggIW5v bmUgKSB7DQogICAgICAgICAgICAgICAgbWl4aW4oICJyZXN1bHQgPSBwYXlsb2Fk LiIgfiBuYW1lIH4gIiggYXJncyApOyIgKTsNCiAgICAgICAgICAgICAgICAvLyBy ZXN1bHQgPSBfX3RyYWl0cyggZ2V0TWVtYmVyLCBwYXlsb2FkLCBuYW1lICkoIGFy Z3MgKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7 DQogICAgICAgIH0NCiAgICB9DQp9DQoNCnZlcnNpb24gKCB1bml0dGVzdCApIHsN CiAgICBzdHJ1Y3QgUyB7DQogICAgICAgIGludCBuOw0KICAgICAgICANCiAgICAg ICAgQHByb3BlcnR5DQogICAgICAgIGZsb2F0IGYoICkgew0KICAgICAgICAgICAg cmV0dXJuIDAuMDsNCiAgICAgICAgfQ0KICAgICAgICBAcHJvcGVydHkNCiAgICAg ICAgZmxvYXQgZiggZmxvYXQgdmFsdWUgKSBjb25zdCB7DQogICAgICAgICAgICBy ZXR1cm4gMC4wOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBAcHJvcGVy dHkNCiAgICAgICAgZG91YmxlIGQoICkgew0KICAgICAgICAgICAgcmV0dXJuIDAu MDsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgQHByb3BlcnR5DQogICAg ICAgIHZvaWQgZCggZG91YmxlIHZhbHVlICkgew0KICAgICAgICB9DQogICAgICAg IA0KICAgICAgICB2b2lkIGZvbyggKSB7DQogICAgICAgIH0NCiAgICAgICAgDQog ICAgICAgIGludCBiYXIoICkgew0KICAgICAgICAgICAgcmV0dXJuIDM7DQogICAg ICAgIH0NCiAgICB9IHVuaXR0ZXN0IHsNCiAgICAgICAgT3B0aW9uIVMgczsNCiAg ICAgICAgDQogICAgICAgIGFzc2VydCggcy5pc1Byb3BlcnR5ISJuIiApOw0KICAg ICAgICBhc3NlcnQoIGlzKCBzLlByb3BlcnR5VHlwZSEibiIgPT0gaW50ICkgKTsN CiAgICAgICAgYXNzZXJ0KCAhcy5oYXNWb2lkQXNzaWduUmVzdWx0ISJuIiApOw0K ICAgICAgICBhc3NlcnQoIHMuaXNQcm9wZXJ0eSEiZiIgKTsNCiAgICAgICAgYXNz ZXJ0KCBpcyggcy5Qcm9wZXJ0eVR5cGUhImYiID09IGZsb2F0ICkgKTsNCiAgICAg ICAgYXNzZXJ0KCAhcy5oYXNWb2lkQXNzaWduUmVzdWx0ISJmIiApOw0KICAgICAg ICBhc3NlcnQoIHMuaXNQcm9wZXJ0eSEiZCIgKTsNCiAgICAgICAgYXNzZXJ0KCBp cyggcy5Qcm9wZXJ0eVR5cGUhImQiID09IGRvdWJsZSApICk7DQogICAgICAgIGFz c2VydCggcy5oYXNWb2lkQXNzaWduUmVzdWx0ISJkIiApOw0KICAgICAgICBhc3Nl cnQoICFzLmlzUHJvcGVydHkhImZvbyIgKTsNCiAgICAgICAgYXNzZXJ0KCAhcy5p c1Byb3BlcnR5ISJiYXIiICk7DQogICAgICAgIA0KICAgICAgICBhdXRvIGYgPSBz LmY7DQogICAgICAgIGFzc2VydCggaXMoIHR5cGVvZiggZiApID09IE9wdGlvbiFm bG9hdCApICk7DQogICAgICAgIGYgPSBzLmYgPSA0Ow0KICAgICAgICANCiAgICAg ICAgcy5kID0gNDsNCiAgICAgICAgDQogICAgICAgIHMuZm9vKCApOw0KICAgICAg ICANCiAgICAgICAgYXV0byBiID0gcy5iYXIoICk7DQogICAgICAgIGFzc2VydCgg aXMoIHR5cGVvZiggYiApID09IE9wdGlvbiFpbnQgKSApOw0KICAgIH0NCn0NCg0K dW5pdHRlc3Qgew0KICAgIE9wdGlvbiFpbnQgYTsNCiAgICBhc3NlcnQoICFhLmhh c1ZhbHVlICk7DQogICAgYSA9IDQ7DQogICAgYXNzZXJ0KCBhLmhhc1ZhbHVlICk7 DQogICAgYSA9IE5vbmUoICk7DQogICAgYXNzZXJ0KCAhYS5oYXNWYWx1ZSApOw0K ICAgIA0KICAgIGEgPSA0Ow0KICAgIA0KICAgIGludCBuID0gYS5tYXRjaCEoDQog ICAgICAgIChpbnQgeCkgID0+IHgsDQogICAgICAgIChOb25lIG4pID0+IDANCiAg ICApOw0KICAgIA0KICAgIGFzc2VydCggbiA9PSA0ICk7DQogICAgDQogICAgYSA9 IE5vbmUoICk7DQogICAgbiA9IGEubWF0Y2ghKA0KICAgICAgICAoaW50IHgpICA9 PiB4LA0KICAgICAgICAoTm9uZSBuKSA9PiAwDQogICAgKTsNCiAgICANCiAgICBh c3NlcnQoIG4gPT0gMCApOw0KfQ0KDQp2b2lkIG1haW4oICkgew0KfQ== ------------40urufvAXXMimgUFXTTUjc--
Aug 23 2012