groovy-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Charles Monteiro <charles.monte...@gmail.com>
Subject Re: Named Parameters Support
Date Sat, 22 Jul 2017 23:00:12 GMT
How about the same support as languages like Ruby and Smalltalk provide ?

On Sat, Jul 22, 2017 at 5:17 PM MG <mgbiz@arscreat.com> wrote:

> Hi,
>
> having recently explained why Groovy is my language of choice got me
> thinking about the few areas of Groovy where I personally wish for / see
> the potential for improvement during my daily development tasks.
>
> I will start off with named paramters support, a topic that has been
> moving more into my consciousness as the framework I develop at work
> grew larger over time: I feel that the current named parameter support I
> am aware of
> (http://groovy-lang.org/objectorientation.html#_named_argument_constructor
> / http://groovy-lang.org/objectorientation.html#_named_arguments ) is a
> limited feature that fit relatively well with a purely dynamic language,
> but is not nearly as well rounded / powerful as in other languages.
>
> Do you have any plans to support named parameters such as they exist
> e.g. in PL/SQL (to be honest, I never expected I would ever quote PL/SQL
> as a language that is superior to Groovy in any aspect before I thought
> about this ;-) ), where named paramters are just a convenient (and
> safer) way to call a callable, without loosing type safety, which works
> in a purely static manner, and without requiring a method to explicitely
> deal with a Map as its argument.
> In short, a way to call any Groovy method/ctor with a syntax like:
>
> class Processor {
>      Processor(String name, boolean writeableQ = false, boolean
> extendableQ = true,  Number id = null, Worker defaultWorker = null,
> Closure logCls = {  println it }) { ... }
>      work(Worker worker = null, boolean dryRunQ = false, int
> maxNrRetries = 10, boolean overwriteQ = false) { ... }
> }
>
> final processor= new Processor(name:"Task 1", id:1234) { log.debug "T1:
> $it" }  // Closure as last argument can still be given outside of brackets
> processor.work(maxNrRetries:99)
>
>
> The grooviest thing of all would be, if there would be a way to keep the
> flexibility of the map argument, and combine it with the named
> arguments, to be able to e.g. define a different default set of default
> values for a method/ctor. E.g.
>
> static ParametersMap getDebugWorkParams() {
>      return [ worker:dummyWorker, dryRunQ:true, maxNrRetries:0,
> overwriteQ:true ]
> }
>
> processor.work(*(debugWorkParams + [worker:logOnlyWorker,
> maxNrRetries:3])) // dryRunQ=true and overwriteQ=true comes from
> debugWorkParams; worker and maxNrRetries are give explicitly in call
>
>
> In my case such a feature would have two benefits:
> 1a) Make it easy to quickly add a final field to a root base class,
> without having to do some a major ctor refactoring on all the child
> classes (for which I typically don't have the time, meaning that I am
> forced to add the field as non-final "for now", so I can modify it after
> object creation where needed).
> Note that this can, even if IntelliJ would not sometimes not get the
> refactoring wrong (which can lead to hard to track bugs), not be covered
> by better refactoring support: Not having to give all the values for the
> parameters before the newly added parameter (but instead having them
> take their default value) is not something a refactoring engine can supply.
> 1b) Similar to 1a), for adding parameters to method calls
> 2) Make the calling of ctors/methods safer in certain cases
> a) When a ctor/method takes a lot of parameters of the same type, e.g.
> boolean: createPackageSql(String name, boolean trimQ, boolean
> indentLinesQ, boolean keepEmptyLinesIndentationQ, boolean
> seperateFunctionsQ, boolean uppercaseKeywordsQ, boolean uppercaseNamesQ)
> { ... } *
> b) When a framework function is called by a framework user, e.g. from a
> script, or generally in an environment where there is little or no test
> coverage, and the paramter order can easily be confused: e.g. method
> which retrieves a DB item through 2 IDs, and getting an empty result set
> is not an error - which ID has to be given first ? Easy, when calling
> with named paramters is supported pe.retrieveTreeNodeRow(orgUnit:123,
> orgItem:456) .
>
> mg
>
> *Here a parameter object might be the better choice. But typically the
> number of paramters was small at the beginning, and grew over time, so
> initially no need for a paramater object existed. Again the refactoring
> time needed to introduce a parameter object, the fact that your class
> namespace gets cluttered with helper structures, external framework
> users will have to adapt their code (or you must maintain a backward
> compatibility facade), etc make this less practical than it might
> initially seem...
>
>
>
> --
Charles A. Monteiro
www.monteirosfusion.com
sent from the road

Mime
View raw message