Dinko Srkoc | 1 May 2012 03:27
Picon
Gravatar

[groovy-dev] Currying and partial application

Hi all,

On the fringe of a recent thread[1] there was a discussion about the
meaning of currying and partial application, and, perhaps somewhat
hastily named method `curry` which partially applies its arguments to
the Closure. Here's a small excerpt from the discussion:

On 27 March 2012 03:19, paulk_asert <paulk@...> wrote:
> [...]
> Nice. Yes, we could probably add curried() as a standard call for Closure
> and leave the n/r/curry methods as is for the time being (at least). But I
> can't think of a nice way to do uncurried() just at the moment and it seems
> a smell to have one without the other.

Encouraged by these words, I played with this idea and came out with
some code. Even the `uncurried()` method is implemented, albeit
Closures must be `curried()` before they can be `uncurried()`. With
this caveat, the implementation of `uncurried` turned out to be very
simple.
Tests and javadoc are, naturally, included.

Implementation detail:
The class that inherits `Closure` is called `ClosureCurried` because,
well, `CurriedClosure` is already taken. The Wikipedia suggests
`SchönfinkeledClosure`[2], but this name doesn't quite have that
certain ring to it. :-)

I was thinking of raising a JIRA for this, but found there already is
one[3]. So, would it be worthwhile to submit a pull request for
GROOVY-4998?
(Continue reading)

Paul King | 1 May 2012 11:13
Picon
Favicon
Gravatar

Re: [groovy-dev] Currying and partial application


Looks like nice work Dinko!

Just on the original naming, there are numerous other languages which use
the name "curry" for partial application - just not the functional ones!

I think we need to do something in this area and what you have looks like
a positive step forward. I still feel a little uneasy about uncurried() not
working in the general case but maybe others are less concerned about this.

Cheers, Paul.

On 1/05/2012 11:27 AM, Dinko Srkoc wrote:
> Hi all,
>
> On the fringe of a recent thread[1] there was a discussion about the
> meaning of currying and partial application, and, perhaps somewhat
> hastily named method `curry` which partially applies its arguments to
> the Closure. Here's a small excerpt from the discussion:
>
> On 27 March 2012 03:19, paulk_asert<paulk@...>  wrote:
>> [...]
>> Nice. Yes, we could probably add curried() as a standard call for Closure
>> and leave the n/r/curry methods as is for the time being (at least). But I
>> can't think of a nice way to do uncurried() just at the moment and it seems
>> a smell to have one without the other.
>
> Encouraged by these words, I played with this idea and came out with
> some code. Even the `uncurried()` method is implemented, albeit
> Closures must be `curried()` before they can be `uncurried()`. With
(Continue reading)

Dinko Srkoc | 2 May 2012 04:06
Picon
Gravatar

Re: [groovy-dev] Currying and partial application

On 1 May 2012 11:13, Paul King <paulk@...> wrote:
>
> Looks like nice work Dinko!

Thanks :-)

>
> Just on the original naming, there are numerous other languages which use
> the name "curry" for partial application - just not the functional ones!
>
> I think we need to do something in this area and what you have looks like
> a positive step forward. I still feel a little uneasy about uncurried() not
> working in the general case but maybe others are less concerned about this.
>

Current implementation is at least simple, and I've indicated the
curried() -> uncurried() connection in the docs for both `curried` and
`uncurried` methods.

The general case may be rather messy.

    { a, b -> a + b }.uncurried()
    { a -> { b -> { c, d -> a + b + c + d }}}.uncurried()

Should the above code snippets fail or not?

Perhaps only properly curried Closures can be uncurried and other
attempts should fail. In that case, is it possible to reliably
discover such cases without peeking somehow at the AST?

(Continue reading)

Russel Winder | 2 May 2012 11:12
Picon
Gravatar

Re: [groovy-dev] Currying and partial application

On Wed, 2012-05-02 at 04:06 +0200, Dinko Srkoc wrote:
[...]
> The general case may be rather messy.
> 
>     { a, b -> a + b }.uncurried()
>     { a -> { b -> { c, d -> a + b + c + d }}}.uncurried()
> 
> Should the above code snippets fail or not?

Both lines should fail I guess.

Since all functions associated with a Curried representation are
functions of a single parameter, then to attempt to uncurry a function
of more than one parameter is an error.

> Perhaps only properly curried Closures can be uncurried and other
> attempts should fail. In that case, is it possible to reliably
> discover such cases without peeking somehow at the AST?

or at least enforce single parameter functions.

Can function and lambdas both be handled?

> Here's an example of a permissive implementation (the above snippets
> do not fail):
> 
>     // member of Closure
>     Closure uncurried(Closure orig) {
>         orig.maximumNumberOfParameters == 1 ?
>             { ...args -> args.inject(orig) { cl, arg -> cl(arg) }} :
(Continue reading)

Mathieu Bruyen | 2 May 2012 15:07
Picon

[groovy-dev] Suggestion of an improvement for MetaClassImpl.setProperty

Hello,

I stumbled upon a problem with type erasure when using the default map constructor, with a script like:

class Address {
    String street
    int zip
}
class User {
    String name
    List<Address> addresses
}
def u = new User([
    name: 'Foo',
    addresses: [
        [street: '36, Foo road', zip: 12345],
        [street: '37, Bar road', zip: 6789]
    ]
])
println u.addresses

In that case u.addresses will be a list of maps, containing the raw map that has been given as parameter (the script echoes [[street:36, Foo road, zip:12345], [street:37, Bar road, zip:6789]]).

After digging a bit I found that the MetaClassImpl.setProperty method does not care about generics even if they are available (and in that case they are). I tried play a bit with the available information and come to a prototype, as seen in the patch (to be applied on commit 762924186670e40e088c2bbb5bc5a205f7c7118b). In the patch I added a method to get generic parameters on CachedMethod, a type transformation that creates a list with types all objects inside it and the hack in MetaClassImpl.

The patch is really just a prototyping and would need to define a real interface to get generic information from MetaMethod as well as a proper way of doing the conversion. The problem is of course not restricted to lists, and it would have to be made for a larger set of types (to me for Map and Collection (all that implements collection at once, not one solution for each individual type)) but I first wanted to know if there was an interest for such a feature before polishing what I did.

I spotted two downsides of this approach:
* depending on how the code is written sometimes types will be enforced and sometimes it would be raw maps
* if the user used a specific collection type (like an unmodifiable or a concurrent one) that would be converted with this approach to a default type like HashMap, ArrayList, ...

So my question, are you interested in such a feature?

Regards,
Mathieu Bruyen
Attachment (prototyping.patch): application/octet-stream, 3896 bytes

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Jochen Theodorou | 2 May 2012 15:36
Picon
Gravatar

Re: [groovy-dev] Traversing collections with indexes

Am 30.04.2012 21:44, schrieb Andrew Taylor:
[...]
> I kind of like this direction. What about setting the closure delegate
> to a one value map [index: 0] where index gets incremented each
> iteration? E.g.
>
> ['a', 'b', 'c'].collect { it -> "$index: $it" }
>
> The "index" variable would come implicitly from the delegate. If the
> owner already has "index" bound, that would still get used with the
> default resolution strategy, so it would be mostly backwards compatible.

If you as programmer in your program do that it is ok to do so. But as 
default not. There is no clear separation of concerns here. Imagine 
someone setting a delegate by himself and then forwarding to collect.

bye blackdrag

--

-- 
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Tim Yates | 2 May 2012 15:45
Picon
Gravatar

Re: [groovy-dev] Iterator.transform

For what it's worth, I put a blog post and call for comments here:



Describing the current state of the code and its usage

Tim

On 27 April 2012 17:37, Johannes Link <jl-YfaajirXv23CeWYh2EZFxg@public.gmane.org> wrote:
S.t. similar got started in gpars within the dataflow package. Maybe u want to have a look at that as well.

best regards, Johannes

Am 27.04.2012 um 18:01 schrieb Tim Yates <tim.yates-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:

Taking the "Stream" nomenclature for my own, I came up with:


List comprehension style tests can be found here:


And a few iterator tests here:


Tim

On 23 April 2012 18:43, Jochen Theodorou <blackdrag-BA+cFGlbTmA@public.gmane.org> wrote:
Am 23.04.2012 17:53, schrieb Andrew Taylor:

On 4/23/2012 1:45 AM, Jochen Theodorou wrote:
Am 22.04.2012 20:31, schrieb Tim Yates:
I might look into working on a new LazyDefaultMethods class which adds
lazyCollect, lazyFindAll, lazyTake and lazyCollate to Iterator and
InputStream...

Is this worth the effort?

How about keeping the methods we have and instead going with a
LazyCollection class?

The Java developers seem to be exploring similar stuff for the JDK once
lambdas make it into the language[1]. In particular, they're proposing a
new interface "Stream" that represents a lazy Iterable. Maybe it makes
sense to keep groovy terminology close to Java's?

[1]:
http://cr.openjdk.java.net/~briangoetz/lambda/collections-overview.html

interesting is especially the list of open issues.


bye blackdrag

--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email




Cédric Champeau | 2 May 2012 16:27
Picon
Gravatar

Re: [groovy-dev] Suggestion of an improvement for MetaClassImpl.setProperty

Hi Mathieu,

I'm trying to apply your patch onto master, but it fails with "corrupt patch". Whatever, I'm wondering if your technique doesn't work only because both Address and User are compiled in the same source file. Could you test, for example, compiling Address, then User and eventually, a script using both?

Le 02/05/2012 15:07, Mathieu Bruyen a écrit :
Hello,

I stumbled upon a problem with type erasure when using the default map constructor, with a script like:

class Address {
    String street
    int zip
}
class User {
    String name
    List<Address> addresses
}
def u = new User([
    name: 'Foo',
    addresses: [
        [street: '36, Foo road', zip: 12345],
        [street: '37, Bar road', zip: 6789]
    ]
])
println u.addresses

In that case u.addresses will be a list of maps, containing the raw map that has been given as parameter (the script echoes [[street:36, Foo road, zip:12345], [street:37, Bar road, zip:6789]]).

After digging a bit I found that the MetaClassImpl.setProperty method does not care about generics even if they are available (and in that case they are). I tried play a bit with the available information and come to a prototype, as seen in the patch (to be applied on commit 762924186670e40e088c2bbb5bc5a205f7c7118b). In the patch I added a method to get generic parameters on CachedMethod, a type transformation that creates a list with types all objects inside it and the hack in MetaClassImpl.

The patch is really just a prototyping and would need to define a real interface to get generic information from MetaMethod as well as a proper way of doing the conversion. The problem is of course not restricted to lists, and it would have to be made for a larger set of types (to me for Map and Collection (all that implements collection at once, not one solution for each individual type)) but I first wanted to know if there was an interest for such a feature before polishing what I did.

I spotted two downsides of this approach:
* depending on how the code is written sometimes types will be enforced and sometimes it would be raw maps
* if the user used a specific collection type (like an unmodifiable or a concurrent one) that would be converted with this approach to a default type like HashMap, ArrayList, ...

So my question, are you interested in such a feature?

Regards,
Mathieu Bruyen


--------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email


-- Cédric Champeau SpringSource - A Division Of VMware http://www.springsource.com/ http://twitter.com/CedricChampeau
code | 2 May 2012 18:38
Picon

Re: [groovy-dev] Suggestion of an improvement for MetaClassImpl.setProperty

Hi,

Here is a new patch (generated with git format-patch rather than git diff),
however it is very similar to the previous and I may have missed something about
patches...

I tried putting each class in its own file and a separate main, compiling each at
a time with groovyc, and then executing the main but got the same result (the raw
map returned).

Regards,
Mathieu Bruyen

On Wed  2/05/12 16:27, Cédric Champeau cedric.champeau@... wrote:
> Hi Mathieu,
> 
> I'm trying to apply your patch onto master, but it fails with
> "corrupt patch". Whatever, I'm wondering if your technique doesn't
> work only because both Address and User are compiled in the same
> source file. Could you test, for example, compiling Address, then User
> and eventually, a script using both?
> 
> Le 02/05/2012 15:07, Mathieu Bruyen a crit : Hello,
> 
> I stumbled upon a problem with type erasure when using the default
> map constructor, with a script like:
> 
> class Address {
> String street
> int zip
> }
> class User {
> String name
> List addresses
> }
> def u = new User([
> name: 'Foo',
> addresses: [
> [street: '36, Foo road', zip: 12345],
> [street: '37, Bar road', zip: 6789]
> ]
> ])
> println u.addresses
> 
> In that case u.addresses will be a list of maps, containing the raw
> map that has been given as parameter (the script echoes [[street:36,
> Foo road, zip:12345], [street:37, Bar road, zip:6789]]).
> 
> After digging a bit I found that the MetaClassImpl.setProperty
> method does not care about generics even if they are available (and in
> that case they are). I tried play a bit with the available information
> and come to a prototype, as seen in the patch (to be applied on commit
> 762924186670e40e088c2bbb5bc5a205f7c7118b). In the patch I added a
> method to get generic parameters on CachedMethod, a type
> transformation that creates a list with types all objects inside it
> and the hack in MetaClassImpl.
> 
> The patch is really just a prototyping and would need to define a
> real interface to get generic information from MetaMethod as well as a
> proper way of doing the conversion. The problem is of course not
> restricted to lists, and it would have to be made for a larger set of
> types (to me for Map and Collection (all that implements collection at
> once, not one solution for each individual type)) but I first wanted
> to know if there was an interest for such a feature before polishing
> what I did.
> 
> I spotted two downsides of this approach:
> * depending on how the code is written sometimes types will be
> enforced and sometimes it would be raw maps
> * if the user used a specific collection type (like an unmodifiable
> or a concurrent one) that would be converted with this approach to a
> default type like HashMap, ArrayList, ...
> 
> So my question, are you interested in such a feature?
> 
> Regards,
> Mathieu Bruyen
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
> http://xircles.codehaus.org/manage_email [1]   
> 
> -- Cdric Champeau SpringSource - A Division Of VMware
> http://www.springsource.com/ [2] http://twitter.com/CedricChampeau [3]
> 
> 
> Links:
> ------
> [1] http://xircles.codehaus.org/manage_email
> [2] http://www.springsource.com/
> [3] http://twitter.com/CedricChampeau
> 
> 

Attachment (prototype.patch): application/octet-stream, 4192 bytes

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Dinko Srkoc | 3 May 2012 03:00
Picon
Gravatar

Re: [groovy-dev] Currying and partial application

On 2 May 2012 11:12, Russel Winder <russel@...> wrote:
> On Wed, 2012-05-02 at 04:06 +0200, Dinko Srkoc wrote:
> [...]
>> The general case may be rather messy.
>>
>>     { a, b -> a + b }.uncurried()
>>     { a -> { b -> { c, d -> a + b + c + d }}}.uncurried()
>>
>> Should the above code snippets fail or not?
>
> Both lines should fail I guess.
>
> Since all functions associated with a Curried representation are
> functions of a single parameter, then to attempt to uncurry a function
> of more than one parameter is an error.

right

>
>> Perhaps only properly curried Closures can be uncurried and other
>> attempts should fail. In that case, is it possible to reliably
>> discover such cases without peeking somehow at the AST?
>
> or at least enforce single parameter functions.

OK, here's my Groovy attempt at enforcing single parameter functions
for `Closure#uncurried()`:

https://gist.github.com/2582238

Can this hold water, or at least have acceptably small holes?

`uncurried()` being implemented only for Closures that were previously
`curried()` is so much simpler.

>
> Can function and lambdas both be handled?

Russel, I'm not quite understanding the question.
What is the difference between a function and a lambda, apart from
lambdas being anonymous and having arity of 1?

Cheers,
Dinko

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Gmane