Use cases for methods with optional parameters

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Use cases for methods with optional parameters

Damien Cassou-2
Hi,

I would like to study the impact of adding optional parameters to
keyword methods in Pharo. The goal of optional parameters is to
facilitate the implementation of methods where some parameters are
optional. For example, Seaside has:

WAComponent>>request: aRequestString label: aLabelString
             default: aDefaultString onAnswer: aBlock

    ...

This method of 4 arguments has only 1 required argument (aRequestString)
and 3 optional ones. In the current implementation, this results in 7
additional methods that only delegate directly or indirectly to the one
above:

- request:
- request:default:
- request:default:onAnswer:
- request:label:
- request:label:default:
- request:label:onAnswer:
- request:onAnswer:

Before starting to implement anything, I need to know if it makes sense.
If you want to help me, please send me all the use cases you have by
giving me:

- the library name (and URL if not in Catalog), or "pharo" if it's in
  Pharo
- the class where this happens
- the range of selectors that make sense

For the example above, this would be:

- Seaside
- WAComponent
- request:*


Thank you very much

--
Damien Cassou
http://damiencassou.seasidehosting.st

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

Max Leske
I don’t have any examples right now, but the idea is great! The situation is a familiar one. I’m looking forward to what you find.

Cheers,
Max

> On 20 Jan 2016, at 16:08, Damien Cassou <[hidden email]> wrote:
>
> Hi,
>
> I would like to study the impact of adding optional parameters to
> keyword methods in Pharo. The goal of optional parameters is to
> facilitate the implementation of methods where some parameters are
> optional. For example, Seaside has:
>
> WAComponent>>request: aRequestString label: aLabelString
>             default: aDefaultString onAnswer: aBlock
>
>    ...
>
> This method of 4 arguments has only 1 required argument (aRequestString)
> and 3 optional ones. In the current implementation, this results in 7
> additional methods that only delegate directly or indirectly to the one
> above:
>
> - request:
> - request:default:
> - request:default:onAnswer:
> - request:label:
> - request:label:default:
> - request:label:onAnswer:
> - request:onAnswer:
>
> Before starting to implement anything, I need to know if it makes sense.
> If you want to help me, please send me all the use cases you have by
> giving me:
>
> - the library name (and URL if not in Catalog), or "pharo" if it's in
>  Pharo
> - the class where this happens
> - the range of selectors that make sense
>
> For the example above, this would be:
>
> - Seaside
> - WAComponent
> - request:*
>
>
> Thank you very much
>
> --
> Damien Cassou
> http://damiencassou.seasidehosting.st
>
> "Success is the ability to go from one failure to another without
> losing enthusiasm." --Winston Churchill
>


Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

Ben Coman
In reply to this post by Damien Cassou-2
On Wed, Jan 20, 2016 at 11:08 PM, Damien Cassou <[hidden email]> wrote:

> Hi,
>
> I would like to study the impact of adding optional parameters to
> keyword methods in Pharo. The goal of optional parameters is to
> facilitate the implementation of methods where some parameters are
> optional. For example, Seaside has:
>
> WAComponent>>request: aRequestString label: aLabelString
>              default: aDefaultString onAnswer: aBlock
>
>     ...
>
> This method of 4 arguments has only 1 required argument (aRequestString)
> and 3 optional ones. In the current implementation, this results in 7
> additional methods that only delegate directly or indirectly to the one
> above:
>
> - request:
> - request:default:
> - request:default:onAnswer:
> - request:label:
> - request:label:default:
> - request:label:onAnswer:
> - request:onAnswer:
>
> Before starting to implement anything, I need to know if it makes sense.
> If you want to help me, please send me all the use cases you have by
> giving me:
>
> - the library name (and URL if not in Catalog), or "pharo" if it's in
>   Pharo
> - the class where this happens
> - the range of selectors that make sense
>
> For the example above, this would be:
>
> - Seaside
> - WAComponent
> - request:*

I don't have any use cases right now, but I'll keep my eyes open.  But
an example (that is maybe too basic to mess with) is the
#at:ifAbsent:   pattern.  For example, the following would be
"deleted"

   Dictionary>>.at: key
       ^ self at: key ifAbsent: [self errorKeyNotFound: key]

and you would only have....

   Dictionary>>at: key ifAbsent: aBlock
         <optional: ifAbsent default: [ self errorKeyNotFound: key]>

The big in-Image example would be...

     TClass>>
           subclass: aName
           uses: aTraitCompositionOrArray
           instanceVariableNames: someInstanceVariableNames
           classVariableNames: someClassVariableNames
           poolDictionaries: someSharedPoolNames
           package: aCategory
                <optional: uses default: {}>
                <optional: instanceVariableNames default: ''>
                <optional: classVariableNames default: ''>
                <optional: poolDictionaries default:''>
                <optional: package 'Unclassified'>

Now I wonder about  senders & implementers  searchability, and if
"virtual" methods are generated in all combinations of optional
parameters and show up in the system browser list, but show the "main"
method as their source.  Maybe it works a little like traits.

cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

stepharo
Ben

We were thinking also about reflection.


So may be we should introduce a relationship between the method and its
actual implementation.

Imagine that
     mother := foo:(bar:zork:)
     mother children
             foo:bar:
             foo:bar:zork:

then
     senders (foo:bar:)
=>
     sender (motherOf(foo:bar:))

where motherOf is a back pointer from the expanded method into its mother
But it means that method using foo:bar: should somehow "mention" that
they will
use motherOf (foo:bar:).



Le 22/1/16 01:41, Ben Coman a écrit :

> I don't have any use cases right now, but I'll keep my eyes open.  But
> an example (that is maybe too basic to mess with) is the
> #at:ifAbsent:   pattern.  For example, the following would be
> "deleted"
>
>     Dictionary>>.at: key
>         ^ self at: key ifAbsent: [self errorKeyNotFound: key]
>
> and you would only have....
>
>     Dictionary>>at: key ifAbsent: aBlock
>           <optional: ifAbsent default: [ self errorKeyNotFound: key]>
>
> The big in-Image example would be...
>
>       TClass>>
>             subclass: aName
>             uses: aTraitCompositionOrArray
>             instanceVariableNames: someInstanceVariableNames
>             classVariableNames: someClassVariableNames
>             poolDictionaries: someSharedPoolNames
>             package: aCategory
>                  <optional: uses default: {}>
>                  <optional: instanceVariableNames default: ''>
>                  <optional: classVariableNames default: ''>
>                  <optional: poolDictionaries default:''>
>                  <optional: package 'Unclassified'>
>
> Now I wonder about  senders & implementers  searchability, and if
> "virtual" methods are generated in all combinations of optional
> parameters and show up in the system browser list, but show the "main"
> method as their source.


Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

Ben Coman
Sounds interesting, but my head hurts trying to think about this more
deeply :)
so I'm going to keep at a superficial level on this for now.
So just thinking out loud...

If you have
  mother1 := foo:(bar:zork:fork)
  mother2 := foo:bar:(zork:bork:)
When you search for senders of #foo:bar: what do you get back and how
to display it?

Maybe a two level tree list with the option combinations appearing at
the top level and each of their senders at the second level, hiding
any top level items that don't have children.
foo:bar:
foo:bar:zork:
foo:bar:fork:
foor:bar:bork
foo:bar:zork:fork:
foo:bar:fork:zork:
foo:bar:zork:bork:
foo:bar:bork:zork:

Actually, full any order combination probably becomes unwieldly.
Maybe there should be a constraint that optional arguments can be
skipped but when used must be used in sequence.

cheers -ben

btw, how do you mean relationship?  Do you mean using a Slots
mechanism like the relationship demo in the Flexible Object layouts
paper?
https://hal.inria.fr/hal-00641716/file/Verw11b-OOSPLA11-FlexibleObjectLayouts.pdf

On Sat, Jan 23, 2016 at 3:29 AM, stepharo <[hidden email]> wrote:

> Ben
>
> We were thinking also about reflection.
>
>
> So may be we should introduce a relationship between the method and its
> actual implementation.
>
> Imagine that
>     mother := foo:(bar:zork:)
>     mother children
>             foo:bar:
>             foo:bar:zork:
>
> then
>     senders (foo:bar:)
> =>
>     sender (motherOf(foo:bar:))
>
> where motherOf is a back pointer from the expanded method into its mother
> But it means that method using foo:bar: should somehow "mention" that they
> will
> use motherOf (foo:bar:).
>
>
>
> Le 22/1/16 01:41, Ben Coman a écrit :
>
>> I don't have any use cases right now, but I'll keep my eyes open.  But
>> an example (that is maybe too basic to mess with) is the
>> #at:ifAbsent:   pattern.  For example, the following would be
>> "deleted"
>>
>>     Dictionary>>.at: key
>>         ^ self at: key ifAbsent: [self errorKeyNotFound: key]
>>
>> and you would only have....
>>
>>     Dictionary>>at: key ifAbsent: aBlock
>>           <optional: ifAbsent default: [ self errorKeyNotFound: key]>
>>
>> The big in-Image example would be...
>>
>>       TClass>>
>>             subclass: aName
>>             uses: aTraitCompositionOrArray
>>             instanceVariableNames: someInstanceVariableNames
>>             classVariableNames: someClassVariableNames
>>             poolDictionaries: someSharedPoolNames
>>             package: aCategory
>>                  <optional: uses default: {}>
>>                  <optional: instanceVariableNames default: ''>
>>                  <optional: classVariableNames default: ''>
>>                  <optional: poolDictionaries default:''>
>>                  <optional: package 'Unclassified'>
>>
>> Now I wonder about  senders & implementers  searchability, and if
>> "virtual" methods are generated in all combinations of optional
>> parameters and show up in the system browser list, but show the "main"
>> method as their source.
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

stepharo


Le 23/1/16 03:38, Ben Coman a écrit :
> Sounds interesting, but my head hurts trying to think about this more
> deeply :)
> so I'm going to keep at a superficial level on this for now.
> So just thinking out loud...
>
> If you have
>    mother1 := foo:(bar:zork:fork)
>    mother2 := foo:bar:(zork:bork:)
I'm not sure that this is allows in the same class. We should check that
in Python or ruby.

> When you search for senders of #foo:bar: what do you get back and how
> to display it?

We should display every caller.

>
> Maybe a two level tree list with the option combinations appearing at
> the top level and each of their senders at the second level, hiding
> any top level items that don't have children.
> foo:bar:
> foo:bar:zork:
> foo:bar:fork:
> foor:bar:bork
> foo:bar:zork:fork:
> foo:bar:fork:zork:
> foo:bar:zork:bork:
> foo:bar:bork:zork:
>
> Actually, full any order combination probably becomes unwieldly.
> Maybe there should be a constraint that optional arguments can be
> skipped but when used must be used in sequence.
>
> cheers -ben
>
> btw, how do you mean relationship?

I mean knowing the mother from the children


>   Do you mean using a Slots
> mechanism like the relationship demo in the Flexible Object layouts
> paper?
no

> https://hal.inria.fr/hal-00641716/file/Verw11b-OOSPLA11-FlexibleObjectLayouts.pdf
>
> On Sat, Jan 23, 2016 at 3:29 AM, stepharo <[hidden email]> wrote:
>> Ben
>>
>> We were thinking also about reflection.
>>
>>
>> So may be we should introduce a relationship between the method and its
>> actual implementation.
>>
>> Imagine that
>>      mother := foo:(bar:zork:)
>>      mother children
>>              foo:bar:
>>              foo:bar:zork:
>>
>> then
>>      senders (foo:bar:)
>> =>
>>      sender (motherOf(foo:bar:))
>>
>> where motherOf is a back pointer from the expanded method into its mother
>> But it means that method using foo:bar: should somehow "mention" that they
>> will
>> use motherOf (foo:bar:).
>>
>>
>>
>> Le 22/1/16 01:41, Ben Coman a écrit :
>>
>>> I don't have any use cases right now, but I'll keep my eyes open.  But
>>> an example (that is maybe too basic to mess with) is the
>>> #at:ifAbsent:   pattern.  For example, the following would be
>>> "deleted"
>>>
>>>      Dictionary>>.at: key
>>>          ^ self at: key ifAbsent: [self errorKeyNotFound: key]
>>>
>>> and you would only have....
>>>
>>>      Dictionary>>at: key ifAbsent: aBlock
>>>            <optional: ifAbsent default: [ self errorKeyNotFound: key]>
>>>
>>> The big in-Image example would be...
>>>
>>>        TClass>>
>>>              subclass: aName
>>>              uses: aTraitCompositionOrArray
>>>              instanceVariableNames: someInstanceVariableNames
>>>              classVariableNames: someClassVariableNames
>>>              poolDictionaries: someSharedPoolNames
>>>              package: aCategory
>>>                   <optional: uses default: {}>
>>>                   <optional: instanceVariableNames default: ''>
>>>                   <optional: classVariableNames default: ''>
>>>                   <optional: poolDictionaries default:''>
>>>                   <optional: package 'Unclassified'>
>>>
>>> Now I wonder about  senders & implementers  searchability, and if
>>> "virtual" methods are generated in all combinations of optional
>>> parameters and show up in the system browser list, but show the "main"
>>> method as their source.
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

HilaireFernandes
In reply to this post by Damien Cassou-2
Yes, sometime we are writing 2 or 3 methods just to handle default
values for some arguments. It is not a big deal, just annoying.
New feature, that may be useful is namespace. No idea about its
implication however.

Thanks

--
Dr. Geo
http://drgeo.eu


Reply | Threaded
Open this post in threaded view
|

Re: Use cases for methods with optional parameters

Damien Pollet
In reply to this post by stepharo
On 23 January 2016 at 16:12, stepharo <[hidden email]> wrote:
If you have
   mother1 := foo:(bar:zork:fork)
   mother2 := foo:bar:(zork:bork:)
I'm not sure that this is allows in the same class. We should check that in Python or ruby.

In Ruby:

def m(x=42, y=51)
→ calling m(3) gets x=3, y=51 (the given arguments are passed into the leftmost parameters first)

def m(options)  
→ calling m( { x: 3, y: 4 } ) or m( x: 3, y: 4 ) gets options = { x: 3, y: 4 }
So, a dictionary magically created because you passed something that either was already a dictionary, or used the syntax of dictionary key/value pairs. If you need default values for known keys, you take a default dictionary and override its contents using http://www.rubydoc.info/stdlib/core/Hash%3Aupdate

In Python I think it's more like the first Ruby alternative, except arguments can be named (so those bypass the left-to-right assignment order)

--
Damien Pollet
type less, do more [ | ] http://people.untyped.org/damien.pollet