Re: [Rd] Julia
On Mon, Mar 05, 2012 at 04:54:05PM -0800, Nicholas Crookston wrote: > There are many experts on this topic. I'll keep this short. > > Newer Fortran Languages allow for call by value, but call by reference > is the typical and historically, the only approach (there was a time > when you could change the value of 1 to 2!). Oh, strange. > > C "only" calls by value except that the value can be a pointer! So, > havoc is just a * away. [...] For me there was no "havoc" at this point, but for others maybe. There are also other languages that only use call-by-value... ...functional languages are that way in principal. Nevertheless internally they may heavily use pointers and even if you have values that are large arrays for example, they internally just give a pointer to that data structure. (That's, why functional languages are not necessarily slow just because you act on large data and have no references in that language. (A common misunderstanding about functional languages must be slow because they have nor references.) The pointer-stuff is just hidden. Even they ((non-purely) functional languages) may have references, their concept of references is different. (See OCaml for example.) There you can use references to change values in place, but the reference itself is a functional value, and you will never have access to the pointer stuff directly. Hence no problems with mem-arithmetics and dangling pointer's or Null-pointers. [...] > I like R and will continue to use it. However, I also think that > strict "call by value" can get you into trouble, just trouble of a > different kind. Can you elaborate more on this? What problems do you have in mind? And what kind of references do you have in mind? The C-like pointers or something like OCaml's ref's? > I'm not sure we will ever yearn for "Julia ouR-Julia", > but it is sure fun to think about what might be possible with this > language. And having fun is one key objective. I have fun if things work. And if the tools do, what I want to achieve... ...and the fun is better, if they do it elegantly. Do you ask for references in R? And what kind of references do you have in mind, and why does it hurt you not to have them? Can you give examples, so that it's easier to see, whwere you miss something? Ciao, Oliver P.S.: The speed issue of R was coming up more than once; in some blog posts it was mentioned. would it make sense to start a seperated thread of it? In one of the blog-articles I read, it was mourned about how NA / missing values were handled, and that NA should maybe become thrown out, just to get higher speed. I would not like to have that. Handling NA as special case IMHO is a very good way. Don't remember if the article I have in mind just argued about HOW this was handled, or if it should be thrown out completely. Making the handling of it better and more performant I think is a good idea, ignoring NA IMHO is a bad idea. But maybe that really would be worth a seperate thread? __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Julia
On Mon, Mar 05, 2012 at 07:33:10PM -0500, Duncan Murdoch wrote: > On 12-03-05 6:58 PM, Hervé Pagès wrote: > >Hi Oliver, > > > >On 03/05/2012 09:08 AM, oliver wrote: > >>On Mon, Mar 05, 2012 at 03:53:28PM +, William Dunlap wrote: > >>>I haven't used Julia yet, but from my quick reading > >>>of the docs it looks like arguments to functions are > >>>passed by reference and not by value, so functions > >>>can change their arguments. My recollection from when > >>>I first started using S (in the course of a job helping > >>>profs and grad students do statistical programming, c. 1983) > >>>is that not having to worry about in-place algorithms changing > >>>your data gave S a big advantage over Fortran or C. > >>[...] > >> > >> > >>C also uses Call-by-Value. > > > >C *only* uses Call-by-Value. > > While literally true, the fact that you can't send an array by > value, and must send the value of a pointer to it, kind of supports > Bill's point: in C, you mostly end up sending arrays by reference. [...] It's a problem of how the term "reference" is used. If you want to limit the possible confsion, better say: giving the pointer-by-value. Or: giving the address-value of the array/struct/... by value. To say, you give the array reference is a shorthand, which maybe creates confusion. Just avoiding the word "reference" here would make it more clear. AFAIK in C++ references are different to pointers. (Some others who know C++ in detail might explain this in detail.) So, using the same terms for many different concepts can create a mess in understanding. Ciao, Oliver __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Julia
On Tue, Mar 06, 2012 at 12:35:32AM +, William Dunlap wrote: [...] > I find R's (& S+'s & S's) copy-on-write-if-not-copying-would-be-discoverable- > by-the-uer machanism for giving the allusion of pass-by-value a good way > to structure the contract between the function writer and the function user. [...] Can you elaborate more on this, especially on the ...-...-...-if-not-copying-would-be-discoverable-by-the-uer stuff? What do you mean with discoverability of not-copying? Ciao, Oliver __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06-03-2012, at 01:21, Dominick Samperi wrote: > Hello, > > I am trying to call the BLAS Level1 function zdotc from R via > a .C call like this: > > #include "R.h" > #include "R_ext/BLAS.h" > > void testzdotc() { >Rcomplex zx[3], zy[3], ret_val; > >zx[0].r = 1.0; zx[0].i = 0.0; >zx[1].r = 2.0; zx[0].i = 0.0; >zx[2].r = 3.0; zx[0].i = 0.0; > >zy[0].r = 1.0; zy[0].i = 0.0; >zy[1].r = 2.0; zy[0].i = 0.0; >zy[2].r = 3.0; zy[0].i = 0.0; > >int n=3, incx=1, incy=1; >F77_CALL(zdotc)(&ret_val, &n, zx, &incx, zy, &incy); >Rprintf("ret_val = %f, %f\n", ret_val.r, ret_val.i); > } > > This does not work. When I run '.C('testzdotc')' there is > typically a delay for a second or so, then I get: 0.0, 0.0 > instead of the correct ans: 14.0, 0.0. I tried calling zdotc through an intermediate Fortran routine hoping it would solve your problem. Above C routine changed to #include "R.h" void F77_NAME(callzdotc)(Rcomplex *, int *, Rcomplex *, int *, Rcomplex *, int *); void testzdotc() { Rcomplex zx[3], zy[3], ret_val; zx[0].r = 1.0; zx[0].i = 0.0; zx[1].r = 2.0; zx[0].i = 0.0; zx[2].r = 3.0; zx[0].i = 0.0; zy[0].r = 1.0; zy[0].i = 0.0; zy[1].r = 2.0; zy[0].i = 0.0; zy[2].r = 3.0; zy[0].i = 0.0; int n=3, incx=1, incy=1; F77_CALL(callzdotc)(&ret_val, &n, zx, &incx, zy, &incy); Rprintf("ret_val = %f, %f\n", ret_val.r, ret_val.i); } The fortran subroutine is subroutine callzdotc(retval,n, zx, incx, zy, incy) integer n, incx, incy double complex retval, zx(*), zy(*) external double complex zdotc retval = zdotc(n, zx, incx, zy, incy) return end Made a shared object with R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c and ran dyn.load("dozdot.so") .C("testzdotc") with the result 0.0, 0.0 I would've expected this to give the correct result. Berend Mac OS X 10.6.8 R2.14.2 Using reference Rblas. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
G'day Berend, On Tue, 6 Mar 2012 11:19:07 +0100 Berend Hasselman wrote: > On 06-03-2012, at 01:21, Dominick Samperi wrote: [...] > >zx[0].r = 1.0; zx[0].i = 0.0; > >zx[1].r = 2.0; zx[0].i = 0.0; > >zx[2].r = 3.0; zx[0].i = 0.0; Just noticing that it is always zx[0].i, same with the imaginary part of zy. But this is probably not of importance. :) > I tried calling zdotc through an intermediate Fortran routine hoping > it would solve your problem. [...] > Above C routine changed to [...] > The fortran subroutine is > > > subroutine callzdotc(retval,n, zx, incx, zy, incy) > integer n, incx, incy > double complex retval, zx(*), zy(*) > external double complex zdotc > > retval = zdotc(n, zx, incx, zy, incy) > > return > end > > > Made a shared object with > > R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c > > and ran > > dyn.load("dozdot.so") > .C("testzdotc") > > with the result 0.0, 0.0 Same here. Once I change the line external double complex zdotc in your fortran subroutine to double complex zdotc everything works fine and I get as result 14.0, 0.0. It is long time ago that I was taught (and studied) the FORTRAN 77 standard. But flipping through some books from that time I thing I have some inkling on what is going on. The "external" statement is not needed here (seems to be used in the sense that C is using the "external" statement). Cheers, Berwin __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06-03-2012, at 12:56, Berwin A Turlach wrote: > G'day Berend, > > [..] >> I tried calling zdotc through an intermediate Fortran routine hoping >> it would solve your problem. > [...] >> Above C routine changed to > [...] >> The fortran subroutine is >> >> >> subroutine callzdotc(retval,n, zx, incx, zy, incy) >> integer n, incx, incy >> double complex retval, zx(*), zy(*) >> external double complex zdotc >> >> retval = zdotc(n, zx, incx, zy, incy) >> >> return >> end >> >> >> Made a shared object with >> >> R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c >> >> and ran >> >> dyn.load("dozdot.so") >> .C("testzdotc") >> >> with the result 0.0, 0.0 > > Same here. > > Once I change the line > > external double complex zdotc > > in your fortran subroutine to > > double complex zdotc > > everything works fine and I get as result 14.0, 0.0. > > It is long time ago that I was taught (and studied) the FORTRAN 77 > standard. But flipping through some books from that time I thing I > have some inkling on what is going on. The "external" statement is not > needed here (seems to be used in the sense that C is using the > "external" statement). Thanks. I should have tried that too. This implies that Dominick's original issue can be avoided by using an intermediate Fortran routine. But I would really like to hear from an Rexpert why you shouldn't/can't use external here in the Fortran. Berend __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
G'day Berend, On Tue, 6 Mar 2012 13:06:34 +0100 Berend Hasselman wrote: [... big snip ...] > But I would really like to hear from an Rexpert why you > shouldn't/can't use external here in the Fortran. Probably less a question for an Rexpert but for a Fortran expert If you insert "implicit none" (one of my favourite extensions that I always use) as the first statement after subroutine callzdotc(retval,n, zx, incx, zy, incy) you will see what is going on. The compiler should refuse compilation and complain that the type of zdotc was not declared (at least my compiler does). For FORTRAN to know that zdotc returns a double complex you need the double complex zdotc declaration in callzdotc. An external double complex zdotc would be necessary if you were to call another subroutine/function, say foo, that accepts functions as formal arguments and you want to pass zdotc via such an argument. Something like subroutine callzdotc() external double complex zdotc call foo(a, b, zdotc) return end subroutine(a, b, h) double complex h, t t = h(..,..,..,..) return end In C, the qualifier (or whatever the technical term is) "external" is used to indicate that the function/variable/symbol is defined in another compilation unit. In FORTRAN77, "external" is used to tell the compiler that you are passing a function to another function/subroutine. At least that is my understanding from what I re-read in my FORTRAN documentation. Thus, perhaps strangely, if there is only a external double complex zdotc declaration in your subroutine, the compiler doesn't know that a call to zdotc will return a double complex but will assume that the result has the implicitly defined type, a real*8 IIRC. So zdotc is called, and puts a double complex as result on the stack (heap?), but within callzdotc a real as return is expected and that is taken from the stack (heap?), that real is than coerced to a double complex when assigned to retval. Note that while I am pretty sure about the above, this last paragraph is more speculative. :) But it would explain why the erroneous code returns 0 on little-endian machines. HTH. Cheers, Berwin Cheers, Berwin __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06-03-2012, at 14:37, Berwin A Turlach wrote: > G'day Berend, > > On Tue, 6 Mar 2012 13:06:34 +0100 > Berend Hasselman wrote: > > [... big snip ...] > >> But I would really like to hear from an Rexpert why you >> shouldn't/can't use external here in the Fortran. > > Probably less a question for an Rexpert but for a Fortran expert > > If you insert "implicit none" (one of my favourite extensions that I > always use) as the first statement after > subroutine callzdotc(retval,n, zx, incx, zy, incy) > you will see what is going on. The compiler should refuse compilation > and complain that the type of zdotc was not declared (at least my > compiler does). For FORTRAN to know that zdotc returns a double > complex you need the > double complex zdotc > declaration in callzdotc. > I usually use -fimplicit-none or a similar option as argument for a fortran compiler. I didn't use it in a syntax checking pre compiling run. > An > external double complex zdotc > would be necessary if you were to call another subroutine/function, say > foo, that accepts functions as formal arguments and you want to pass > zdotc via such an argument. Something like > > subroutine callzdotc() > >external double complex zdotc > >call foo(a, b, zdotc) > > return > end > > subroutine(a, b, h) > double complex h, t > > t = h(..,..,..,..) > > return > end > > In C, the qualifier (or whatever the technical term is) "external" is > used to indicate that the function/variable/symbol is defined in > another compilation unit. In FORTRAN77, "external" is used to tell the > compiler that you are passing a function to another > function/subroutine. At least that is my understanding from what I > re-read in my FORTRAN documentation. Not quite true. It is required to use external if you are passing the name of a function/subroutine to another routine. Otherwise it is just a statement telling the compile that the is external to the function/subroutine/.. being compiled. See http://www.fortran.com/F77_std/rjcnf0001-sh-8.html#sh-8.7 > > Thus, perhaps strangely, if there is only a > external double complex zdotc > declaration in your subroutine, the compiler doesn't know that a call > If I am reading the above reference correctly, the syntax external double complex zdotc is simply incorrect (correct syntax uses commas to separate names e.g. A,B,C). The compiler (gfortran) simply seems to ignore the "double" and the "complex" if you don't use implicit none. Berend __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06/03/2012 13:37, Berwin A Turlach wrote: G'day Berend, On Tue, 6 Mar 2012 13:06:34 +0100 Berend Hasselman wrote: [... big snip ...] But I would really like to hear from an Rexpert why you shouldn't/can't use external here in the Fortran. Probably less a question for an Rexpert but for a Fortran expert Exactly If you insert "implicit none" (one of my favourite extensions that I always use) as the first statement after subroutine callzdotc(retval,n, zx, incx, zy, incy) you will see what is going on. The compiler should refuse compilation and complain that the type of zdotc was not declared (at least my compiler does). For FORTRAN to know that zdotc returns a double complex you need the double complex zdotc declaration in callzdotc. An external double complex zdotc would be necessary if you were to call another subroutine/function, say foo, that accepts functions as formal arguments and you want to pass zdotc via such an argument. Something like subroutine callzdotc() external double complex zdotc call foo(a, b, zdotc) return end subroutine(a, b, h) double complex h, t t = h(..,..,..,..) return end In C, the qualifier (or whatever the technical term is) "external" is 'extern' in C? used to indicate that the function/variable/symbol is defined in another compilation unit. In FORTRAN77, "external" is used to tell the compiler that you are passing a function to another function/subroutine. At least that is my understanding from what I re-read in my FORTRAN documentation. Not quite. It also means that you really want to externally link and not allow the compiler to find any routine of that name it knows about (e.g. an intrinsic). See para 8.7 of http://www.fortran.com/F77_std/rjcnf-8.html (although I got this from my Fortran reference on my bookshelf). Thus, perhaps strangely, if there is only a external double complex zdotc declaration in your subroutine, the compiler doesn't know that a call The only 'strangely' thing is that is accepted: AFAICS is it not valid according to the link above. to zdotc will return a double complex but will assume that the result has the implicitly defined type, a real*8 IIRC. The Fortran default type for z* is real. > So zdotc is called, and puts a double complex as result on the stack (heap?), but within callzdotc a real as return is expected and that is taken from the stack (heap?), that real is than coerced to a double complex when assigned to retval. Note that while I am pretty sure about the above, this last paragraph is more speculative. :) But it would explain why the erroneous code returns 0 on little-endian machines. We haven't been told which machines, and this actually matters down to the level of optimization used by the compilers. But these days typically double complex gets passed in sse registers, and double is passed in fpu registers. Note that passing double complex/Rcomplex as return values, from C or Fortran, is rather fragile in that it does depend on a pretty precise match of compilers (and R's configure does test the constructions it uses, and from time to time finds combinations which fail -- R 2.12.2 was released to workaround one of them). -- Brian D. Ripley, rip...@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UKFax: +44 1865 272595 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06-03-2012, at 15:17, Prof Brian Ripley wrote: >> [..] >> used to indicate that the function/variable/symbol is defined in >> another compilation unit. In FORTRAN77, "external" is used to tell the >> compiler that you are passing a function to another >> function/subroutine. At least that is my understanding from what I >> re-read in my FORTRAN documentation. > > Not quite. It also means that you really want to externally link and not > allow the compiler to find any routine of that name it knows about (e.g. an > intrinsic). See para 8.7 of http://www.fortran.com/F77_std/rjcnf-8.html > (although I got this from my Fortran reference on my bookshelf). > >> Thus, perhaps strangely, if there is only a >> external double complex zdotc >> declaration in your subroutine, the compiler doesn't know that a call > > The only 'strangely' thing is that is accepted: AFAICS is it not valid > according to the link above. > Agree. The fortran 77 standard doesn't allow that syntax and I'm really surprised that no error is flagged. >> to zdotc will return a double complex but will assume that the result >> has the implicitly defined type, a real*8 IIRC. > > The Fortran default type for z* is real. > > > So zdotc is called, and >> puts a double complex as result on the stack (heap?), but within >> callzdotc a real as return is expected and that is taken from the >> stack (heap?), that real is than coerced to a double complex when >> assigned to retval. Note that while I am pretty sure about the above, >> this last paragraph is more speculative. :) But it would explain why >> the erroneous code returns 0 on little-endian machines. > > We haven't been told which machines, and this actually matters down to the > level of optimization used by the compilers. But these days typically double > complex gets passed in sse registers, and double is passed in fpu registers. > Mac OS X 10.6.8, Mini Core 2 Duo Apple gcc (i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)) and gfortran (GNU Fortran (GCC) 4.2.1 (Apple Inc. build 5664)) from r.research.att.com. Output from R CMD SHLIB --output=dozdot.so callzdotc.f czdot.c gfortran -arch x86_64 -fPIC -g -O2 -c callzdotc.f -o callzdotc.o gcc -arch x86_64 -std=gnu99 -I/Library/Frameworks/R.framework/Resources/include -I/Library/Frameworks/R.framework/Resources/include/x86_64 -I/usr/local/include-fPIC -g -O2 -c czdot.c -o czdot.o gcc -arch x86_64 -std=gnu99 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/lib -o dozdot.so callzdotc.o czdot.o -lgfortran -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation Same thing happens with gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 and gfortran on Xubuntu 11.10 64-bit. Berend __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06/03/2012 06:28, Berwin A Turlach wrote: G'day Dominick, On Mon, 5 Mar 2012 19:21:01 -0500 Dominick Samperi wrote: ... This is consistent with the interface prototype for the BLAS routine zdotc contained in/include/R_ext/BLAS.h, namely, BLAS_extern Rcomplex F77_NAME(zdotc)(Rcomplex * ret_val, int *n, Rcomplex *zx, int *incx, Rcomplex *zy, int *incy); [...] On the other hand, this is not consistent with the standard FORTRAN definition for zdotc that is contained in /src/extra/blas/cmplxblas.f, where the first argument is n, not ret_val. This seems to be indeed inconsistent and, presumably, a bug. Applying the attach patch to R's development version (compiles, installs and passes all checks with this patch), and changing in your code the line As I said elsewhere in this thread, this really is very compiler-specific, and rather than being a bug, that header is not appropriate to the compilers used (it came from the days of f2c and Fortran compilers based on it such as g77). I'll change the sources to follow your patch as I think it is much more likely to be correct these days, but also add a warning in the header. I don't think it is safe to call these functions from C without configure-testing the effect. F77_CALL(zdotc)(&ret_val,&n, zx,&incx, zy,&incy); to ret_val = F77_CALL(zdotc)(&n, zx,&incx, zy,&incy); produces the expected output. -- Brian D. Ripley, rip...@stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UKFax: +44 1865 272595 __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On 06-03-2012, at 15:46, Berend Hasselman wrote: > >> >>> Thus, perhaps strangely, if there is only a >>> external double complex zdotc >>> declaration in your subroutine, the compiler doesn't know that a call >> >> The only 'strangely' thing is that is accepted: AFAICS is it not valid >> according to the link above. >> > > Agree. The fortran 77 standard doesn't allow that syntax and I'm really > surprised that no error is flagged. > Got it. See http://www.fortran.com/F77_std/rjcnf0001-sh-3.html#sh-3.1.6 Compiler ignores the blanks and external double complex zdotc becomes external doublecomplexzdotc And that is legal. And how long have I been using Fortran? I won't tell. Berend __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Julia
S (and its derivatives and successors) promises that functions will not change their arguments, so in an expression like val <- func(arg) you know that arg will not be changed. You can do that by having func copy arg before doing anything, but that uses space and time that you want to conserve. If arg is not a named item in any environment then it should be fine to write over the original because there is no way the caller can detect that shortcut. E.g., in cx <- cos(runif(n)) the cos function does not need to allocate new space for its output, it can just write over its input because, without a name attached to it, the caller has no way of looking at what runif(n) returned. If you did x <- runif(n) cx <- cos(x) then cos would have to allocate new space for its output because overwriting its input would affect a subsequent sum(x) I suppose that end-users and function-writers could learn to live with having to decide when to copy, but not having to make that decision makes S more pleasant (and safer) to use. I think that is a major reason that people are able to share S code so easily. Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com > -Original Message- > From: oliver [mailto:oli...@first.in-berlin.de] > Sent: Tuesday, March 06, 2012 1:12 AM > To: William Dunlap > Cc: Hervé Pagès; R-devel > Subject: Re: [Rd] Julia > > On Tue, Mar 06, 2012 at 12:35:32AM +, William Dunlap wrote: > [...] > > I find R's (& S+'s & S's) > > copy-on-write-if-not-copying-would-be-discoverable- > > by-the-uer machanism for giving the allusion of pass-by-value a good way > > to structure the contract between the function writer and the function user. > [...] > > > Can you elaborate more on this, > especially on the ...-...-...-if-not-copying-would-be-discoverable-by-the-uer > stuff? > > What do you mean with discoverability of not-copying? > > Ciao, >Oliver __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Julia
On Tue, Mar 6, 2012 at 11:44 AM, William Dunlap wrote: > S (and its derivatives and successors) promises that functions > will not change their arguments, so in an expression like > val <- func(arg) > you know that arg will not be changed. You can > do that by having func copy arg before doing anything, > but that uses space and time that you want to conserve. > If arg is not a named item in any environment then it > should be fine to write over the original because there > is no way the caller can detect that shortcut. E.g., in > cx <- cos(runif(n)) > the cos function does not need to allocate new space for > its output, it can just write over its input because, without > a name attached to it, the caller has no way of looking > at what runif(n) returned. If you did > x <- runif(n) > cx <- cos(x) > then cos would have to allocate new space for its output > because overwriting its input would affect a subsequent > sum(x) > I suppose that end-users and function-writers could learn > to live with having to decide when to copy, but not having > to make that decision makes S more pleasant (and safer) to use. > I think that is a major reason that people are able to > share S code so easily. But don't forget the "Holy Grail" that Doug mentioned at the start of this thread: finding a flexible language that is also fast. Currently many R packages employ C/C++ components to compensate for the fact that the R interpreter can be slow, and the pass-by-value semantics of S provides no protection here. In 2008 Ross Ihaka and Duncan Temple Lang published the paper "Back to the Future: Lisp as a base for a statistical computing system" where they propose Common Lisp as a new foundation for R. They suggest that this could be done while maintaining the same familiar R syntax. A key requirement of any strategy is to maintain easy access to the huge universe of existing C/C++/Fortran numerical and graphics libraries, as these libraries are not likely to be rewritten. Thus there will always be a need for a foreign function interface, and the problem is to provide a flexible and type-safe language that does not force developers to use another unfamiliar, less flexible, and error-prone language to optimize the hot spots. Dominick > Bill Dunlap > Spotfire, TIBCO Software > wdunlap tibco.com > >> -Original Message- >> From: oliver [mailto:oli...@first.in-berlin.de] >> Sent: Tuesday, March 06, 2012 1:12 AM >> To: William Dunlap >> Cc: Hervé Pagès; R-devel >> Subject: Re: [Rd] Julia >> >> On Tue, Mar 06, 2012 at 12:35:32AM +, William Dunlap wrote: >> [...] >> > I find R's (& S+'s & S's) >> > copy-on-write-if-not-copying-would-be-discoverable- >> > by-the-uer machanism for giving the allusion of pass-by-value a good way >> > to structure the contract between the function writer and the function >> > user. >> [...] >> >> >> Can you elaborate more on this, >> especially on the ...-...-...-if-not-copying-would-be-discoverable-by-the-uer >> stuff? >> >> What do you mean with discoverability of not-copying? >> >> Ciao, >> Oliver > __ > R-devel@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] Calling FORTRAN function from R issue?
On Tue, Mar 6, 2012 at 9:17 AM, Prof Brian Ripley wrote: > On 06/03/2012 13:37, Berwin A Turlach wrote: >> >> G'day Berend, >> >> On Tue, 6 Mar 2012 13:06:34 +0100 >> Berend Hasselman wrote: >> >> [... big snip ...] >> >>> But I would really like to hear from an Rexpert why you >>> shouldn't/can't use external here in the Fortran. >> >> >> Probably less a question for an Rexpert but for a Fortran expert > > > Exactly > > >> If you insert "implicit none" (one of my favourite extensions that I >> always use) as the first statement after >> subroutine callzdotc(retval,n, zx, incx, zy, incy) >> you will see what is going on. The compiler should refuse compilation >> and complain that the type of zdotc was not declared (at least my >> compiler does). For FORTRAN to know that zdotc returns a double >> complex you need the >> double complex zdotc >> declaration in callzdotc. >> >> An >> external double complex zdotc >> would be necessary if you were to call another subroutine/function, say >> foo, that accepts functions as formal arguments and you want to pass >> zdotc via such an argument. Something like >> >> subroutine callzdotc() >> >> external double complex zdotc >> >> call foo(a, b, zdotc) >> >> return >> end >> >> subroutine(a, b, h) >> double complex h, t >> >> t = h(..,..,..,..) >> >> return >> end >> >> In C, the qualifier (or whatever the technical term is) "external" is > > > 'extern' in C? > > >> used to indicate that the function/variable/symbol is defined in >> another compilation unit. In FORTRAN77, "external" is used to tell the >> compiler that you are passing a function to another >> function/subroutine. At least that is my understanding from what I >> re-read in my FORTRAN documentation. > > > Not quite. It also means that you really want to externally link and not > allow the compiler to find any routine of that name it knows about (e.g. an > intrinsic). See para 8.7 of http://www.fortran.com/F77_std/rjcnf-8.html > (although I got this from my Fortran reference on my bookshelf). > > >> Thus, perhaps strangely, if there is only a >> external double complex zdotc >> declaration in your subroutine, the compiler doesn't know that a call > > > The only 'strangely' thing is that is accepted: AFAICS is it not valid > according to the link above. > > >> to zdotc will return a double complex but will assume that the result >> has the implicitly defined type, a real*8 IIRC. > > > The Fortran default type for z* is real. > > >> So zdotc is called, and >> >> puts a double complex as result on the stack (heap?), but within >> callzdotc a real as return is expected and that is taken from the >> stack (heap?), that real is than coerced to a double complex when >> assigned to retval. Note that while I am pretty sure about the above, >> this last paragraph is more speculative. :) But it would explain why >> the erroneous code returns 0 on little-endian machines. > > > We haven't been told which machines, and this actually matters down to the > level of optimization used by the compilers. But these days typically > double complex gets passed in sse registers, and double is passed in fpu > registers. > > Note that passing double complex/Rcomplex as return values, from C or > Fortran, is rather fragile in that it does depend on a pretty precise match > of compilers (and R's configure does test the constructions it uses, and > from time to time finds combinations which fail -- R 2.12.2 was released to > workaround one of them). It turns the problem reported above was discovered in a completely different context, unrelated to R, and when I looked at how R handles the problem I found similar issues. As Brian says, the C/Fortran interface can be fragile and machine/compiler-dependent. The code appended below may shed some light on the issues. The Fortran code provides three interfaces to zdotc, two function interfaces and one subroutine interface. The test driver exercises each interface and the results are what you would expect. This was tested using gfortran/gcc under Fedora 16 (64bit). This depends on the particular way the gfortran and gcc interact, specifically, the -std=gnu flag is important (it is also the default). Also, it is important to remember that REAL in Fortran maps to float in C, REAL*16 maps to double, DOUBLE COMPLEX maps to complex, etc. To run the executable you may have to use: export LD_LIBRARY_PATH=. *** Makefile *** testzdotc: gfortran -std=gnu -fPIC -shared -o libmyblas.so zdotc.f gcc -o testzdotc testzdotc.c -L/home/dsamperi -lmyblas -lm *** testzdotc.c *** #include #include extern double complex zdotc1_(int*,complex*,int*,complex*,int*); extern void zdotc2_(complex*,int*,complex*,int*,complex*,int*); extern float zdotc3_(int*,complex*,int*,complex*,int*); int main() { int n