[Rd] Julia

oliver oliver at first.in-berlin.de
Wed Mar 7 16:50:47 CET 2012


On Wed, Mar 07, 2012 at 10:31:14AM -0500, Dominick Samperi wrote:
> On Tue, Mar 6, 2012 at 3:56 AM, oliver <oliver at first.in-berlin.de> wrote:
> > 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?
> 
> OCaml refs are an "escape hatch" from the pure
> functional programming paradigm where nothing can
> be changed once given a value, an extreme form of
> pass-by-value.

OCaml is not a purely functional language and has
not the claim to be one; hence it's not an "escape hatch"
(which seem to have a negative touch to me).

Arrays and strings in OCaml are also imperative.
And with the "mutable" attribute in records, you also can
crearte imperative record entries.

So, it's just a different design / approach than
Haskell for example. OCaml is coming from ML-languages.

Purely Functional on the one hand is beautiful, and 
therefore nice; but it also is dogmatic on the other hand.

> Similarly, most languages that are
> advertised as pass-by-value include some kind of
> escape hatch that permits you to work with pointers
> (or mutable vectors) for improved runtime performance.

References in OCaml are NOT pointers.
You do have access in an imperative / in-place way, but you
have NO POINTER STUFF in that language.

====================================================
# let a = ref 5;;
val a : int ref = {contents = 5}
# a := 7;;
- : unit = ()
# a;;
- : int ref = {contents = 7}
# 
====================================================

This is in-place modification of the contents of the ref,
without any pointer arithmetics.
"a" is a functional value which hosts an imperative one
on the inside.


> 
> The speed issues arise for two main reasons: interpreting
> code is much slower than running machine code, and
> copying large data structures can be expensive.

The functional approach often saves time and space.
This is just not well known.
And the distinction of imperative vs. functional has
nothing to do with interpreted vs. directly executed.


====================================================
# let mylist_1 = [ 3;5;323 ];;
val mylist_1 : int list = [3; 5; 323]
# let mylist_2 = 12 :: mylist_1;;
val mylist_2 : int list = [12; 3; 5; 323]
# mylist_1;;
- : int list = [3; 5; 323]
# mylist_2;;
- : int list = [12; 3; 5; 323]
# 
====================================================

Both lists share the common elements here.
No copy is done.
In this case the functional approach is very nice.

Just a counter-example to "functional is eating up space".

When thinking about the questions here, I think
the design of Ocaml addressed all this, and that this was
the design decision, why arrays are possible to be changed
imperatively.

====================================================
# let my_array = [| 1; 3; 54; 99 |];;
val my_array : int array = [|1; 3; 54; 99|]
# my_array;;
- : int array = [|1; 3; 54; 99|]
# my_array.(2) <- 99999;;
- : unit = ()
# my_array;;
- : int array = [|1; 3; 99999; 99|]
# 
====================================================

If R is rather purely functional here,
then the problem addressed here is, that
a pureley functional approach without any "escape hatches"
creates the problem.

If in-place modification is also not possible on arrays,
then this is the base of the problem.

But changing this behaviour in newer versions of R
would brake a lot of already existing R-code.


Ciao,
   Oliver



More information about the R-devel mailing list