Does re-assigning a non-function to be a function with set! create a new frame? - scope

The following code is confusing me:
(define (even-or-odd-letrec x)
((lambda (internal-even? internal-odd?)
(set! internal-even? (lambda (n)
(if (= n 0) 'even
(internal-odd? (- n 1)))))
(set! internal-odd? (lambda (n)
(if (= n 0) 'odd
(internal-even? (- n 1)))))
(internal-even? x))
#f #f))
As I read it, the environments are as follows:
Inside the environment of even-or-odd-letrec, internal-even? and internal-odd? are initially bound to #f. Their parent environment is the global environment.
set! then changes these two values to the obvious lambdas, but does not change the environments.
Because the environments haven't changed, any calls to internal-even? will look in the global environment for internal-odd? and find nothing.
So how does this code work?

Answering the title of your question: no, setting does not create any new frames.
Setting sets the value of a binding in the current environment frame. Whatever the old and new values might be. Function or no, makes no difference.
Again, set! does not change values. It changes bindings' values. A binding is a pairing of a name and its value. Set!ting changes that name's bound value.
Seen as a named pointer, after being re-set!, a name points to a new value -- that value which was supplied to set! as the second argument.
So contrary to what you say, set! does change the current environment frame -- it mutates its binding for the given name that is sets.
+---------------+ +---------------+
| n1 ---> v1 | | n1 ---> x |
| n2 ---> v2 | (set! n1 x) | n2 ---> v2 |
|---------------| -------------> |---------------|
| ..code... | | ..code... |
|_______________| |_______________|
"Any call to internal-even? will" ..... stop! this isn't the right way to look at it.
Any reference to internal-even? inside the lambda-created frame will be resolved by looking up the value under the name internal-even? in that same frame, and all will work out fine.
When you (set! internal-even? (lambda (...) ... internal-odd? ...)), it is true that internal-odd?'s value still isn't what it should be, but that's OK, because its value isn't looked up yet -- because internal-even? is not yet run either. When a lambda expression is evaluated (here, as part of the set! call), its value is the function which says, when time comes, when this function runs, then look up the value of any name in it as it is needed.

When applied to two argument values, (lambda (internal-even? internal-odd?) ...) creates a new environment with bindings for internal-even? and internal-odd?. Anything in that environment which refers to internal-even? or internal-odd? will refer to the current value of those bindings at the time when the code runs. set! mutates this environment by altering the values of the bindings, such that the current values of those bindings are now two procedures which themselves refer to the current values of those bindings.
By far the easiest way to understand this, I think, is to implement a little interpreter. It is extremely easy to do this: you use alists for environments, the evaluator needs pretty much to handle if and lambda and set! as special cases. Everyone should write one of these.

Setting a variable does not bind a new location. Note, however, that binding a new variable does not mean to create/enlarge a frame. It is possible (like in C) to keep variables into registers, not in frames, or not keeping them at all if you can prove things about a variable's behavior.

Related

Slot Options in Common Lisp structure without specifying any slot value

Is there any way to specify a slot-option for a struct slot without having to give it a default value? This can be of benefit e.g. when defining a base structure from which other structures would inherit, specifying the :types or :read-only without giving an initial value would look nicer i think.
The following structure definition leads to an error since the initial value is missing:
(defstruct s
(x :type number :read-only t)
)
No. One (of many) difference between defstruct and defclass is that all structure slots always have a value, and not specifying the default is equivalent to specifying nil default.
Note that
The restriction against issuing a warning for type mismatches between a slot-initform and the corresponding slot's :type option is necessary because a slot-initform must be specified in order to specify slot options; in some cases, no suitable default may exist.
In your case, I recommend:
(defstruct s
(x (error "x is required") :type number :read-only t))
in which case (make-s) will signal an error, while (make-s :x 10) will work.

difference between variable definition in a Haskell source file and in GHCi?

In a Haskell source file, I can write
a = 1
and I had the impression that I have to write the same in GHCi as
let a = 1
, for a = 1 in GHCi gives a parse error on =.
Now, if I write
a = 1
a = 2
in a source file, I will get an error about Multiple declaration of a, but it is OK to write in GHCi:
let a = 1
let a = 2
Can someone help clarify the difference between the two styles?
Successive let "statements" in the interactive interpreter are really the equivalent of nested let expressions. They behave as if there is an implied in following the assignment, and the rest of the interpreter session comprises the body of the let. That is
>>> let a = 1
>>> let a = 1
>>> print a
is the same as
let a = 1 in
let a = 1 in
print a
There is a key difference in Haskell in having two definitions of the same name and identical scopes, and having two definitions of the same name in nested scopes. GHCi vs modules in a file isn't really related to the underlying concept here, but those situations do lead you to encounter problems if you're not familiar with it.
A let-expression (and a let-statement in a do block) creates a set of bindings with the same scope, not just a single binding. For example, as an expression:
let a = True
a = False
in a
Or with braces and semicolons (more convenient to paste into GHCi without turning on multi-line mode):
let { a = True; a = False} in a
This will fail, whether in a module or in GHCi. There cannot be a single variable a that is both True and False, and there can't be two separate variables named a in the same scope (or it would be impossible to know which one was being referred to by the source text a).
The variables in a single binding set are all defined "at once"; the order they're written in is not relevant at all. You can see this because it's possible to define mututally-recursive bindings that all refer to each other, and couldn't possibly be defined one-at-a-time in any order:
λ let a = True : b
| b = False : a
| in take 10 a
[True,False,True,False,True,False,True,False,True,False]
it :: [Bool]
Here I've defined an infinite list of alternating True and False, and used it to come up with a finite result.
A Haskell module is a single scope, containing all the definitions in the file. Exactly as in a let-expression with multiple bindings, all the definitions "happen at once"1; they're only in a particular order because writing them down in a file inevitably introduces an order. So in a module this:
a = True
a = False
gives you an error, as you've seen.
In a do-block you have let-statements rather than let-expressions.2 These don't have an in part since they just scope over the entire rest of the do-block.3 GHCi commands are very like entering statements in an IO do-block, so you have the same option there, and that's what you're using in your example.
However your example has two let-bindings, not one. So there are two separate variables named a defined in two separate scopes.
Haskell doesn't care (almost ever) about the written order of different definitions, but it does care about the "nesting order" of nested scopes; the rule is that when you refer to a variable a, you get the inner-most definition of a whose scope contains the reference.4
As an aside, hiding an outer-scope name by reusing a name in an inner scope is known as shadowing (we say the inner definition shadows the outer one). It's a useful general programming term to know, since the concept comes up in many languages.
So it's not that the rules about when you can define a name twice are different in GHCi vs a module, its just that the different context makes different things easier.
If you want to put a bunch of definitions in a module, the easy thing to do is make them all top-level definitions, which all have the same scope (the whole module) and so you get an error if you use the same name twice. You have to work a bit more to nest the definitions.
In GHCi you're entering commands one-at-a-time, and it's more work to use multi-line commands or braces-and-semicolon style, so the easy thing when you want to enter several definitions is to use several let statements, and so you end up shadowing earlier definitions if you reuse names.5 You have to more deliberately try to actually enter multiple names in the same scope.
1 Or more accurately the bindings "just are" without any notion of "the time at which they happen" at all.
2 Or rather: you have let-statements as well as let-expressions, since statements are mostly made up of expressions and a let-expression is always valid as an expression.
3 You can see this as a general rule that later statements in a do-block are conceptually nested inside all earlier statements, since that's what they mean when you translate them to monadic operations; indeed let-statements are actually translated to let-expressions with the rest of the do-block inside the in part.
4 It's not ambiguous like two variables with the same name in the same scope would be, though it is impossible to refer to any further-out definitions.
5 And note that anything you've previously defined referring to the name before the shadowing will still behave exactly as it did before, referring to the previous name. This includes functions that return the value of the variable. It's easiest to understand shadowing as introducing a different variable that happens to have the same name as an earlier one, rather than trying to understand it as actually changing what the earlier variable name refers to.

Why are arguments to an enclosing function not captured by closures in Common Lisp?

test.lisp:
(defvar test
#'(lambda (var1)
#'(lambda (var2)
`((var1 . ,var1)
(var2 . ,var2)))))
(defvar var1 'wrong)
(defvar var2 'wrong)
And in the REPL:
$ clisp -q -i test.lisp
;; Loading file test.lisp ...
;; Loaded file test.lisp
[1]> (funcall (funcall test 'right) 'right)
((VAR1 . WRONG) (VAR2 . RIGHT))
I thought that common lisp was supposed to be lexically scoped these days, so why is the value of var1 not captured by the inner lambda in test? How can I make sure it is captured?
This is visible when using an interpreter.
Let's look at a compiler first:
? (load "/tmp/test.lisp")
#P"/private/tmp/test.lisp"
? (funcall (funcall test 'right) 'right)
((VAR1 . RIGHT) (VAR2 . RIGHT))
First the functions are getting compiled. The compiler assumes lexical binding. Then DEFVAR declares the variables VAR1 and VAR2 to be special (-> not lexical). In the executed code then, the code is still using lexical binding.
You were using an Interpreter:
First the functions are loaded. Nothing gets compiled. Then DEFVAR declares VAR1 and VAR2 as special.
In the executed code then, the Interpreter is using dynamic binding - like you declared it. The Interpreter looks at the variables at runtime and sees that they are declared to be special.
Difference:
The compiler has generated the machine code before the special declaration. Thus at runtime it uses lexical binding.
The interpreter looks at runtime at the existing declarations.
Style
If you want to avoid dynamic binding, don't declare variables to be special.
defvar (and defparameter) declare the variable to be special (dynamic). Give your special variables *earmuffs* to prevent surprises about whether a binding is lexical or dynamic.

Scope of functions and variables within a function and/or let statement for lisp

I'm having some trouble understanding the scope of variables and functions when defined inside a function call. I tried searching for this scope, but could not find a suitable answer (or maybe was searching for the wrong thing), so I decided to write a few functions to test things myself:
(defun test-scope1 ()
(setf myvar 1)
(defun set-var1 ()
(setf myvar 2))
(set-var1))
With this function I just wanted to see if anything gets set global. I would expect myvar and set-var to be defined globally because I have no scope here. As expected, before calling (test-scope1) the commands myvar and (set-var) give me errors. After calling (test-scope1), I can run myvar and (set-var) in the interpreter to yield 2.
Thinking to myself it would be nice to encapsulate my variables, I decided to add a let inside my function, therefore getting my next test:
(defun test-scope2 ()
(let ((myvar 10))
(defun set-var2 ()
(setf myvar 20))
(set-var2)))
I would expect myvar to be stuck in the scope of the let block, but wouldn't be able to guess for set-var2. It could be stuck in the let block or it could be defined globally. After running (test-scope2) I try to access myvar and get 2. That means this new function has its own myvar since it's still 2 from the previous function. I try running (set-var2)and get 20.
I'm not completely surprised that the function is defined globally after being run in the let block, but now I'm very confused what myvar variable its accessing. Since it didn't change my global copy of myvar, it would seem there's some variable floating around it still refers to.
Now I want to see if I can manipulate that floating variable, so I create this third function.
(defun test-scope3 ()
(let ((myvar (if (ignore-errors myvar)
myvar
100)))
(defun set-var3 ()
(setf myvar (+ myvar 100)))
(set-var3)))
Instead of just setting the variable to a fixed value, I want to increment it based on the previous value. I check two things here. The first is when test-scope3 is called. I wanted to see if I could pull up a "previous value" of myvar, since if it's floating around somewhere maybe I can access it again. It probably wouldn't be good practice, but that's not the point here. Ignore-errors is there in case there wasn't really a previous value floating around, in which case I choose a default of 100.
The second thing I test is to have set-var3 add 100 to the previous the value of myvar. I want to see if this will adjust that floating variable, or if somehow is something static. I have no idea what my function "should" return.
After running (test-scope3) I'm completely surprised to see 102. So apparently my test-scope3 found the value of myvar from running test-scope1. But, after checking the value of myvar in the interpreter, it is still 2. Next I run (set-var3) and get a return value of 202. Okay, so it added 100 again to my previous value. Calling it again returns 302 and so on. But, calling (test-scope3) again resets this value back down to 102.
I wrote one more function as a double nested let command. I just ran this in two ways: with no myvar definition for the let arguments. This function returns 10002. Then, I tried setting the local myvar to 50 and had 1050 return.
(defun test-scope4 ()
(let () ; or ((myvar 50))
(let ((myvar (if (ignore-errors myvar)
myvar
2000)))
(defun set-var4 ()
(setf myvar (+ myvar 1000)))
(set-var4))))
So, with all this together, here are some of my specific questions:
When I do a defun inside another defun, even in a let block, why does that function become accessible globally?
When I call set-var#, what variables (or within what scope) is this accessing? Or maybe more appropriately, when I define a function inside another statement, what am I actually binding?
When I use the variable myvarin a function, where does this pull from? From my 4th example conjecture is that it looks for the symbol myvar in the current scope, then checks up one level higher until it finds a value for it.
Sorry if everything was very wordy and my questions ill-formed. I tried to investigate things to the best of my ability. Really this all leads to my real question, which after writing everything up I realize might be beyond the scope (no pun intended) of this question as I've set it up so far.
The issue of hiding my inner functions as given above could be handled with a lambda expression; however, what I'd really love to do is to have a recursive function inside of a bigger block that uses the block to store values without feeding them directly into the function. To my knowledge, this is not possible with a lambda expression. For example, consider the following function which does this.
(defun outer-function (start)
(let ((x start))
(defun increment-to-ten ()
(setf x (+ x 1))
(if (< x 10)
(increment-to-ten)))
(increment-to-ten)
(print x)))
Which could be instead implemented recursively with arguments as
(defun increment-to-ten-recursive (x)
(if (< x 10)
(increment-to-ten-recursive (+ x 1))
10))
If there's a solution for this, that would be great, or if my thinking is completely wrong and there's a better way to do this that would be great to. It just seems convenient to have a block store data for you and then just call a recursive function with no arguments to work on that data.
Why it is difficult to discuss the effects you see:
You are doing things which are undefined in Common Lisp: setting undeclared variables in test-scope1: myvar. It's from then on unclear how the following code behaves.
Undeclared Variables
It is undefined what effect it has when an undeclared variable foo is set. Implementations allow it. Some will warn. SBCL:
* (setf foo 10)
; in: SETF FOO
; (SETF FOO 10)
; ==>
; (SETQ FOO 10)
;
; caught WARNING:
; undefined variable: FOO
;
; compilation unit finished
; Undefined variable:
; FOO
; caught 1 WARNING condition
Global variables are defined with DEFPARAMETER and DEFVAR. Local variables are defined by LET, LET* and by functions parameters. Since DEFPARAMETER and DEFVAR define global special (using dynamic binding) variables, it is common to write them as *some-variable* - note the * around it, which are part of the symbol name and not special syntax. It's a convention for special variables.
Nested DEFUNs
Nested DEFUNs are not used in Common Lisp. DEFUN is a top-level form, which sets a global function. To define local functions use FLET and LABELS. You can nest DEFUN forms, but it is bad style and you won't find it used in actual Lisp code. Don't nest DEFUN forms. Note: this is different from Scheme, where one can nest DEFINE forms. Since nested DEFUNs are not used, it makes little sense to discuss the effects. Convert the examples to use local functions defined by FLET or LABELS.
When I do a defun inside another defun, even in a let block, why does that function become accessible globally?
Because DEFUN defines global functions. That's its purpose.
You need to rewrite your examples to make it possible to discuss the effects:
declare all variables
don't use nested DEFUNs
We could try to understand the code you have in your current examples, but much depends on the implementation and the sequence of actions. We are either not in the realm of portable Common Lisp or doing stuff (nested DEFUNs), which has no practical use in Common Lisp.
As Rainer explained, the answer to your first question is that defun defines global functions. Use labels to define local functions.
Rainer is also right about much being dependent on the configuration of your lisp. Many Lisps know about two types of scope, lexical and dynamic. Lexical scope is the one you can see when you look at a page of code, and what you're used to from most other programming languages. Dynamic scope is what you get when you a lisp looks for the value of a variable in the environment where the function was called instead of the one where it was defined.
Finally, your code makes usse of closures. When you put a lambda (defun) inside a let, you create a closure, e.g. your variables "hang or float around" for the function to use in the future even when the function that contains them returns to it's caller.
So here's what might be going on (as Rainer said, it's hard to know since you're doing things that usually aren't done, such as nesting defuns):
So... probably, test-scope1 uses a global myvar and it's set-var references the global myvar since we are dealing with lexical scope. test-scope2 builds a closure, which creates a myvar with lexical scope only accessible to set-var2. Since this myvar has lexical scope, the call to set-var in test-scope2 will not use this myvar but still the global one.
I'm not sure why calling test-scope3 gets you 102, since test-scope3 just calls set-var, which should set the global myvar to 2, not 102. The only code that could explain 102 is in set-var3, and this isn't being called when you call test-scope3. Here's what might be going on if you got 2 instead of 102 when calling test-scope3:
(defun test-scope3 ()
(let ((myvar (if (ignore-errors myvar)
myvar
100)))
(defun set-var3 ()
(setf myvar (+ myvar 100)))
(set-var)))
With the let, you create a local binding for myvar with lexical scope, but you refer to the global myvar in it's binding form - the (if (ignore-errors myvar) myvar). Later on you call set-var, which should again reference the global myvar since test'scope3's let uses lexical scope for the binding of myvar. Then, wen you call set-var3 for the first time, it takes the myvar bound by the above let, which currently has a value of 2, and adds 100 to it. When you call it the second time, you again add 100 to the lexically bound myvar which still hangs around in the closure you built in test-scope3, and so on. But when you call test-scope3 again, you create a new closure (but replace the old one because you use defun to give the same name to it...) which again sets the initial value of the closed-over myvar to the value of the global myvar, which is 2.
I suggest you read Paul Graham's excellent ANSI Common Lisp and On Lisp, which explain special variables (dynamic scope), lexical scope and closures in depth.
Here's how you might have several closures share variables:
(let ((myvar 0))
(defun reset ()
(setf myvar 0)
(defun inc ()
(setf myvar (+ myvar 1))))
This builds two closures and makes them share myvar, and since myvar has lexical scope you can't access this copy of myvar from anywhere else. So you've basically given exclusive control of myvar to reset and inc.
This could be one way to build your recursive function that doesn't need a value passed into it with each iteration.

ghci: keep defined values in scope after module reload

I am wondering if it is possible to keep assigned values in ghci when a module is reloaded?
For example i assign a value in ghci:
ghci> let x = 1
or
ghci> x <- getLine
After entering :r to reload an existing module x is not in scope anymore. Is it generally possible to keep the assignment available, like for example in the Python interpreter? (this is really convenient...)
Even tho that actually each line in ghci represents a function that is (monadically) bound to the next one I am still wondering if maintaining that state is possible.
I'm not aware of any way of doing this.
The trouble is that you could have some variable bound to a value of a certain type, edit the source to remove that type, and hit reload. Now you have a variable of a type that no longer exists.
Still, you would think it shouldn't be too hard to detect that, and discard just the variables that don't make sense any more. (The really fun part is presumably when a type still exists but has a different number of fields now, or something like that...)

Resources