News for hackers. Stuff that matters.
Re:The Second Edition of “Refactoring” by quietbritishjim on Saturday December 01, 2018 @06:21PM (#18579649)
I remember having exactly the same experience, including the anticipation that I would benefit from it the way I would from Design Patterns. For most of the refactorings in the book, a bullet point in a list would've seemed a bit excessive, never mind a step-by-step sequence of instructions. In the end I literally threw the book away – the only technical book I've ever done that to.

I distinctly remember one of the things in the book, which in retrospect isn't even really a refactoring, called something like "null object". The idea was that if you were going to return null from a function (e.g. get student by ID but that ID doesn't exist) then you could instead return a concrete singleton object that represented null. That way, if you forgot to check for it then at least your program wouldn't crash. Now, the merits of this idea are debatable and I don't think I've ever used it in the years since. But I strongly remember thinking at the time that it was the only idea in the book that wasn't totally obvious.

There was a good chapter early on about testing, which I think was my first exposure to that idea. It was a bit brief but that's not a surprise given it was a bit of a digression from the main topic. A whole book on that might've been quite a bit more interesting.

Re:The Second Edition of “Refactoring” by dennisgorelik on Saturday December 01, 2018 @11:24PM (#18580779)
> if you forgot to check for it then at least your program wouldn't crash

If I forgot to check for null (or missing data) then I would rather have my program to raise an exception (to prevent data corruption). Then my error handling code will email that exception to me. I will analyze exception message (NPE) and stack trace. Then I will fix my program and deploy it to production.

Re:The Second Edition of “Refactoring” by Too on Sunday December 02, 2018 @02:58AM (#18581336)
Depends on the context. In game engines it's quite common to just render a generic pattern when a texture could not be found, instead of crashing the whole game. That's a good use for this pattern, not so good example would be in a bank transaction backend.
Re:The Second Edition of “Refactoring” by joshka on Sunday December 02, 2018 @03:03AM (#18581347)
I use this pattern fairly regularly in a variety of ways. Here's a quick piece of example code that might help explain this a bit better. I'm writing this example in C#, but I usually work in other languages (Java / ruby / Python / JS),

before:

  public Student GetStudentById(int id)
  {
    var record = db.findStudentById(id)
    if (record == null) return null;
    return new Student(record.id, record.name, ...);
  }
Then in say a student record controller class:

  public View Get(int id)
  {
    var student = getStudentById(id);
    if (student == null) return View("NotFound");
    return View("Display", student);
  }
After:

  [ContractAnnotation("=> notnull")]
  public StudentSearchResult GetStudentById(int id)
  {
    var record = db.findStudentById(id);
    if (record == null) return StudentSearchRsult.NotFound;
    return new StudentSearchResult(record.id, record.name, ...);
  }
Then:

  public View Get(int id)
  {
    var student = getStudentById(id);
    return new View(student.ViewName, student); // look no null check becase student.ViewName is always valid here
  }
Note: of course this is entirely simplified for the purposes of example. Perhaps your real world example doesn't return null from the db, but a RecordSet with either 0 or 1 elements. Perhaps your db uses exceptions that you translate into results like this.

The cool thing there is that you get tool support (from e.g. ReSharper) telling your that this is entirely safe to do without a null check and tool support when it's not.

Re:The Second Edition of “Refactoring” by goto11 on Sunday December 02, 2018 @08:49AM (#18582282)
But then the 'Student' object does not represent a student but represent the result of a search which may or may not be a student, and this result decides its own view. Effectively the model is coupled to a specific view, which seems wrong to me. I would much prefer to have the search return an Option<Student> and then have the controller select the view based on this option. This also makes it explicit that the search may nor return a result, which is not really explicit if it always returns a Student instance.
Re:The Second Edition of “Refactoring” by joshka on Tuesday December 04, 2018 @08:56PM (#18605171)
Note the explicit change to StudentSearchResult over student there to make your last comment kind of a yes, I agree and that was the intent...

There are many ways that this can be implemented that avoid an if result != null / == no value, often a map suffices.

Re:The Second Edition of “Refactoring” by myth_buster on Saturday December 01, 2018 @08:53PM (#18580286)
Re:The Second Edition of “Refactoring” by endgame on Sunday December 02, 2018 @01:01AM (#18581059)
Thinking more about this, null object are meant to be neutral with respect to some behaviour, but that behaviour isn't really specified alongside the object. It seems like it's a weaker reinvention of the idea of an "identity element" from e.g., the `Monoid` typeclass. I say "weaker" because `Monoid` specifies the neutral element (`mempty`) alongside the behaviour (`mappend`), whereas the null object pattern does not.
Re:The Second Edition of “Refactoring” by paulddraper on Saturday December 01, 2018 @11:32PM (#18580806)
Ay ay ay.

This is basically a workaround for a defect of certain typed programming languages that allow null everywhere.

Worst mistake of computer science.

https://www.lucidchart.com/techblog/2015/08/31/the-worst-mis...

Re:The Second Edition of “Refactoring” by goto11 on Sunday December 02, 2018 @08:55AM (#18582311)
No really, it is almost the opposite. The mistake was to have null be a valid value for all object types. Languages where nullability is represent in the type system (e.g. Typescript) does not have this problem. But the null-object pattern introduces the same problem in a new way.
Re:The Second Edition of “Refactoring” by paulddraper on Sunday December 02, 2018 @05:54PM (#18585096)
In languages without "everything can be null", the null-object pattern is what is always done.

The problem with "everything can be null" is the type system is prevented from finding very common "you can't do this thing" errors.

Without it, everyone uses null objects (or Maybe, a generic for of this) and there are no segmentation faults/dereferencing errors. (Yes there can be other sorts of errors, but the problem has been made far better.)

Re:The Second Edition of “Refactoring” by goto11 on Sunday December 02, 2018 @06:18PM (#18585211)
The "Null object pattern" is a particular pattern where missing values are represented with an object with "neutral" behavior. This is not the same as an actual null or an option type.