This page is no longer maintained — Please continue to the home page at www.scala-lang.org

suggestion for argument passing by keyword

15 replies
Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.

I am working on a research prototype of safety-critical software for
air traffic control. One of my goals is to eliminate as many potential
sources of bugs as possible, both major and minor.

Passing arguments by keyword is a simple way to eliminate a whole
class of bugs. It goes beyond just checking argument types and checks
names too. Without it, if more than one argument in a list has the
same type, the compiler cannot tell if they were passed out of order.
Nor can anyone reading the source code, without referring to the
definition of the class, method, or function that the arguments are
being passed to.

For actual operational safety-critical code, I think that most if not
all arguments should be passed by keyword. An obvious exception is
when there is only one argument, although even there it enhances
documentation and does no harm.

The only minor problem with passing by keyword is that it requires
more typing and it sacrifices succinctness. That's where my suggestion
comes in.

I find that I often use the same name for an actual parameter that I
use for the corresponding formal parameter. If it's the best name in
one place, it's usually the best name in the other place too (unless
it's already taken).

Here's an extreme example of what I end up with:

Encounter(time=time, time0=time0,
timeToLOS=timeToLOS, timeToMin=timeToMin,
minSepRatio=minSepRatio, minSepRatH=minSepRatH,
minSepRatV=minSepRatV,
pos1atMin=pos1atMin, pos2atMin=pos2atMin,
pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
LOSnow=LOSnow, critLevel=critLevel)

As you can see, many names are repeated. (Not that it matters here,
but "Encounter" is a case class that stores data for a predicted
encounter between two flights, and "LOS" stands for "loss of
separation".)

My suggestion is to provide a simple syntax to avoid the repeats. One
possibility might be to keep the = but leave off the formal parameter
name if it is the same as the actual parameter name:

Encounter(time=, time0=, timeToLOS=, timeToMin=,
minSepRatio=, minSepRatH=, minSepRatV=,
pos1atMin=, pos2atMin=, pos1atLOS=, pos2atLOS=,
LOSnow=, critLevel=)

Another possibility might be to use some symbol:

Encounter(time=@, time0=@, timeToLOS=@, timeToMin=@,
minSepRatio=@, minSepRatH=@, minSepRatV=@,
pos1atMin=@, pos2atMin=@, pos1atLOS=@, pos2atLOS=@,
LOSnow=@, critLevel=@)

Other conventions are also possible. In any case, I realize that this
suggestion will probably go nowhere, but I thought I'd throw it out
there anyway just to see what happens.

--Russ P.

H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: suggestion for argument passing by keyword

intellij idea has an inspection for exactly that, at least for java :)
i don't know the exact details on how they perform the name matching,
but it has already found a few errors in my code. this doesn't have to
be solved at language level. and then there are tagged types:

http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagge...

this is also what you want, isn't it? instead of passing an int, you are
passing an int with intention X, the intention being the tagged type.
this is actually safer than your extreme example because the "name
taken"-problem doesn't exist.
and you could, at least theoretically, still write doIt(x=y,y=x). with
tagged types, this will turn into a compilation error.

Am 30.12.2011 06:13, schrieb Russ P.:
> I am working on a research prototype of safety-critical software for
> air traffic control. One of my goals is to eliminate as many potential
> sources of bugs as possible, both major and minor.
>
> Passing arguments by keyword is a simple way to eliminate a whole
> class of bugs. It goes beyond just checking argument types and checks
> names too. Without it, if more than one argument in a list has the
> same type, the compiler cannot tell if they were passed out of order.
> Nor can anyone reading the source code, without referring to the
> definition of the class, method, or function that the arguments are
> being passed to.
>
> For actual operational safety-critical code, I think that most if not
> all arguments should be passed by keyword. An obvious exception is
> when there is only one argument, although even there it enhances
> documentation and does no harm.
>
> The only minor problem with passing by keyword is that it requires
> more typing and it sacrifices succinctness. That's where my suggestion
> comes in.
>
> I find that I often use the same name for an actual parameter that I
> use for the corresponding formal parameter. If it's the best name in
> one place, it's usually the best name in the other place too (unless
> it's already taken).
>
> Here's an extreme example of what I end up with:
>
> Encounter(time=time, time0=time0,
> timeToLOS=timeToLOS, timeToMin=timeToMin,
> minSepRatio=minSepRatio, minSepRatH=minSepRatH,
> minSepRatV=minSepRatV,
> pos1atMin=pos1atMin, pos2atMin=pos2atMin,
> pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
> LOSnow=LOSnow, critLevel=critLevel)
>
> As you can see, many names are repeated. (Not that it matters here,
> but "Encounter" is a case class that stores data for a predicted
> encounter between two flights, and "LOS" stands for "loss of
> separation".)
>
> My suggestion is to provide a simple syntax to avoid the repeats. One
> possibility might be to keep the = but leave off the formal parameter
> name if it is the same as the actual parameter name:
>
> Encounter(time=, time0=, timeToLOS=, timeToMin=,
> minSepRatio=, minSepRatH=, minSepRatV=,
> pos1atMin=, pos2atMin=, pos1atLOS=, pos2atLOS=,
> LOSnow=, critLevel=)
>
> Another possibility might be to use some symbol:
>
> Encounter(time=@, time0=@, timeToLOS=@, timeToMin=@,
> minSepRatio=@, minSepRatH=@, minSepRatV=@,
> pos1atMin=@, pos2atMin=@, pos1atLOS=@, pos2atLOS=@,
> LOSnow=@, critLevel=@)
>
> Other conventions are also possible. In any case, I realize that this
> suggestion will probably go nowhere, but I thought I'd throw it out
> there anyway just to see what happens.
>
> --Russ P.
>

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: suggestion for argument passing by keyword

The "tagged types" approach looks interesting, but I think it is
overkill for the vast majority of cases. Setting up tagged types every
time I just want to make sure I didn't pass arguments of the same type
out of order would be too much extra boilerplate and code clutter.

Let's say I have a function (or method) that takes arguments for a
start time, a length in time, and a time step. All three are the same
type. I can call them something like "startTime, "timeLength," and
"timeStep" (or just "dt"). Passing them by keyword eliminates any
ambiguity. I would be very reluctant to set up tagged types for this
case.

My suggestion would just reduce the repetition of the names in the
common case where the argument names and the formal parameter names
are the same. It's a small benefit, but it might be worthwhile if the
implementation cost is also small.

--Russ P.

On Dec 30, 12:21 am, HamsterofDeath wrote:
> intellij idea has an inspection for exactly that, at least for java :)
> i don't know the exact details on how they perform the name matching,
> but it has already found a few errors in my code. this doesn't have to
> be solved at language level. and then there are tagged types:
>
> http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-ta...
>
> this is also what you want, isn't it? instead of passing an int, you are
> passing an int with intention X, the intention being the tagged type.
> this is actually safer than your extreme example because the "name
> taken"-problem doesn't exist.
> and you could, at least theoretically, still write doIt(x=y,y=x). with
> tagged types, this will turn into a compilation error.
>
> Am 30.12.2011 06:13, schrieb Russ P.:
>
>
>
>
>
>
>
> > I am working on a research prototype of safety-critical software for
> > air traffic control. One of my goals is to eliminate as many potential
> > sources of bugs as possible, both major and minor.
>
> > Passing arguments by keyword is a simple way to eliminate a whole
> > class of bugs. It goes beyond just checking argument types and checks
> > names too. Without it, if more than one argument in a list has the
> > same type, the compiler cannot tell if they were passed out of order.
> > Nor can anyone reading the source code, without referring to the
> > definition of the class, method, or function that the arguments are
> > being passed to.
>
> > For actual operational safety-critical code, I think that most if not
> > all arguments should be passed by keyword. An obvious exception is
> > when there is only one argument, although even there it enhances
> > documentation and does no harm.
>
> > The only minor problem with passing by keyword is that it requires
> > more typing and it sacrifices succinctness. That's where my suggestion
> > comes in.
>
> > I find that I often use the same name for an actual parameter that I
> > use for the corresponding formal parameter. If it's the best name in
> > one place, it's usually the best name in the other place too (unless
> > it's already taken).
>
> > Here's an extreme example of what I end up with:
>
> >     Encounter(time=time, time0=time0,
> >         timeToLOS=timeToLOS, timeToMin=timeToMin,
> >         minSepRatio=minSepRatio, minSepRatH=minSepRatH,
> >         minSepRatV=minSepRatV,
> >         pos1atMin=pos1atMin, pos2atMin=pos2atMin,
> >         pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
> >         LOSnow=LOSnow, critLevel=critLevel)
>
> > As you can see, many names are repeated. (Not that it matters here,
> > but "Encounter" is a case class that stores data for a predicted
> > encounter between two flights, and "LOS" stands for "loss of
> > separation".)
>
> > My suggestion is to provide a simple syntax to avoid the repeats. One
> > possibility might be to keep the = but leave off the formal parameter
> > name if it is the same as the actual parameter name:
>
> >     Encounter(time=, time0=, timeToLOS=, timeToMin=,
> >         minSepRatio=, minSepRatH=, minSepRatV=,
> >         pos1atMin=, pos2atMin=, pos1atLOS=, pos2atLOS=,
> >         LOSnow=, critLevel=)
>
> > Another possibility might be to use some symbol:
>
> >     Encounter(time=@, time0=@, timeToLOS=@, timeToMin=@,
> >         minSepRatio=@, minSepRatH=@, minSepRatV=@,
> >         pos1atMin=@, pos2atMin=@, pos1atLOS=@, pos2atLOS=@,
> >         LOSnow=@, critLevel=@)
>
> > Other conventions are also possible. In any case, I realize that this
> > suggestion will probably go nowhere, but I thought I'd throw it out
> > there anyway just to see what happens.
>
> > --Russ P.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: suggestion for argument passing by keyword
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.

A plugin that insisted on named methods might be interesting, however.

If it is _really_ important, then I agree with HamsterofDeath--you want types, not naming conventions, to help you out.  At the point where you call Encounter when already having everything computed, it would just be a hassle, but earlier on you could increase your confidence that you were computing the correct thing by making sure you have the right input types.

  --Rex

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: suggestion for argument passing by keyword
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure." That's precisely what the Encounter case class is. And no, I don't think the Encounter class is the right place to do the actual separation computations. Those computations are a complicated function of several potential trajectories that are predicted for each flight. (Trajectory prediction is not deterministic. Climb and descent rates cannot be predicted accurately, for example, since the weight of the aircraft isn't even known to the ground-based ATC systems, among other factors. Hence both "fast" and "slow" climb/descent predictions are needed to cover a range of possible rates. Keeping track of all the potential trajectories is a non-trivial job to say the least.)
The main purpose of the Encounter case class is to keep track of the results of the analysis of a predicted encounter. That includes encounters that are predicted to result from candidate maneuvers for conflict resolution. The Encounter class is also used for plotting the predicted encounter in detail to visualize exactly what is going on.
It's easy to say that something looks like "poor design" when you don't have a clue about the actual problem. Then again, maybe it really is poor design. If so, I'm open to suggestions about how to improve it. But suggestions from someone who doesn't understand the problem are not likely to be helpful. Thanks.
--Russ P.
--
http://RussP.us
ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: suggestion for argument passing by keyword


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex

Russ P.
Joined: 2009-01-31,
User offline. Last seen 1 year 26 weeks ago.
Re: suggestion for argument passing by keyword
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,       timeToLOS=timeToLOS, timeToMin=timeToMin,       minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,       pos1atMin=pos1atMin, pos2atMin=pos2atMin,       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,       LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,       minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,       LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us
d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: suggestion for argument passing by keyword

On Fri, Dec 30, 2011 at 06:11:04PM -0800, Russ Paielli wrote:
> possible. Passing arguments of the same type in the wrong order is perhaps
> a "shallow" bug that is likely to be discovered with sufficient testing,
> but it is still a potential bug that can be easily avoided in the first
> place by passing arguments by keyword. In combination with well chosen
> parameter names, passing by keyword also provides greatly enhanced
> documentation at calling sites.

I've worked in situations where all arguments were passed by keyword,
and where we were able to use shortcuts, similar to what you are proposing.

In doing this, we hit a class of bugs which parallels the positional
parameter bug you are talking about: semantic slippage of names. Two
methods might take a parameter with the same name, but whose meaning is
subtly different. In these cases, code often gets written passing "foo"
from A to B, even though B's foo parameter is subtly different.

Again, these errors are usually shallow and caught quickly, but
occasionally they can be a big deal. In fact, the syntactic shortcuts
which allowed use to e.g. match up parameter-names with variables in
scope (or in a mapping) tended to trick one into making these very
mistakes.

I only bring this up because I became convinced that by-name parameters
were better at supporting self-documenting code, but were specifically
*not* better at avoiding the situation where one "mixes up" the
parameters in a subtle way that type checks.

YMMV, of course.

ARKBAN
Joined: 2011-08-11,
User offline. Last seen 42 years 45 weeks ago.
Re: suggestion for argument passing by keyword
I agree with Rexx, the Encounter class is a good idea and making smaller pieces that compose the Encounter class will help even further. This is the Parameter Object pattern (http://c2.com/cgi/wiki?ParameterObject) if you want the technical name (at least that's the best fit pattern I've found).

I introduced this design into my previous work on satellite planning software and it greatly helped the clarity of new and old code -- we even found some bugs when refactoring old code! Also we didn't run into any performance issues with creating lots of objects (but was all in a .NET environment).

Looking at your code:
  • I found that whenever you add an index to arguments such as "pos1atMin' and "pos1atLOS" you are implicitly defining something that should be its own class.
  • The arguments "timeToLOS" and "LOSnow" look like you are defining what Joda Time refers to as an Interval (http://joda-time.sourceforge.net/api-release/index.html), a period of time with a fixed start and end time. I'd take a look at what Joda Time might offer you (or create your own if that suits you). Representing time is such a common problem in domains like this that creating good utility classes is worth the effort.

ARKBAN


On 12/30/2011 09:11 PM, Russ Paielli wrote:
CAHy81hMQ+PehjSV-xTubxpEufzQ2O5toKH9+oRouxQKY4AJyOw [at] mail [dot] gmail [dot] com" type="cite">Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,        timeToLOS=timeToLOS, timeToMin=timeToMin,        minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,        pos1atMin=pos1atMin, pos2atMin=pos2atMin,        pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,        LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,        minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,        LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com" rel="nofollow">ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com" target="_blank" rel="nofollow">ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us
Alex Cruise
Joined: 2008-12-17,
User offline. Last seen 2 years 26 weeks ago.
Re: suggestion for argument passing by keyword
On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.

I'm somewhat sympathetic to your request, but why not take a page from Java idiom and just rename the locals using a fixed pattern?
Also, in cases like this I find it helps to use a very rigid, columnar formatting style that makes visual pattern matching much easier.  IDEA's columnar selection tool (Shift-Alt-Insert to toggle) is very helpful.  Encounter(  time        = _time,   time0       = _time0,   timeToLOS   = _timeToLOS,   timeToMin   = _timeToMin,  minSepRatio = _minSepRatio,    minSepRatH  = _minSepRatH,  minSepRatV  = _minSepRatV,  pos1atMin   = _pos1atMin,    pos2atMin   = _pos2atMin,  pos1atLOS   = _pos1atLOS,   pos2atLOS   = _pos2atLOS,   LOSnow      = _LOSnow,   critLevel   = _critLevel)
-0xe1a
Cédric Beust ♔
Joined: 2011-06-17,
User offline. Last seen 42 years 45 weeks ago.
Re: suggestion for argument passing by keyword
It seems like you could easily address this problem by using the good old builder pattern:
Encounter e = Encounter.Builder.timeToLOS(timeToLOS)    .timeToMin(timeToMin)    ...     .build();
As an added benefit, the build() method can make sure the object was properly initialized).
-- Cédric




On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,       timeToLOS=timeToLOS, timeToMin=timeToMin,       minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,       pos1atMin=pos1atMin, pos2atMin=pos2atMin,       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,       LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,       minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,       LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us

marius
Joined: 2008-08-31,
User offline. Last seen 3 years 19 weeks ago.
Re: suggestion for argument passing by keyword
Except that the builder pattern assumes mutability of the builder not to mention the extra code one would have to write.
Marius

2011/12/31 Cédric Beust ♔ <cedric [at] beust [dot] com>
It seems like you could easily address this problem by using the good old builder pattern:
Encounter e = Encounter.Builder.timeToLOS(timeToLOS)     .timeToMin(timeToMin)    ...     .build();
As an added benefit, the build() method can make sure the object was properly initialized).
--  Cédric




On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,       timeToLOS=timeToLOS, timeToMin=timeToMin,       minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,       pos1atMin=pos1atMin, pos2atMin=pos2atMin,       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,       LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,       minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,       LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us


Chris Twiner
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: suggestion for argument passing by keyword

You can write immutable type safe builders as well http://www.tikalk.com/java/blog/type-safe-builder-scala-using-type-constraints

On Dec 31, 2011 9:58 AM, "Marius Danciu" <marius [dot] danciu [at] gmail [dot] com> wrote:
Except that the builder pattern assumes mutability of the builder not to mention the extra code one would have to write.
Marius

2011/12/31 Cédric Beust ♔ <cedric [at] beust [dot] com>
It seems like you could easily address this problem by using the good old builder pattern:
Encounter e = Encounter.Builder.timeToLOS(timeToLOS)     .timeToMin(timeToMin)    ...     .build();
As an added benefit, the build() method can make sure the object was properly initialized).
--  Cédric




On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,       timeToLOS=timeToLOS, timeToMin=timeToMin,       minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,       pos1atMin=pos1atMin, pos2atMin=pos2atMin,       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,       LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,       minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,       LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us


H-star Development
Joined: 2010-04-14,
User offline. Last seen 2 years 26 weeks ago.
Re: suggestion for argument passing by keyword
another possible solution: a curried function. make each parameter list take the proper type(s), and it cannot go wrong.
you'll lose the freedom to pick the initialization order, and you win less code to write: one method signature vs a complete builder

Am 31.12.2011 11:10, schrieb Chris Twiner:
SFDHg [at] mail [dot] gmail [dot] com" type="cite">

You can write immutable type safe builders as well http://www.tikalk.com/java/blog/type-safe-builder-scala-using-type-constraints

On Dec 31, 2011 9:58 AM, "Marius Danciu" <marius [dot] danciu [at] gmail [dot] com" rel="nofollow">marius [dot] danciu [at] gmail [dot] com> wrote:
Except that the builder pattern assumes mutability of the builder not to mention the extra code one would have to write.
Marius

2011/12/31 Cédric Beust ♔ <cedric [at] beust [dot] com" target="_blank" rel="nofollow">cedric [at] beust [dot] com>
It seems like you could easily address this problem by using the good old builder pattern:
Encounter e = Encounter.Builder.timeToLOS(timeToLOS)     .timeToMin(timeToMin)     ...     .build();
As an added benefit, the build() method can make sure the object was properly initialized).
--  Cédric




On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ [dot] paielli [at] gmail [dot] com> wrote:
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,        timeToLOS=timeToLOS, timeToMin=timeToMin,        minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,        pos1atMin=pos1atMin, pos2atMin=pos2atMin,        pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,        LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,        minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,        LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com" target="_blank" rel="nofollow">ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com" target="_blank" rel="nofollow">ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com" target="_blank" rel="nofollow">russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us



marius
Joined: 2008-08-31,
User offline. Last seen 3 years 19 weeks ago.
Re: suggestion for argument passing by keyword
I was referring to the "good old builder pattern" ... sure there are ways to make it immutable except that for a structure with several fields ( 5 + maybe) the code grows fairly big. Thus even something like:
Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

is much more succinct than the (im)mutable builder pattern. (... being relevant only if you care about succintness of course)
Marius

On Sat, Dec 31, 2011 at 12:10 PM, Chris Twiner <chris [dot] twiner [at] gmail [dot] com> wrote:

You can write immutable type safe builders as well http://www.tikalk.com/java/blog/type-safe-builder-scala-using-type-constraints

On Dec 31, 2011 9:58 AM, "Marius Danciu" <marius [dot] danciu [at] gmail [dot] com> wrote:
Except that the builder pattern assumes mutability of the builder not to mention the extra code one would have to write.
Marius

2011/12/31 Cédric Beust ♔ <cedric [at] beust [dot] com>
It seems like you could easily address this problem by using the good old builder pattern:
Encounter e = Encounter.Builder.timeToLOS(timeToLOS)     .timeToMin(timeToMin)    ...     .build();
As an added benefit, the build() method can make sure the object was properly initialized).
--  Cédric




On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
Yeah, that Encounter class does seem have a lot of stuff thrown in there more or less willy-nilly, but I don't think it's quite as bad as it seems. Each of those items is needed for one reason or another based on my past experience. Yes, there is probably a better way to group them. Thanks for the suggestion. I'll give it some thought.
Getting back to my original motivation, let me try to outline my thought process again. For safety-critical software, two things are important: (1) getting it right, and (2) making verification of correctness as simple as possible. Passing arguments of the same type in the wrong order is perhaps a "shallow" bug that is likely to be discovered with sufficient testing, but it is still a potential bug that can be easily avoided in the first place by passing arguments by keyword. In combination with well chosen parameter names, passing by keyword also provides greatly enhanced documentation at calling sites.
Here was my original example:
   Encounter(time=time, time0=time0,       timeToLOS=timeToLOS, timeToMin=timeToMin,       minSepRatio=minSepRatio, minSepRatH=minSepRatH,        minSepRatV=minSepRatV,       pos1atMin=pos1atMin, pos2atMin=pos2atMin,       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,       LOSnow=LOSnow, critLevel=critLevel)
Now, consider the same call without passing arguments by keyword:
   Encounter(time, time0, timeToLOS, timeToMin,       minSepRatio, minSepRatH, minSepRatV,        pos1atMin, pos2atMin, pos1atLOS, pos2atLOS,       LOSnow, critLevel)
Which case is more clearly correct? Obviously the first, because at least it is clear that the arguments are not out of order. For the second case, anyone who reads the code needs to go to the definition and verify the order. Yes, that may be simple with an IDE, but not everyone uses an IDE, and reading a printout is not unheard of.
I don't even claim to be an expert on safety-critical code. I'm sure I have a lot to learn yet. But it seems to me that the minor inconvenience of passing all (or nearly all) arguments by keyword is a small price to pay for the added clarity and safety that it achieves.
The same principle applies to explicit type declarations too, by the way. If an FAA regulator is trying to understand safety-critical code, he shouldn't be scratching his head and wasting time trying to figure out the return type of a function, either at the definition or at the calling site. The only acceptable place for type inference in that case is where the type is determined in the statement itself, as in "val x = 1".
If you agree with me about passing arguments by keyword for safety-critical code, then you will agree that passing by keyword should be common in such code. In that case, the repetition of names, as in my example above, could become annoying, and you might appreciate my proposal for eliminating the repetition. Otherwise you won't. It's that simple.
--Russ P.

On Fri, Dec 30, 2011 at 2:39 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:


On Fri, Dec 30, 2011 at 5:23 PM, Russ Paielli <russ [dot] paielli [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 1:14 PM, Rex Kerr <ichoran [at] gmail [dot] com> wrote:
On Fri, Dec 30, 2011 at 12:13 AM, Russ P. <russ [dot] paielli [at] gmail [dot] com> wrote:
Here's an extreme example of what I end up with:

   Encounter(time=time, time0=time0,
       timeToLOS=timeToLOS, timeToMin=timeToMin,
       minSepRatio=minSepRatio, minSepRatH=minSepRatH,
       minSepRatV=minSepRatV,
       pos1atMin=pos1atMin, pos2atMin=pos2atMin,
       pos1atLOS=pos1atLOS, pos2atLOS=pos2atLOS,
       LOSnow=LOSnow, critLevel=critLevel) 

As you can see, many names are repeated.

My sense is that this isn't much of an issue--the repeated names, not the use of method argument names--because this looks like poor design to begin with.  If all these values are known already, they should be bundled up into appropriate data structures; if they're not, many should be calculated right here instead of being assigned to a variable and then the variable being passed to the method.


That's exactly what I'm doing here, Rex. I'm bundling into an "appropriate data structure."

Well, you have an awful lot bundled into one data structure.  That really increases the burden of making sure your arguments are in the right order.  _Maybe_ this is the best way to do it in your case (though I am doubtful).  Even if it is the correct thing to do in your case, it is usually the wrong thing to do in most other cases, so I would hesitate to introduce the feature just because you've run into a case where it is sensible to do this.

Personally, I would think
  case class Snapshot(time: Long, pos1: Vec3, pos2: Vec3) {}
  case class Separation(ratio: Double, ratH: Double, ratV: Double) {}
  Encounter(time, time0, snapLOS, snapMin, sepMin, LOSnow, critLevel)
would be a good start towards modularizing repeated concerns and reducing type ambiguity at the same time.

  --Rex




--
http://RussP.us



fanf
Joined: 2009-03-17,
User offline. Last seen 2 years 30 weeks ago.
Re: suggestion for argument passing by keyword

Le 31/12/2011 03:19, Alex Cruise a écrit :
> On Fri, Dec 30, 2011 at 6:11 PM, Russ Paielli columnar selection tool (Shift-Alt-Insert to toggle) is very helpful.
> Encounter(
> time = _time,
> time0 = _time0,
> timeToLOS = _timeToLOS,
> timeToMin = _timeToMin,
> minSepRatio = _minSepRatio,
> minSepRatH = _minSepRatH,
> minSepRatV = _minSepRatV,
> pos1atMin = _pos1atMin,
> pos2atMin = _pos2atMin,
> pos1atLOS = _pos1atLOS,
> pos2atLOS = _pos2atLOS,
> LOSnow = _LOSnow,
> critLevel = _critLevel
> )

In my company, we have adopted that formatting, that is even nicer[1] to
use as soon as the "that's too weird" effect disappears:

Encounter(
time = _time
, time0 = _time0
, timeToLOS = _timeToLOS
, timeToMin = _timeToMin
, minSepRatio = _minSepRatio
, minSepRatH = _minSepRatH
, minSepRatV = _minSepRatV
, pos1atMin = _pos1atMin
, pos2atMin = _pos2atMin
, pos1atLOS = _pos1atLOS
, pos2atLOS = _pos2atLOS
, LOSnow = _LOSnow
, critLevel = _critLevel
)

I believe I saw it for the first time on that mailing-list, founding it
really awful, but it is really nice to use ("," are more visible,
adding/removing items seems simpler - it seems that we more often
add/remove things at the end of the list than at the top of it), and
well... It goes well with the two-space indent syntax of Scala).

Thanks,

[1] based on a statically significant set of 3 people, with a 100%
agreement outcome.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland