Functional programming?

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

Functional programming?

Roger Koenker-3
I have a (remarkably ugly!!) code snippet  (below) that, given
two simple functions, f and g,  generates
a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
better ways to do this.  I don’t particularly care about the returned list,
I’d be happy to have the final  h_K version of the function,
but I keep losing my way and running into the dreaded:

Error in h[[1]] : object of type 'closure' is not subsettable
or
Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
something more sensible lurking beneath this minimal (toy)  example.

    f <- function(u) function(x) u * x^2
    g <- function(u) function(x) u * log(x)
    set.seed(3)
    a <- runif(5)
    h <- list()
    hit <- list()
    h[[1]] <- f(a[1])
    hit[[1]] <- f(a[1])
    for(i in 2:5){
        ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
        h[[i]] <- eval(parse(text = ht))
        hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
        }
    x <- 1:99/10
    plot(x, h[[1]](x), type = "l")
    for(i in 2:5)
        lines(x, h[[i]](x), col = i)

Thanks,
Roger

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Bert Gunter-2
Does this do what you want:

f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- list()
hit <- list()
h[[1]] <- f(a[1])
hit[[1]] <- f(a[1])
for(i in 2:5)h[[i]] <- eval(bquote(function(x).(h[[i-1]])(x) * g(a[i])(x)))
x <- 1:99/10
plot(x, h[[1]](x), type = "l")
for(i in 2:5){
  i
  lines(x, h[[i]](x), col = i)
}

Cheers,
Bert


Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Wed, Mar 2, 2016 at 8:47 AM, Roger Koenker <[hidden email]> wrote:

> I have a (remarkably ugly!!) code snippet  (below) that, given
> two simple functions, f and g,  generates
> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
> better ways to do this.  I don’t particularly care about the returned list,
> I’d be happy to have the final  h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>
> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
> something more sensible lurking beneath this minimal (toy)  example.
>
>     f <- function(u) function(x) u * x^2
>     g <- function(u) function(x) u * log(x)
>     set.seed(3)
>     a <- runif(5)
>     h <- list()
>     hit <- list()
>     h[[1]] <- f(a[1])
>     hit[[1]] <- f(a[1])
>     for(i in 2:5){
>         ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
>         h[[i]] <- eval(parse(text = ht))
>         hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
>         }
>     x <- 1:99/10
>     plot(x, h[[1]](x), type = "l")
>     for(i in 2:5)
>         lines(x, h[[i]](x), col = i)
>
> Thanks,
> Roger
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Duncan Murdoch-2
In reply to this post by Roger Koenker-3
On 02/03/2016 11:47 AM, Roger Koenker wrote:

> I have a (remarkably ugly!!) code snippet  (below) that, given
> two simple functions, f and g,  generates
> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
> better ways to do this.  I don’t particularly care about the returned list,
> I’d be happy to have the final  h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>
> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
> something more sensible lurking beneath this minimal (toy)  example.
>
>      f <- function(u) function(x) u * x^2
>      g <- function(u) function(x) u * log(x)
>      set.seed(3)
>      a <- runif(5)
>      h <- list()
>      hit <- list()
>      h[[1]] <- f(a[1])
>      hit[[1]] <- f(a[1])
>      for(i in 2:5){
> ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
> h[[i]] <- eval(parse(text = ht))
> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
> }
>      x <- 1:99/10
>      plot(x, h[[1]](x), type = "l")
>      for(i in 2:5)
> lines(x, h[[i]](x), col = i)

I don't understand what "hit" is for, but something like this should do it:


hlist <- function(maxk, f,g,a) {
   h <- list()
   h[[1]] <- f(a[1])
   for (j in 2:maxk) {
     h[[j]] <- local({
       k <- j
       function(x) {
         result <- h[[1]](x)
         for (i in 2:k) {
           result <- result*g(a[i])(x)
         }
         result
       }
     })
   }
   h
}

f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- hlist(5, f, g, a)

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Roger Koenker-3
In reply to this post by Roger Koenker-3
Thanks, Duncan and Bert,

Duncan’s version does replicate my result, Bert’s does something a bit different,
now I just need some time to digest what you have done, and try to see how
and why.  Many thanks!!!

Roger

url:    www.econ.uiuc.edu/~roger            Roger Koenker
email    [hidden email]            Department of Economics
vox:     217-333-4558                University of Illinois
fax:       217-244-6678                Urbana, IL 61801

> On Mar 2, 2016, at 12:23 PM, Duncan Murdoch <[hidden email]> wrote:
>
> On 02/03/2016 11:47 AM, Roger Koenker wrote:
>> I have a (remarkably ugly!!) code snippet  (below) that, given
>> two simple functions, f and g,  generates
>> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
>> better ways to do this.  I don’t particularly care about the returned list,
>> I’d be happy to have the final  h_K version of the function,
>> but I keep losing my way and running into the dreaded:
>>
>> Error in h[[1]] : object of type 'closure' is not subsettable
>> or
>> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>>
>> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
>> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
>> something more sensible lurking beneath this minimal (toy)  example.
>>
>>     f <- function(u) function(x) u * x^2
>>     g <- function(u) function(x) u * log(x)
>>     set.seed(3)
>>     a <- runif(5)
>>     h <- list()
>>     hit <- list()
>>     h[[1]] <- f(a[1])
>>     hit[[1]] <- f(a[1])
>>     for(i in 2:5){
>> ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
>> h[[i]] <- eval(parse(text = ht))
>> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
>> }
>>     x <- 1:99/10
>>     plot(x, h[[1]](x), type = "l")
>>     for(i in 2:5)
>> lines(x, h[[i]](x), col = i)
>
> I don't understand what "hit" is for, but something like this should do it:
>
>
> hlist <- function(maxk, f,g,a) {
>   h <- list()
>   h[[1]] <- f(a[1])
>   for (j in 2:maxk) {
>     h[[j]] <- local({
>       k <- j
>       function(x) {
>         result <- h[[1]](x)
>         for (i in 2:k) {
>           result <- result*g(a[i])(x)
>         }
>         result
>       }
>     })
>   }
>   h
> }
>
> f <- function(u) function(x) u * x^2
> g <- function(u) function(x) u * log(x)
> set.seed(3)
> a <- runif(5)
> h <- hlist(5, f, g, a)

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Mikko Korpela
In reply to this post by Roger Koenker-3
On 02.03.2016 18:47, Roger Koenker wrote:

> I have a (remarkably ugly!!) code snippet  (below) that, given
> two simple functions, f and g,  generates
> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
> better ways to do this.  I don’t particularly care about the returned list,
> I’d be happy to have the final  h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>
> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
> something more sensible lurking beneath this minimal (toy)  example.
>
>     f <- function(u) function(x) u * x^2
>     g <- function(u) function(x) u * log(x)
>     set.seed(3)
>     a <- runif(5)
>     h <- list()
>     hit <- list()
>     h[[1]] <- f(a[1])
>     hit[[1]] <- f(a[1])
>     for(i in 2:5){
> ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
> h[[i]] <- eval(parse(text = ht))
> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
> }
>     x <- 1:99/10
>     plot(x, h[[1]](x), type = "l")
>     for(i in 2:5)
> lines(x, h[[i]](x), col = i)

Here is my (ugly?) suggestion:

f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- f(a[1])
for (i in 2:5) {
    body(h) <- call("*", body(h),
                    as.call(list(do.call("g", list(a[i])), quote(x))))
}

--
Mikko Korpela
Aalto University School of Science
Department of Computer Science

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Gabor Grothendieck
In reply to this post by Roger Koenker-3
This manufactures the functions without using eval by using substitute
to substitute i-1 and a[i] into an expression for the body which is
then assigned to the body of the function:

hh <- vector("list", 5)
hh[[1]] <- f(a[1])
for(i in 2:5) {
     hh[[i]] <- hh[[1]]
     body(hh[[i]]) <- substitute(hh[[iprev]](x) * g(ai)(x), list(iprev
= i-1, ai = a[i]))
}
all.equal(h[[5]](.5), hh[[5]](.5)) # test
## [1] TRUE



This uses quote to define the body of h[[i]] as a call object and then
substitutes in the values of i-1 and a[i] assigning the result to the
body of h[[i]].

h <- vector("list", 5)
h[[1]] <- f(a[1])
for(i in 2:5) {
     h[[i]] <- h[[1]]
     body(hh[[i]]) <- do.call(substitute,
                                           list(quote(hh[[iprev]](x) *
g(ai)(x)),
                                           list(iprev = i-1, ai = a[i])))
}



On Wed, Mar 2, 2016 at 11:47 AM, Roger Koenker <[hidden email]> wrote:

> I have a (remarkably ugly!!) code snippet  (below) that, given
> two simple functions, f and g,  generates
> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
> better ways to do this.  I don’t particularly care about the returned list,
> I’d be happy to have the final  h_K version of the function,
> but I keep losing my way and running into the dreaded:
>
> Error in h[[1]] : object of type 'closure' is not subsettable
> or
> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>
> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
> something more sensible lurking beneath this minimal (toy)  example.
>
>     f <- function(u) function(x) u * x^2
>     g <- function(u) function(x) u * log(x)
>     set.seed(3)
>     a <- runif(5)
>     h <- list()
>     hit <- list()
>     h[[1]] <- f(a[1])
>     hit[[1]] <- f(a[1])
>     for(i in 2:5){
>         ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
>         h[[i]] <- eval(parse(text = ht))
>         hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
>         }
>     x <- 1:99/10
>     plot(x, h[[1]](x), type = "l")
>     for(i in 2:5)
>         lines(x, h[[i]](x), col = i)
>
> Thanks,
> Roger
>
> ______________________________________________
> [hidden email] mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



--
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Bert Gunter-2
In reply to this post by Roger Koenker-3
Thanks, Roger:

I think Duncan's approach is far more efficient, but I believe the
following replicates your result and may be a bit easier to
understand.

f <- function(u) function(x) u * x^2
g <- function(u) function(x) u * log(x)
set.seed(3)
a <- runif(5)
h <- list()
hit <- list()
h[[1]] <- f(a[1])
hit[[1]] <- f(a[1])
for(i in 2:5) h[[i]] <- eval(bquote(function(x)h[[.(i-1)]](x)*g(a[.(i)])(x)))
x <- 1:99/10
plot(x, h[[1]](x), type = "l")
for(i in 2:5){
  lines(x, h[[i]](x), col = i)
}

This uses recursion to "unwind" h[[i]] each time it's called, ergo
the inefficiency. But in that sense,anyway,  it seems to be more
"functional."

But certainly feel free to ignore.

Cheers,
Bert
Bert Gunter

"The trouble with having an open mind is that people keep coming along
and sticking things into it."
-- Opus (aka Berkeley Breathed in his "Bloom County" comic strip )


On Wed, Mar 2, 2016 at 10:40 AM, Roger Koenker <[hidden email]> wrote:

> Thanks, Duncan and Bert,
>
> Duncan’s version does replicate my result, Bert’s does something a bit different,
> now I just need some time to digest what you have done, and try to see how
> and why.  Many thanks!!!
>
> Roger
>
> url:    www.econ.uiuc.edu/~roger            Roger Koenker
> email    [hidden email]            Department of Economics
> vox:     217-333-4558                University of Illinois
> fax:       217-244-6678                Urbana, IL 61801
>
>> On Mar 2, 2016, at 12:23 PM, Duncan Murdoch <[hidden email]> wrote:
>>
>> On 02/03/2016 11:47 AM, Roger Koenker wrote:
>>> I have a (remarkably ugly!!) code snippet  (below) that, given
>>> two simple functions, f and g,  generates
>>> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
>>> better ways to do this.  I don’t particularly care about the returned list,
>>> I’d be happy to have the final  h_K version of the function,
>>> but I keep losing my way and running into the dreaded:
>>>
>>> Error in h[[1]] : object of type 'closure' is not subsettable
>>> or
>>> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>>>
>>> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
>>> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
>>> something more sensible lurking beneath this minimal (toy)  example.
>>>
>>>     f <- function(u) function(x) u * x^2
>>>     g <- function(u) function(x) u * log(x)
>>>     set.seed(3)
>>>     a <- runif(5)
>>>     h <- list()
>>>     hit <- list()
>>>     h[[1]] <- f(a[1])
>>>     hit[[1]] <- f(a[1])
>>>     for(i in 2:5){
>>>      ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
>>>      h[[i]] <- eval(parse(text = ht))
>>>      hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
>>>      }
>>>     x <- 1:99/10
>>>     plot(x, h[[1]](x), type = "l")
>>>     for(i in 2:5)
>>>      lines(x, h[[i]](x), col = i)
>>
>> I don't understand what "hit" is for, but something like this should do it:
>>
>>
>> hlist <- function(maxk, f,g,a) {
>>   h <- list()
>>   h[[1]] <- f(a[1])
>>   for (j in 2:maxk) {
>>     h[[j]] <- local({
>>       k <- j
>>       function(x) {
>>         result <- h[[1]](x)
>>         for (i in 2:k) {
>>           result <- result*g(a[i])(x)
>>         }
>>         result
>>       }
>>     })
>>   }
>>   h
>> }
>>
>> f <- function(u) function(x) u * x^2
>> g <- function(u) function(x) u * log(x)
>> set.seed(3)
>> a <- runif(5)
>> h <- hlist(5, f, g, a)
>

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
Reply | Threaded
Open this post in threaded view
|

Re: Functional programming?

Roger Koenker-3
In reply to this post by Roger Koenker-3
Thanks again to all.  This was highly educational for me.  As it turned out
Mikiko's suggestion turned out to be most easily adaptable to my real problem.
I’m not at all able to evaluate relative efficiency at this point, but fortunately this isn’t
an important factor (so far) in what I’m trying to do.

As always the knowledge and generosity of the R-help community is inspiring.


url:    www.econ.uiuc.edu/~roger            Roger Koenker
email    [hidden email]            Department of Economics
vox:     217-333-4558                University of Illinois
fax:       217-244-6678                Urbana, IL 61801

> On Mar 2, 2016, at 1:25 PM, Mikko Korpela <[hidden email]> wrote:
>
> On 02.03.2016 18:47, Roger Koenker wrote:
>> I have a (remarkably ugly!!) code snippet  (below) that, given
>> two simple functions, f and g,  generates
>> a list of new functions h_{k+1} =  h_k * g, k= 1, …, K.  Surely, there are vastly
>> better ways to do this.  I don’t particularly care about the returned list,
>> I’d be happy to have the final  h_K version of the function,
>> but I keep losing my way and running into the dreaded:
>>
>> Error in h[[1]] : object of type 'closure' is not subsettable
>> or
>> Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
>>
>> Mainly I’d like to get rid of the horrible, horrible paste/parse/eval evils.  Admittedly
>> the f,g look a bit strange, so you may have to suspend disbelief to imagine that there is
>> something more sensible lurking beneath this minimal (toy)  example.
>>
>>    f <- function(u) function(x) u * x^2
>>    g <- function(u) function(x) u * log(x)
>>    set.seed(3)
>>    a <- runif(5)
>>    h <- list()
>>    hit <- list()
>>    h[[1]] <- f(a[1])
>>    hit[[1]] <- f(a[1])
>>    for(i in 2:5){
>> ht <- paste("function(x) h[[", i-1, "]](x) * g(", a[i], ")(x)")
>> h[[i]] <- eval(parse(text = ht))
>> hit[[i]] <- function(x) {force(i); return(h[[i]] (x))}
>> }
>>    x <- 1:99/10
>>    plot(x, h[[1]](x), type = "l")
>>    for(i in 2:5)
>> lines(x, h[[i]](x), col = i)
>
> Here is my (ugly?) suggestion:
>
> f <- function(u) function(x) u * x^2
> g <- function(u) function(x) u * log(x)
> set.seed(3)
> a <- runif(5)
> h <- f(a[1])
> for (i in 2:5) {
>    body(h) <- call("*", body(h),
>                    as.call(list(do.call("g", list(a[i])), quote(x))))
> }
>
> --
> Mikko Korpela
> Aalto University School of Science
> Department of Computer Science

______________________________________________
[hidden email] mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.