[R] R as a non-functional language

peter dalgaard pdalgd at gmail.com
Sun Mar 20 11:30:58 CET 2011


On Mar 20, 2011, at 06:46 , Russ Abbott wrote:

> I'm afraid I disagree.  As a number of people have shown, it's certainly
> possible to get the end result
> 
>> pH <- c(4.5,7,7.3,8.2,6.3)
>> names(pH) <- c('area1','area2','mud','dam','middle')
>> pH
> area1  area2    mud    dam middle
>   4.5    7.0    7.3    8.2    6.3
> 
> using a single expression. But what makes this non-functional is that the
> names() function operates on a reference to the pH object/entity/element. In
> other words, the names() function has a side effect, which is not permitted
> in strictly functional programming.
> 

Actually, it _is_ functional, sort of.

The convention is that 

names(foo)<-bar 

is syntactic sugar for

foo <- "names<-"(foo, bar)

and if you implements assignment functions in pure R, that is exactly what you need to do. 

If this was followed to the letter, it would indeed be functional, but to avoid duplication of objects (in almost all cases, the returned values is assigned immediately back to the argument in the first argument), some of the frequently used examples allow destructive modification of their arguments. Hence the "sort of" above.

However, this is an implementation hack, and there are cases where the destructive modification is undesirable, e.g. it is unsafe to apply the "f<-" functions directly, where it might otherwise be quite sensible do things like

yesnoFactors <- lapply(dd[3:10], "levels<-" , c("yes","no"))

(The hack is not something that anyone is particularly proud of, but the inefficiency of x[1] <- 1 copying unconditionally for very long vectors is a bit forbidding).


> I don't know if R has threads. But imagine it did and that one ran
> 
>> names(pH) <- c('area1','area2','mud','dam','middle')
> 
> and
> 
>> names(pH) <- c('areaA','areaB','dirt','blockage','center')
> 
> in simultaneous threads. Since they are both operating on the same pH
> element, it is uncertain what the result would be. That's one of the things
> that functional programming prevents.


No, that's not it. If there are two references to pH, names(pH) will duplicate the object before renaming and the pH name will be bound to a different object afterwards. Of course, assignment in itself allows race conditions: if one thread does x <- 1 and the other x <- 2, in the same environment.

(R doesn't have multithreading, but it does allow quite complex evaluation scenarios via GUI callbacks and lazy evaluation, so the multiple reference issues have been given quite a bit of though.)

> 
> *-- Russ *
> 
> 
> 
> On Sat, Mar 19, 2011 at 10:22 PM, <Bill.Venables at csiro.au> wrote:
> 
>> PS the form
>> 
>> names(p) <- c(...)
>> 
>> is still functional, of course.  It is just a bit of syntactic sugar for
>> the clumsier
>> 
>> p <- `names<-`(p, c(...))
>> 
>> e.g.
>>> pH <- `names<-`(pH, letters[1:5])
>>> pH
>> a   b   c   d   e
>> 4.5 7.0 7.3 8.2 6.3
>>> 
>> 
>> 
>> 
>> -----Original Message-----
>> From: Venables, Bill (CMIS, Dutton Park)
>> Sent: Sunday, 20 March 2011 3:09 PM
>> To: 'Gabor Grothendieck'; 'Russ.Abbott at gmail.com'
>> Cc: 'r-help at r-project.org'
>> Subject: RE: [R] R as a non-functional language
>> 
>> The idiom I prefer is
>> 
>> pH <- structure(c(4.5,7,7.3,8.2,6.3),
>>               names = c('area1','area2','mud','dam','middle'))
>> 
>> -----Original Message-----
>> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
>> On Behalf Of Gabor Grothendieck
>> Sent: Sunday, 20 March 2011 2:33 PM
>> To: Russ.Abbott at gmail.com
>> Cc: r-help at r-project.org
>> Subject: Re: [R] R as a non-functional language
>> 
>> On Sun, Mar 20, 2011 at 12:20 AM, Russ Abbott <russ.abbott at gmail.com>
>> wrote:
>>> I'm reading Torgo (2010) *Data Mining with
>>> R*<http://www.liaad.up.pt/~ltorgo/DataMiningWithR/code.html>in
>>> preparation for a class I'll be teaching next quarter.  Here's an
>>> example
>>> that is very non-functional.
>>> 
>>>> pH <- c(4.5,7,7.3,8.2,6.3)
>>>> names(pH) <- c('area1','area2','mud','dam','middle')
>>>> pH
>>> area1  area2    mud    dam middle
>>>  4.5    7.0    7.3    8.2    6.3
>>> 
>>> 
>>> This sort of thing seems to be quite common in R.
>> 
>> Try this:
>> 
>> pH <- setNames(c(4.5,7,7.3,8.2,6.3),
>> c('area1','area2','mud','dam','middle'))
>> 
>> 
>> 
>> 
>> --
>> Statistics & Software Consulting
>> GKX Group, GKX Associates Inc.
>> tel: 1-877-GKX-GROUP
>> email: ggrothendieck at gmail.com
>> 
>> ______________________________________________
>> R-help at r-project.org mailing list
>> 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.
>> 
> 
> 	[[alternative HTML version deleted]]
> 
> ______________________________________________
> R-help at r-project.org mailing list
> 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.

-- 
Peter Dalgaard
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com



More information about the R-help mailing list