PROPOSAL: Named and Optional parameters, "Java-style"
Frédéric Martini
frederic.martini at gmail.com
Thu Sep 1 02:56:15 PDT 2011
I think that "optional & named parameters" will be very useful, using
named tuples, Map<String,Object> or another specific type.
For another exemple, look at the NIO.2 File API.
It simulate "optional and named parameters" with a "hack" using a
marker interface (CopyOption, OpenOption).
* There are some enums that implement them (StandardCopyOption,
StandardOpenOption, LinkOption), for standard's values
* And some more specific implementation can define new value by
implementing interfaces (there is no real example to my knowledge)
Example :
// Metode signature :
InputStream newInputStream (Path path, OpenOption... options)
OutputStream newOutputStream(Path path, OpenOption... options)
// Some usage :
InputStream in = Files.newInputStream(path, LinkOption.NOFOLLOW_LINKS);
OutputStream out = Files.newOutputStream(path, StandardOpenOption.APPEND,
StandardOpenOption.SYNC);
// Possible use of a non-standard option (imaginary example)
InputStream in = Files.newInputStream(path, AnUtilityClass.bufferSize(8192) );
However, in my opinion, this "pattern" is quite limited, because it is
difficult to determine the possible values, even for the standard
values (so EDI can not offer a full autocompletion), and lot's of
these values depends of the method.
With "optional and named parameters", we could provide a better API,
specifying the possible values in the method signature (IDE can use
it for autocompletion)
Example :
// Metode signature :
InputStream newInputStream (Path path, {boolean noFollowLinks =
false, ...} namedArgs)
OutputStream newOutputStream(Path path, {boolean noFollowLinks = false,
boolean append = false, boolean truncate = true,
boolean create = true, createNew = false,
boolean sync = false, boolean dsync = false,
boolean deleteOnClose = false, boolean sparse = false, ...} namedArgs)
/* varargs means : compiler accept any others name/key not declared
on the function type */
// Some usage :
InputStream in = Files.newInputStream(path, noFollowLinks:false);
OutputStream out = Files.newOutputStream(path, append:true, sync:true);
// Possible use of a non-standard option (imaginary example)
InputStream in = Files.newInputStream(path, bufferSize:8192);
However, non-standard args via varargs introduce a problem : as any
key/value can be used, compiler cannot detect typo error.
Exemple :
// bad name : 'followLinks' instead of 'noFollowLinks'
// but it's was considerer as a non-standard args :
InputStream in = Files.newInputStream(path, followLinks:true);
// compile OK but might produce a runtime error
A solution can be to use a warning/error and an annotation in order to
detect problem at compile time :
InputStream in = Files.newInputStream(path, followLinks:true);
// Compile WARNING/ERROR : 'followLinks' is not a valid named parameters
// use @Extended for non-standard args
InputStream in = Files.newInputStream(path, bufferSize:8192);
// Compile WARNING/ERROR : 'bufferSize' is not a valid named parameters
// use @Extended for non-standard args
InputStream in = Files.newInputStream(path, @Extended bufferSize:8192);
// Compile OK
We can also use enum in order to "group" incompatible option (ex:
append or truncate), in order to improve method signature :
enum OpenMode { APPEND, TRUNCATE }
enum CreateMode { CREATE, CREATE_IF_NEW, DO_NO_CREATE }
enum SyncMode { NONE, SYNC, DSYNC }
OutputStream newOutputStream(Path path, {boolean followLinks:true,
OpenMode open = TRUNCATE,
CreateMode create = CREATE,
SyncMode sync = NONE,
boolean deleteOnClose = false, boolean sparse = false, ...} namedArgs)
Don't you think that this is clearer than
newOutputStream(Path,OptionOption...) ???
2011/8/22 Florian Weimer <fweimer at bfk.de>
>
> * Frédéric Martini:
>
> > * The "Builder pattern" is also painful to write and to use, and the
> > documentation is separed from the method.
>
> Another approach to named parameters would be fixing that. For
> instance, values of structural record type (named tuples) could be used
> to emulate named parameters and would be quite useful independently.
>
>
More information about the coin-dev
mailing list