Lisp HUG Maillist Archive

Passing primitive value by reference

Hi
 
One my frind, who likes C++ much, asked me How to pass by reference value of primitive type to function. It's common technique in C/C++ to share one memory cell between multiple functions passing address of cell as value. One way similar to it is to pass value wraped into cons cell. Another way is to use dynamic extent or macro, but it is very ugly.
 
As far as I know a primitive value being passed to a function, remains unmuttable object. So I have to use some wrapper...
To answer a question I should find some way to do it like below:
 
(let ((mutable-var 2))
    (function-to-change-var mutable-var)
mutable-var)
 
So mutable-var is not equals 2 after calling of function-to-change-var.
 
Thanks in advance
Lisper

Re: Passing primitive value by reference

On Mon, Oct 04, 2004, 13:20, lisptracker <lisptracker@mail.ru> wrote
>Hi
>
>One my frind, who likes C++ much, asked me How to pass by reference value 
of primitive type to function. It's common technique in C/C++ to share one 
memory cell between multiple functions passing address of cell as value. One 
way similar to it is to pass value wraped into cons cell. Another way is to 
use dynamic extent or macro, but it is very ugly.
>
>As far as I know a primitive value being passed to a function, remains 
unmuttable object. So I have to use some wrapper...
>To answer a question I should find some way to do it like below:
>
>(let ((mutable-var 2))
>    (function-to-change-var mutable-var)
>mutable-var)
>
>So mutable-var is not equals 2 after calling of function-to-change-var.

Why would you want to do this in Lisp?  WHat are you really trying to do?
I ask because though C and C++ programers frequently need to pass "by 
reference" parameters, I as a Lisp programmer don't recall ever having to do 
so.

The typical use for by-reference parameters in C and C++ is for a function 
to return more than one value, e.g. returning a sucess/failure code as the 
value of the function and filling in some structure which was passed by 
reference.  The way one would do this in Lisp is to have the function return 
multiple values.  In Lisp, functions can return more than one value.  In
C and C++ they can't.

If you really need to be able to have some function modify a value that it 
doesn;t have access to, you can always pass a closure which modifies the 
value, e.g.:

for some code fragment 

   ...
   (let ((change-this-value 7))
     (some-function #'(lambda (new-value)
                        (setq change-this-value new-value)))
     ;; At this point the value of CHANGE-THIS-VALUE is 4
     )
   ...

which calls SOME-FUNCTION and expects it to modify the value of 
CHANGE-THIN-VALUE

(defun some-function (value-changer)
  (funcall value-changer 4))



Re: Passing primitive value by reference

On Monday 04 October 2004 01:20 pm, lisptracker wrote:
> As far as I know a primitive value being passed to a function, remains
> unmuttable object. So I have to use some wrapper... To answer a question I
> should find some way to do it like below:

Make sure that you are comparing apples with apples.

In C, you cannot do the following:

  &7

or

  &(3 + 4)

So, in C, you can't pass the address of a "primitive type", either!  

In C, when you do this:

  int x = 7;
  ...
  &x

You are creating a wrapper (it's name is "x"), putting the primitive value 7 
into it and then taking the address of the wrapper.

If you want to do *exactly* the same thing in lisp, you can use defstruct, 
make-array, cons, defclass and probably a bunch of other things that don't 
come to mind, to create the wrapper.

You can do *exactly* the same thing in Lispworks if you use the FLI, too.

You can play games with the :displaced-to option of make-array, to share 
memory.

But, of course, you're using Lisp so that you never again have to deal with 
the insanity of the baggage that C brings with it, right? :-)

You wouldn't solve the same problem the same way in Lisp as you do in C, 
because Lisp gives you better ways of solving the problem - ways that are 
much less error-prone (one of the points of using a better language!).  
Taking the address of a variable with a cheap built-in syntax is something 
you need to get rid of, so that you can have the much-more-important feature 
of garbage collection.

Sharing memory - without using the address operator - in Lisp is easy.  It 
happens all of the time, for example in lists (e.g. if x is a list, then (cdr 
x) shares memory with x).  C++-people tend to build list operators with 
*less* sharing and more wasted memory (e.g. cursors).

pt



Updated at: 2020-12-10 08:55 UTC