JOIN
Get Time
forums  Revision History
Search My Post History  |  My Watches  |  User Settings
Forums Round Tables General Career Discussions Re: Foiled by a Div2-250! Revision History (2 edits)
Re: Foiled by a Div2-250! (response to post by d000hg)
I would implement exactly what I am asked first, without any validation. I would spell out the preconditions in comments. Then I would explain in what situations I would also write validation code and then I would also write the validation code. If they don't want the validation code they will stop you. What is important is to communicate what is your plan and what are you are doing while you are writing code. When you finish writing the code you should have a pretty good idea on what input it works.

In industry you would write validation code almost for each method. In the unlikely case that you have tools that check automatically that private methods are always called with valid data (which could be done for simple things such as nullness) then you can skip the ugly validation code.

Why do I say it's ugly? See these two pieces of code.

private Rational div(Rational a, Rational b) {
  if (a == null) throw BlaBlaException("error in Rational.div: null a");
  if (b == null) throw BlaBlaException("error in Rational.div: null b");
  if (b.getDenominator() == 0)
    throw BlaBlaException("error in Rational.div: division by zero");
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}
And this.

/*@ requires b.getDenominator() != 0; */
private /*@non_null*/ Rational div(/*@non_null*/ Rational a, /*@non_null*/ Rational b) {
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}
For the second one there are compilers that generate the equivalent of the IFs in the first one. There are also static tools that check whether the contract is always satisfied. It's shorter, though not as short as it could be if backwards compatibility would not be an issue. For example, in Spec# it looks like this.
private Rational! div(Rational! a, Rational! b) 
requires b.getDenominator() != 0;
{
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}

The big problem is that the tools I'm talking about, especially the ones that do static verification, are far from being good enough for normal use. But we'll get there :)

edit: the method should be static to make sense and I didn't pay too much attention to correctness (i don't have a coeherent way of treating a 0 denominator). The point was only to illustrate what can be done if the language supports contracts. [oh, and the first time i mixed denominators/numerators -- I always forget which is which in English. I had to fix that].
Re: Foiled by a Div2-250! (response to post by d000hg)
I would implement exactly what I am asked first, without any validation. I would spell out the preconditions in comments. Then I would explain in what situations I would also write validation code and then I would also write the validation code. If they don't want the validation code they will stop you. What is important is to communicate what is your plan and what are you are doing while you are writing code. When you finish writing the code you should have a pretty good idea on what input it works.

In industry you would write validation code almost for each method. In the unlikely case that you have tools that check automatically that private methods are always called with valid data (which could be done for simple things such as nullness) then you can skip the ugly validation code.

Why am I say it's ugly? See these two pieces of code.

private Rational div(Rational a, Rational b) {
  if (a == null) throw BlaBlaException("error in Rational.div: null a");
  if (b == null) throw BlaBlaException("error in Rational.div: null b");
  if (b.getDenominator() == 0)
    throw BlaBlaException("error in Rational.div: division by zero");
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}
And this.

/*@ requires b.getDenominator() != 0; */
private /*@non_null*/ Rational div(/*@non_null*/ Rational a, /*@non_null*/ Rational b) {
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}
For the second one there are compilers that generate the equivalent of the IFs in the first one. There are also static tools that check whether the contract is always satisfied. It's shorter, though not as short as it could be if backwards compatibility would not be an issue. For example, in Spec# it looks like this.
private Rational! div(Rational! a, Rational! b) 
requires b.getDenominator() != 0;
{
  return new Rational(
    a.getNumerator() * b.getDenominator(),
    a.getDenominator() * b.getNumerator()
  );
}

The big problem is that the tools I'm talking about, especially the ones that do static verification, are far from being good enough for normal use. But we'll get there :)

edit: the method should be static to make sense and I didn't pay too much attention for correctness (i don't have a coeherent way of treating a 0 denominator). The point was only to illustrate what can be done if the language supports contracts. [oh, and the first time i mixed denominators/numerators -- I always forget which is which in English. I had to fix that].
Re: Foiled by a Div2-250! (response to post by d000hg)
I would implement exactly what I am asked first, without any validation. I would spell out the preconditions in comments. Then I would explain in what situations I would also write validation code and then I would also write the validation code. If they don't want the validation code they will stop you. What is important is to communicate what is your plan and what are you are doing while you are writing code. When you finish writing the code you should have a pretty good idea on what input it works.

In industry you would write validation code almost for each method. In the unlikely case that you have tools that check automatically that private methods are always called with valid data (which could be done for simple things such as nullness) then you can skip the ugly validation code.

Why am I say it's ugly? See these two pieces of code.

private Rational div(Rational a, Rational b) {
  if (a == null) throw BlaBlaException("error in Rational.div: null a");
  if (b == null) throw BlaBlaException("error in Rational.div: null b");
  if (b.getDenominator() == 0)
    throw BlaBlaException("error in Rational.div: division by zero");
  return new Rational(
    a.getDenominator() * b.getNominator(),
    a.getNominator() * b.getDenominator()
  );
}
And this.

/*@ requires b.getDenominator() != 0; */
private /*@non_null*/ Rational div(/*@non_null*/ Rational a, /*@non_null*/ Rational b) {
  return new Rational(
    a.getDenominator() * b.getNominator(),
    a.getNominator() * b.getDenominator()
  );
}
For the second one there are compilers that generate the equivalent of the IFs in the first one. There are also static tools that check whether the contract is always satisfied. It's shorter, though not as short as it could be if backwards compatibility would not be an issue. For example, in Spec# it looks like this.
private Rational! div(Rational! a, Rational! b) 
requires b.getDenominator() != 0;
{
  return new Rational(
    a.getDenominator() * b.getNominator(),
    a.getNominator() * b.getDenominator()
  );
}

The big problem is that the tools I'm talking about, especially the ones that do static verification, are far from being good enough for normal use. But we'll get there :)