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