adrianb@queets.stat.washington.edu (Adrian Baddeley) (08/15/89)
In article <612@windy.dsir.govt.nz> Robert writes: >This is to support Doug Lea's proposal for "named return values". I >don't want to comment on the specific syntax he proposed - simply to say >we need a better way of getting objects back from functions. Also, what about named arguments? If we ever get a C++ interpreter, we could have problems in calling functions with lots of arguments. Interactive statistical packages (like 'S') use named arguments, e.g. z <- scatplot(x, y, scale=3) Here `scatplot' could be a function that makes a scatter plot object from the vectors x and y; it would be sensible to have zillions of options, scatplot(x,y,aspect,scale,xtitle,ytitle,xmargin,ymargin,etc..) the options need sensible defaults of course. Is there a better solution?? ---- adrianb@castor.ms.washington.edu (until 21 august 1989) Adrian Baddeley, visiting Department of Statistics GN-22, University of Washington, Seattle WA 98195, USA. tel (U of W): +1 206 545-2617 / 543-7237
neal@cs.rochester.edu (Neal Gafter) (08/16/89)
In article <2179@uw-entropy.ms.washington.edu> adrianb@queets.stat.washington.edu (Adrian Baddeley) writes: > Also, what about named arguments? Named arguments provide a further method for overload resolution and allow parameters other than the last ones in the argument list to be omitted/defaulted. I have noot seen a good syntax proposed for named arguments, so let me make a specific proposal that is upwardly-compatible with C++, seems natural (at least to me), and introduces no ambiguities: extern int distance(int x, int y, int z, float scale = 1.0); main() { extern int x1, y1, z1; extern float scale; int result = distance(scale: scale1, x: x1, y: y1, z: z1); } Opinions? -- Arpa: neal@cs.rochester.edu (Neal Gafter) UUCP: ...{rocksvax|allegra|decvax}!rochester!neal USnail: Department of Computer Science, U. of Rochester, N.Y. 14627 phone: (716) 275 - 1348 (office) or (716) 473 - 2361 (home)
adrianb@elk.stat.washington.edu (Adrian Baddeley) (08/16/89)
In article <NEAL.89Aug15144003@jabbah.cs.rochester.edu> Neal Gafter writes: >I have not seen a good syntax proposed for named arguments, so let me >make a specific proposal that is upwardly-compatible with C++, seems >natural (at least to me), and introduces no ambiguities: > >extern int distance(int x, int y, int z, float scale = 1.0); > int result = distance(scale: scale1, x: x1, y: y1, z: z1); > >Opinions? Looks good. The calling syntax resembles an interpreter that I once wrote for image processing. (It didn't have your nice declaration syntax.) y = subset(x, margin:10) z = transform(x, table: y ) print(x, copies:2, title:"Image X", pipe:"lpr -Pps") This seemed to satisfy users (as does 'S'). 'S' has a mechanism for testing in the function body whether a named argument was present in the function call, even if it was assigned the default value. Is this a good idea??? ---- adrianb@castor.ms.washington.edu (until 21 august 1989) Adrian Baddeley, visiting Department of Statistics GN-22, University of Washington, Seattle WA 98195, USA. tel (U of W): +1 206 545-2617 / 543-7237
usenet@lll-winken.LLNL.GOV (Usenet news admin) (08/16/89)
In article <2179@uw-entropy.ms.washington.edu> adrianb@castor.ms.washington.edu writes: > Also, what about named arguments? > [...] > Interactive statistical packages (like 'S') use > named arguments, e.g. > > z <- scatplot(x, y, scale=3) > > Here `scatplot' could be a function that makes a scatter plot object > from the vectors x and y; it would be sensible to have zillions > of options, > scatplot(x,y,aspect,scale,xtitle,ytitle,xmargin,ymargin,etc..) > the options need sensible defaults of course. > > Is there a better solution?? > From: jac@muslix.llnl.gov (James Crotinger) Path: muslix!jac I've often wondered why C++ default arguments have to obey this silly rule of requiring you specify the leftmost arguments. Either the named argument approach (ala above and...Fortran), or the approach taken by REXX (and probably other languages) where you just use commas to delimit the missing arguments: z = scatplot(x, y,, scale) Is there a good reason that one of these isn't used? >adrianb@castor.ms.washington.edu (until 21 august 1989) Jim
zhu@csli.Stanford.EDU (Lei Zhu) (08/16/89)
In article <NEAL.89Aug15144003@jabbah.cs.rochester.edu> neal@cs.rochester.edu (Neal Gafter) writes: >I have noot seen a good syntax proposed for named arguments, so let me >make a specific proposal that is upwardly-compatible with C++, seems >natural (at least to me), and introduces no ambiguities: > >extern int distance(int x, int y, int z, float scale = 1.0); > >main() >{ > extern int x1, y1, z1; > extern float scale; > > int result = distance(scale: scale1, x: x1, y: y1, z: z1); >} >Opinions? That reminds me of keyword arguments in lisp, even the syntax is similar. Your example would be like (distance :scale scale1 :x x1 :y y1 :z z1) in lisp. I find this feature to be especially useful when there isn't a natural orderings of parameters and/or there are lots of parameters. Anyway, I think it's a good idea and your syntax is about as good as I can of. Just my two cents, --Lei
wright@hsi.UUCP (Gary Wright) (08/16/89)
In article <2179@uw-entropy.ms.washington.edu> adrianb@castor.ms.washington.edu writes: > If we ever get a C++ interpreter, we could have problems > in calling functions with lots of arguments. Having procedures or functions with many parameters is probably an indication that you need to redesign your classes. > > Interactive statistical packages (like 'S') use > named arguments, e.g. > > z <- scatplot(x, y, scale=3) > > Here `scatplot' could be a function that makes a scatter plot object > from the vectors x and y; it would be sensible to have zillions > of options, > scatplot(x,y,aspect,scale,xtitle,ytitle,xmargin,ymargin,etc..) > the options need sensible defaults of course. > > Is there a better solution?? I have admittedly little experience in object oriented programming but I have been reading quite a bit lately so I'll take a stab at a better solution. It seems to me that the solution is to use the OO paradigm when designing the scatplot object. The scatplot object should be defined with all the necessary attributes. When the object is created, the attributes get appropriate default values. The attributes are changed by what Booch in _Software_Components_with_Ada_ calls "constructors" (in C++ terminology, member functions that change the state of an object). Using an Eiffel-like syntax: plot : SCATTER_PLOT; plot.Create; -- plot object is created with possibly default values for -- for attributes. For example scale would default to 1. plot.set_points(x, y); plot.set_scale(3); plot.set_xtitle("The is the title for the X axis"); -- more attributes can be modified here plot.display;-- And now display the object While some may say that this is just too verbose. I would make the same argument for: scatplot( xvector => x , yvector => y, aspect => aspect, scale => 2, xtitle => "The X axis", ytitle => "The Y axis", ... ); If you just wanted to change the scale from the default then we have: scatplot( xvector => x, yvector => y, scale => 3); versus plot.Create; plot.set_points( x, y); plot.set_scale( 3 ); What if you want to change the scale and redisplay the object? plot.display; plot.set_scale(3); plot.display; The other method does not provide a solution because all the unnamed arguments will be set to defaults. In other words if you use the first method, than you are going to need seperate procedures to set individual attributes anyway. I think the second method is simpler (no need to introduce named arguments for one). It also allows the compiler to be smart and to inline the appropriate functions unlike the more complex constructor which is not a good candidate for inlining. Well, now that I have mentioned C++, Eiffel, and Ada in one article, I should be in for some interesting mail... -- Gary Wright ...!uunet!hsi!wright Health Systems International wright@hsi.com
jima@hplsla.HP.COM (Jim Adcock) (08/17/89)
Seems to me passing everything in long function parameter lists, so long that you need to give parameters names, offer a zillion options, etc, etc, is the antithesis of object oriented programming, and is just the opposite direction of where C++ programming should be going. Instead, all those parameters and options should be represented in the state of the underlying object, not represented a gigantic list of options to one function. Options are invoked by calling a method, with perhaps a parameter or two, to turn on that option. The option being turned on is uniquely represented by the name of the method called -- not the name of a named argument supplied to that option. Defaults are established by the constructor to an object, so that optional methods need not be called for standard usage. someClass myObject; myObject.someOption; myObject.someParameter(paramvalue); myObject.someOption(withAParameter); myObject.doSomething; As opposed to: doSomething(myStructure, someOption=TRUE, someParameter=paramvalue, someParameteredOption=withAParameter); Long parameter list simply indicate one is still doing functional programming rather than object oriented programming. 99.9% of object oriented programming should be done with zero, one, or two parameters. The simple default parameter capabilities built into C++ handle these cases well. Named parameters would simply encourage people to continue hack functional programming, rather than making the mental switch to object oriented programming.
nagle@well.UUCP (John Nagle) (08/17/89)
In article <30765@lll-winken.LLNL.GOV> jac@muslix.UUCP (James Crotinger) writes: > ... or the approach >taken by REXX (and probably other languages) where you just use commas >to delimit the missing arguments: > > z = scatplot(x, y,, scale) > >Is there a good reason that one of these isn't used? When a large number of optional, positional arguments are allowed, the call can get a bit painful. z = plot(x,y,,,,,,1,,,'c'); is not something one finds desirable. This sort of thing is a curse of some mainframe job control languages. We don't want to bring it back. One major advantage of named, optional arguments, is that when it becomes necessary to add a new feature to a package, or to delete an unused one, all the callers of the package need not be revised. Whatever solution is chosen should definitely retain this property. John Nagle
alonzo@microsoft.UUCP (Alonzo Gariepy) (08/18/89)
Lasciate Ogne Named Arguments, Voi ch'Entrate! In article <6590229@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: >Seems to me passing everything in long function parameter lists, so >long that you need to give parameters names, offer a zillion options, etc, >etc, is the antithesis of object oriented programming, and is just the >opposite direction of where C++ programming should be going. Bravo! Listen to this man and abandon your Named arguments. Consider the smalltalk method, replaceFrom:to:with:, invoked as: anIndexedCollection replaceFrom: x to: y with: aCollection. Who needs named arguments? You might have another method with the name, replaceTo:with:, where the starting index defaults to 1. Anything more complicated than this simple variation (reflected in the name) is unnecessary. Since methods should generally contain no more than a dozen or two lines, long parameter lists are probably symptomatic of design rot. If you have to set several attributes of an object before beginning an action, it can be done with several calls. If the call needs two sets of three dimensional coordinates (six parameters total) these are better passed as two 3D Point objects, at least if you buy much of the object-oriented programming religion. My preference is to do away with default arguments altogether, especially the way they are implemented in C++ (i.e., only trailing arguments may be omitted). Alonzo Gariepy // These opinions do not reflect alonzo@microsoft // the policy of Microsoft Corp.
arn@apple.com (Arn Schaeffer) (08/18/89)
In article <6590229@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: > Instead, all those parameters and options should be represented in the > state of the underlying object, not represented a gigantic list of options > to one function. Options are invoked by calling a method, with perhaps > a parameter or two, to turn on that option. The option being turned on > is uniquely represented by the name of the method called -- not the name > of a named argument supplied to that option. Defaults are established > by the constructor to an object, so that optional methods need not be > called for standard usage. This could have severe implications if an object was shared by more than one process. In general, it seems that ephemeral information like parameters should not be part of the state of the object. Arnold Schaeffer arn@apple.com The opinions expressed are not necessarily those of Apple Computer.
t-robje@microsoft.UUCP (Rob Jellinghaus) (08/19/89)
In article <3671@internal.Apple.COM> arn@apple.com (Arn Schaeffer) writes: >In article <6590229@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: >> Instead, all those parameters and options should be represented in the >> state of the underlying object, not represented a gigantic list of >options >> to one function. Options are invoked by calling a method, with perhaps >> a parameter or two, to turn on that option. The option being turned on >> is uniquely represented by the name of the method called -- not the name >> of a named argument supplied to that option. Defaults are established >> by the constructor to an object, so that optional methods need not be >> called for standard usage. > >This could have severe implications if an object was shared by more than >one process. In general, it seems that ephemeral information like >parameters should not be part of the state of the object. You're still not seeing it. The example we've been dealing with is that of a graph, which might have a number of different attributes (x, y axis labels, dataset to be plotted, type of graph, etc., etc.) In this case, one might want to define a DATASET class, which contains the data being plotted. This is the information that would be shared between processes. Then one could define a GRAPH object, with the state information of the particular graph to be drawn, which would contain the various parameters of the graph, and a reference to the DATASET to be plotted. This separates the information that should be shared from that which need not be shared (although if you come up with a good graph, you could simply send the GRAPH object to another process in order for that process to be able to produce that graph...). In general, any procedure with many, many parameters is probably a useful, general-purpose, central-to-the-system routine. Any such routine probably encapsulates functionality that could profitably be objectified. Even if you balk at the idea of creating objects that seem to have no purpose other than as argument lists, you should ocnsider the idea carefully. It may lead to a better object-oriented design. >Arnold Schaeffer >arn@apple.com >The opinions expressed are not necessarily those of Apple Computer. Rob Jellinghaus (robertj@CS.Yale.EDU)
adrianb@mica.stat.washington.edu (Adrian Baddeley) (08/20/89)
>In article <6590229@hplsla.HP.COM> jima@hplsla.HP.COM (Jim Adcock) writes: > Instead, all those parameters and options should be represented in the > state of the underlying object, not represented a gigantic list of options > to one function. Options are invoked by calling a method, with perhaps > a parameter or two, to turn on that option. The option being turned on > is uniquely represented by the name of the method called -- not the name > of a named argument supplied to that option. Defaults are established > by the constructor to an object, so that optional methods need not be > called for standard usage. OK. I'm convinced: named arguments are a bad idea, and are a relic of functional programming. The only remaining issue here for *interactive* languages is how to call the methods with a minimum of fuss/keystrokes. Thanks for your advice. PS: where do I join FPA (Functional Programmers Anonymous) ? ---- adrianb@castor.ms.washington.edu (until 21 august 1989) Adrian Baddeley, visiting Department of Statistics GN-22, University of Washington, Seattle WA 98195, USA. tel (U of W): +1 206 545-2617 / 543-7237
paulc@microsoft.UUCP (Paul Canniff 2/1011) (08/21/89)
In article <13186@well.UUCP> nagle@well.UUCP (John Nagle) writes: > > When a large number of optional, positional arguments are allowed, > the call can get a bit painful. > > z = plot(x,y,,,,,,1,,,'c'); > > is not something one finds desirable. This sort of thing is a curse of > some mainframe job control languages. We don't want to bring it back. It is, however, a simple and logical extension of the current "optional arguments" in C++. IMHO it is no more offensive than the current stuff; and if you have that many args, you have a problem anyway -- the methods and objects are becoming too complex, and it's time to look for component objects and methods which can be combined to satisfy the requirement. > One major advantage of named, optional arguments, is that when it > becomes necessary to add a new feature to a package, or to delete an > unused one, all the callers of the package need not be revised. Whatever > solution is chosen should definitely retain this property. Revised, no. Recompiled, probably. I am assuming that to retain efficiency, the translation from a named unordered list to an unnamed fixed list is done by the compiler, and not at runtime. So adding options may or may not require recompilation. Using methods to define the state of an object seems to provide even more flexibility that named arguments, because it allows the object to be extended w/o revising OR RECOMPILING the original source. And in the world of distributing processing, where messages to objects may actually be shipped across a network, it is very desireable to have the new object be compatible with the methods of the old object; it's hard to guarantee that everyone will be running the same version!