Page 2 of 2

Re: Why have the let function when you already have setf?

Posted: Sun Jan 31, 2010 11:32 am
by yougene
Is it possible to use setf without side effects if it's used to only modify variables passed in as parameters or generated within the function?

Is that how you write good lisp code?

Re: Why have the let function when you already have setf?

Posted: Sun Jan 31, 2010 1:49 pm
by nuntius
yougene wrote:Is it possible to use setf without side effects if it's used to only modify variables passed in as parameters or generated within the function?
Have you programmed in other languages? LET is simply one way to define a local (lexically scoped) variable in lisp. In languages like perl, you might say "local x" or "my x". In C/C++/Java, you say "{int x; ...}". In lisp, you use "(let (x) ...)". SETF is the mutation/assignment operator; "(setf x 5)" is like "x=5" in other languages; it does not create a new variable.

Maybe the following snippet will help you.

Code: Select all

(defun f (x)
  (setf x 5) ; nobody outside F sees this
  x) ; until this return
(defun g (x)
  (let ((y (+ x 5)))
     (setf x 5)
     y)) ; here, the new value of X is never seen
That LET also shadows dynamic variables is a historical accident. Old lisps (before Scheme) didn't have lexical variables! Instead, there were several interesting schemes for how variables passed values.

Re: Why have the let function when you already have setf?

Posted: Sun Jan 31, 2010 2:22 pm
by yougene
I understand what let does and what scope is, but thanks for the feedback.

My question was about how to program without side effects. Whether properly programming in lisp is simply a matter of maintaining referential transparency.

Re: Why have the let function when you already have setf?

Posted: Sun Jan 31, 2010 6:27 pm
by gugamilare
yougene wrote:Is it possible to use setf without side effects if it's used to only modify variables passed in as parameters or generated within the function?

Is that how you write good lisp code?
You are right, setf will only have side effects if you use it to modify a global variable or a local variable outside of the current function (like, when creating a function, you can modify the values being defined in its surroundings). Sometimes, whether you use setf or let is just a matter of personal preference. For instance when you want your function to accept numbers and strings representing numbers, one way you can do to make sure that the variable holds a number is setf-ing it or rebinding it with let.

In Lisp, we consider setf to be a bad choice when it is not necessary. Lisp is about brevity, not walk on circles around what you are trying to do. In C, programmers often assign the result of a function just to pass it to another function, and they do that when they learn Lisp, which is considered bad Lisp. It is considered to be more Lispy style to nest the function calls, unless the nesting get too haired, in which case you generally use let, but a setf can also be used if it makes sense.

Also, in general, Lispers avoid side effects, but sometimes they are very useful. There are other languages where side effects are condemned with punishment, but that is not the case with Common Lisp ;)

Re: Why have the let function when you already have setf?

Posted: Sun Jan 31, 2010 7:43 pm
by yougene
Thanks, I think I'm starting to get this functional programming thingamajig.

Re: Why have the let function when you already have setf?

Posted: Sun Feb 07, 2010 3:39 am
by hewih
i'm just a newbie too and i don't know if this is considered good style but my functions usually start with a lot of let* bindings with function calls to get their values. this is especially true if i need a value more than once. in the actual function body there are usually only very few calculations going on.

Re: Why have the let function when you already have setf?

Posted: Sun Feb 07, 2010 7:47 am
by gugamilare
hewih wrote:i'm just a newbie too and i don't know if this is considered good style but my functions usually start with a lot of let* bindings with function calls to get their values. this is especially true if i need a value more than once. in the actual function body there are usually only very few calculations going on.
Well, many good libraries do stuff this way, so I think you are safe :)