From: Oli Schwarz
Subject: call by value
Date: 
Message-ID: <cduf93$gt6$1@online.de>
Hello,

does Lisp use exclusive "call by value"? In some other languages I know
(python or java) object-orientated datatypes are "called by reference".

I want to handle a stream to a file. I could use one function, which
opens and returns this stream. Then there could be another function,
which gets one parameter, the created stream and closes this stream. Is
this ok or should i use a global variable for the stream?

I' dont understand exactly what happens when a function gets a stream
as a parameter. Is the stream copied, so that there are 2 streams to the
same file in the system? Is the stream in the calling-function still
available when the other function returns.

Thanks
Oli

From: Rahul Jain
Subject: Re: call by value
Date: 
Message-ID: <87fz7hhzr3.fsf@nyct.net>
Oli Schwarz <·····@gmx.net> writes:

> Hello,
>
> does Lisp use exclusive "call by value"?

Yes, but one can use macros and setf to get a sort of CBR behavior.

> In some other languages I know
> (python or java) object-orientated datatypes are "called by reference".

This is false. They pass a value, the object. They do not pass in a
reference that can be re-assigned to something else.

private void mutateRef(Object x) {
    x = new Object();
}

public static void main(String[]args) {
    Object x = new Object();
    Object originalx = x;
    System.out.println((mutateRef(x) == originalx)?"CBV":"CBR");
}

There is also call-by-name which actually re-evaluates the what is in
the parameter location syntactically each time the parameter is
referenced in the function. This can also be emulated with lisp macros. 
Macros of this type are often referred to as "control structures".

> I want to handle a stream to a file. I could use one function, which
> opens and returns this stream. Then there could be another function,
> which gets one parameter, the created stream and closes this stream. Is
> this ok or should i use a global variable for the stream?

To be techical, CL doesn't have global variables. There are only dynamic
variables which may have a global binding. However, if you don't use LET
to shadow such bindings, you'll never see the difference.

Are you sure you want to use this "singleton pattern" (which was
actually called the "simpleton pattern" by someone... a nice Freudian
slip... or just someone who is just exceptionally insightful) way of
dealing with streams? You should probably be passing the stream
(possibly as part of another data structure) down to the place where it
is used so that your code can be used on more than one stream at a time.

You could also have a dynamic variable that is the default stream for
this library and allow an optional or keyword arg to override that
value. With this method, you could thread-locally change the default
stream by re-binding that variable within that thread, as well. This is
how all the lisp stream manipulation functions work already, with the
variable being *STANDARD-OUTPUT*.

> I' dont understand exactly what happens when a function gets a stream
> as a parameter. Is the stream copied, so that there are 2 streams to the
> same file in the system? Is the stream in the calling-function still
> available when the other function returns.

Most "mainstream" languages use the same argument-passing behaviors as
lisp.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Alex Mizrahi
Subject: Re: call by value
Date: 
Message-ID: <2mi0peFmh2faU1@uni-berlin.de>
(message (Hello 'Rahul)
(you :wrote  :on '(Sat, 24 Jul 2004 17:16:48 -0400))
(

 RJ> Most "mainstream" languages use the same argument-passing behaviors
 RJ> as lisp.

really? lisp way of passing arguments was a surprise for me after c++,
object pascal and vbasic..
main difference i think is because some things are immutable in lisp
(numbers, for example) or are muttable in quite odd way.
for example, you can add elements to end of list because conses are
mutable - but only when size of this list is at least one.
i still (after almost 100kb of lisp code written 8-] )  sometimes get stuck
when i need mutable parameter (possibly there are better solutions that
doesn't require mutable parameters)..

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
(prin1 "Jane dates only Lisp programmers"))
From: ·········@random-state.net
Subject: Re: call by value
Date: 
Message-ID: <ce0q23$41o0c$2@midnight.cs.hut.fi>
Alex Mizrahi <········@hotmail.com> wrote:

> really? lisp way of passing arguments was a surprise for me after c++,
> object pascal and vbasic..

I like to think of C++ as call-by-obscenity language. 

...and that wasn't just a stupid quip: I was really disguested when I
learned of the copy-semantics in C++ function calls.

> for example, you can add elements to end of list because conses are
> mutable - but only when size of this list is at least one.

That's not really a lisp issue, but the way unencapsulated singly linked
lists behave in any language.

Cheers,

 -- Nikodemus                   "Not as clumsy or random as a C++ or Java. 
                             An elegant weapon for a more civilized time."
From: Alex Mizrahi
Subject: Re: call by value
Date: 
Message-ID: <2mlmepFoia2gU1@uni-berlin.de>
(message (Hello ··········@random-state.net)
(you :wrote  :on '(25 Jul 2004 17:18:59 GMT))
(

 >> really? lisp way of passing arguments was a surprise for me after
 >> c++, object pascal and vbasic..

 n> I like to think of C++ as call-by-obscenity language.

 n> ...and that wasn't just a stupid quip: I was really disguested when I
 n> learned of the copy-semantics in C++ function calls.

strange, i find C++ way of calling/passing parameters quite OK..
what do you dislike in it?

 >> for example, you can add elements to end of list because conses are
 >> mutable - but only when size of this list is at least one.

 n> That's not really a lisp issue, but the way unencapsulated singly
 n> linked lists behave in any language.

nope, it's lisp way of handling variables..
it could be solved like this:

(defun foo()
  (let* ((mylist (list 1 2 3))
  (mylist-setter (lambda (x) (setq mylist x))))
    (bar mylist mylist-setter)
    mylist))

(defun bar (list list-setter)
  (funcall list-setter (cons 'bar list)))

(foo) => (BAR 1 2 3)

as far as i know there's no way to modify mylist variable in lexical scope
without mylist-setter from another function.
but in C/C++ i could pass mylist as reference or pointer - and modify it
without any setters..
you can call this "encapsulated", but it's quite transparent language
constuct. who cares that instead of pointer on list head pointer on variable
that contains list head is passed? all this is done by compiler, program
looks same except little & sign.
with dynamic variables in lisp something like pointers can be done - i can
pass symbol of variable, and then call set on it instead of setq. however,
it's not as transparent as C/C++ references - if i want value of such
variable i'll need to call symbol-value..

)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
(prin1 "Jane dates only Lisp programmers"))
From: Rahul Jain
Subject: Re: call by value
Date: 
Message-ID: <87pt67pyw9.fsf@nyct.net>
"Alex Mizrahi" <········@hotmail.com> writes:

> as far as i know there's no way to modify mylist variable in lexical scope
> without mylist-setter from another function.

You define a modifier-macro. DEFINE-MODIFIER-MACRO for the simple cases
where the modifier can be expressed as a function that returns the new
value, or make a macro which gets the setf-expansion from the
environment for the variable passed in to be modified and calls the
getter and setter expansions as needed.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Gareth McCaughan
Subject: Re: call by value
Date: 
Message-ID: <87wu0tqff2.fsf@g.mccaughan.ntlworld.com>
Oli Schwarz wrote:

> does Lisp use exclusive "call by value"? In some other languages I know
> (python or java) object-orientated datatypes are "called by reference".

Lisp uses call by value, but the values are object references.
Same as in Python, for instance. If you call what Python does
"call by reference" then you might as well use the same term
for Lisp.

(in-digression
    I happen to think that the term "call by reference" is best avoided,
    because it's ambiguous. In your description of Python and Java
    (and, accordingly, Lisp) a "reference" means something that refers
    to an *object*, and "call by reference" means that a function gets
    to do stuff with the *same* object that's passed, not just a
    copy. But in other contexts -- such as in Algol and C++ -- a
    "reference" means something that refers to a *variable*, and
    "call by reference" means that calling f(x) can make the variable
    x be bound to something entirely different.
    
    So, compare
    
        def f(x):
          x = 1
    
    in Python with
    
        void f1(int x) { x=1; }
        void f2(int& x) { x=1; }
    
    in C++. The second one is what a C++ programmer would call
    "call by reference", but it doesn't correspond to what the
    Python code does. The first one is what a C++ programmer
    would call "call by value", and ... actually, it doesn't
    correspond to what the Python code does *either*, really.
    Calling f1 notionally copies the argument you pass. It
    just happens that for ints, this doesn't make any difference.)

Anyway: if you have a solid understanding of what happens
in Python and in Java, then Lisp's behaviour should not
surprise you.

> I want to handle a stream to a file. I could use one function, which
> opens and returns this stream. Then there could be another function,
> which gets one parameter, the created stream and closes this stream. Is
> this ok or should i use a global variable for the stream?

It's "OK" in the sense that it will work. In fact, you've
just described the functions OPEN and CLOSE. :-) But that
sort of design is often poor style, because of the possibility
that one of the functions will get called without the other.
Common Lisp provides a macro called WITH-OPEN-FILE that lets
you say something like this:

    (with-open-file (f "foo.txt" :direction :output)
      (format f "This line will be written to foo.txt.~%")
      (error "bang!")
      (format f "This line won't be written anywhere.~%")
      (format f "But the file will get closed properly.~%"))

Sometimes it's not convenient to enclose all your uses
of a stream in a single WITH-OPEN-FILE or whatever. The
usual reason for this is that they're spread throughout
the whole system, or a large part of it. In that situation,
using a global variable would probably be appropriate.

> I' dont understand exactly what happens when a function gets a stream
> as a parameter. Is the stream copied, so that there are 2 streams to the
> same file in the system? Is the stream in the calling-function still
> available when the other function returns.

No copying takes place. If you call two different functions
with the stream as parameter to each, each function gets
(a reference to) the same stream.

-- 
Gareth McCaughan
.sig under construc
From: Rahul Jain
Subject: Re: call by value
Date: 
Message-ID: <87bri5hwo7.fsf@nyct.net>
Gareth McCaughan <················@pobox.com> writes:

>     in C++. The second one is what a C++ programmer would call
>     "call by reference", but it doesn't correspond to what the
>     Python code does. The first one is what a C++ programmer
>     would call "call by value", and ... actually, it doesn't
>     correspond to what the Python code does *either*, really.
>     Calling f1 notionally copies the argument you pass. It
>     just happens that for ints, this doesn't make any difference.)

The argument you pass in object-oriented languages like Lisp, Python,
and Java is a reference to an object (except that in Python and Java
there are non-object values, too). This is distinct from calling a
function and having _your_ reference passed in and from passing entire
data structures by value. In C++, you can make all those distinctions. 
You can pass a reference by reference (foo *& f), a reference by value
(foo * f), a value by reference (foo& f), or a value by value (foo f). 
Passing a reference vs. a value is only meaningful if a mutable object
is passed.

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Thomas Schilling
Subject: Re: call by value
Date: 
Message-ID: <opsbnu8omttrs3c0@news.CIS.DFN.DE>
> does Lisp use exclusive "call by value"? In some other languages I know
> (python or java) object-orientated datatypes are "called by reference".

(Hm, never really thought about it, but I now find it's really hard to 
explain.)

...

Okay, I give up.

Peter can surely help you. See section "Assignment":

  http://www.gigamonkeys.com/book/variables.html

> I want to handle a stream to a file. I could use one function, which
> opens and returns this stream. Then there could be another function,
> which gets one parameter, the created stream and closes this stream. Is
> this ok or should i use a global variable for the stream?

Doesn't one of the with-* idioms suffice?

E.g.:

  (defun print-foo (stream)
    (print "Foo" stream))

  (defun using-foo ()
    (with-open-file (f "myfile.txt" ...)
      (print-foo f)))
   ;; now f is closed (even if an error happens) and no longer accessible

> I' dont understand exactly what happens when a function gets a stream
> as a parameter. Is the stream copied, so that there are 2 streams to the
> same file in the system? Is the stream in the calling-function still
> available when the other function returns.

Available? yes. Usable? Not if it's closed. But see above.

-ts
-- 
      ,,
     \../   /  <<< The LISP Effect
    |_\\ _==__
__ | |bb|   | _________________________________________________