Understanding bound and free variables in LISP - scope

I'm reading SICP, and the topic of bound and free variables has come up. However, I am confused about it. Does the term "bound variables" only apply to variables that are formal parameters? In addition, the text says that a procedure definition "binds" its formal parameters. This confuses me with the fact that some people say that we "bind" a value to a variable. Obviously, the term seems to mean different things when we're talking about different types of variables. Could someone clear up what a bound variable is and what binding means? Finally, in contrast to a bound variable, what is free variable? How does all of this relate to scope?

There are only two types of variables. Global and lexical. You can actually think of global as a changeable root of the lexical scope and in that case there is only one type of variables.
A bound variable is the formal parameters of the current procedure and everything else, which either is global or bound from previous nested calls, are free variables.
Example:
(lambda (x)
(let ((y (+ x x))) ; + is free x is bound
(+ x y))) ; + and x is free, y is bound
Remember let is ust syntactic sugar so it's really the same as this:
(lambda (x)
((lambda (y)
(+ x y)) ; + and x is free, y is bound
(+ x x))) ; + is free x is bound
In the inner lambda with y as bound variable + and x are free. In the outer lambda x is bound and + is free. + might be a global.

Related

Is there a programming language where a variable is evaluated when it is accessed?

The below is the pseudo-code of what I want to explain, in JavaScript-like syntax.
const func1 = (x => x * x); // JavaScript Arrow Function syntax.
const func2 = (x => {log("I'm func2!"); return x + 1;});
var a;
var b <= func1(a); // `<=` is a *Binding* operator.
var c <= func2(b);
a = 1;
log(c); // Logs "I'm func2!", and then logs 2, which is ((a * a) + 1).
log(b); // Logs 1, which is (a * a).
a = 2;
log(c); // Logs "I'm func2!", and then logs 5, which is ((a * a) + 1).
log(b); // Logs 4, which is (a * a).
// When b or c is accessed, the function for it is called and make the value.
Is there a programming language that has the concept explained above?
The main evaluation strategies in programming languages are lazy (for example, call-by-name) and strict (for example, call-by-value). Lazy languages evaluate an expression only when it is needed; strict languages evaluate an expression eagerly. To be concrete, the difference usually arises in function calls: lazy languages pass the argument to the function unevaluated, and strict languages evaluate the argument and then call the function. There are lots of tradeoffs that you can read about, e.g. https://en.wikipedia.org/wiki/Evaluation_strategy.
But your code example raises a question: how does the binding to b work? Regardless of whether the language is strict or lazy, you have a problem because you're going to want to use the value of a, which you haven't bound yet. This brings up a second parameter in programming language design: static versus dynamic scope. In a statically-scoped language, a variable's scope is determined statically. That is, the "a" passed to func1 is exactly the a that is in scope at the time func1 is called. In a dynamically-scoped language, a variable's scope is determined at runtime, so it would be possible to imagine that func1(a) is evaluated lazily, in which case the a in scope at that time is the one after the assignment to a.
The question of static vs. dynamic scope, however, is mostly a resolved one: static scope is almost always the right answer. Some languages tried using dynamic scope (e.g. older LISPs) but switched to static scope because people found it too confusing.
So, in summary, I could imagine a language that works the way you describe, but it's likely that most people would find it very confusing to use.
I don't know such language, but I know a different strategy for that: you can wrap the call again in a Lambda object. It would have the same effect as you have described. E.g. in Lisp you can do:
(defun some-func (x) (* x x))
(defvar *a* (lambda () (some-func 4)))
*a* ;; => returns the function
(*a*) ;; => returns 16
That is possible in almost all today's languages. Even in C, but there it's getting pretty hard.
What a funny coincidence! I happen to be aware of one language which has this property, it exists since Monday, here: https://github.com/drcz/ZJEB
It was supposed to be partly a joke and partly an experiment in expressiveness; here is a REPL session with your example:
(-- ALGORITHMIC LANGUAGE ZJEB v0.1 --)
copyleft 2016/08/08 by Scislav Dercz
type (halt) to quit
READY.
>(def func1 (bind (x) (* x x)))
(new shorthand func1 memoized)
>(def func2 (bind (x) (+ x 1)))
(new shorthand func2 memoized)
>(def a 1)
(new shorthand a memoized)
>(def b (func1 a))
(new shorthand b memoized)
>(def c (func2 b))
(new shorthand c memoized)
>c
2
>b
1
>(def a 2)
(new shorthand a memoized)
>c
5
>b
4
and here's a simpler one
>(def x 5)
(new shorthand x memoized)
>(def y (* x x))
(new shorthand y memoized)
>y
25
>(def x 3)
(new shorthand x memoized)
>y
9
The thing is, unlike in scheme (or any other lisp I know), the "def" form does not evaluate the second operand -- it just creates a syntactical "shorthand" to an expression given. So any time the evaluator finds a symbol, it tries to look it up in the environment (i.e. variable-value bindings created with "bind" form -- which is a multi-case pattern-matching variant of "lambda" form from lisp), and if it fails, it also check the list of definitions -- when it succeeds, it immediately evaluates the coresponding expression.
It was not meant to do things which you describe (and in general is not usefull at all, only forcing the evaluator to do a little more work in the current implementation), as the language is purely functional (and actually the only reason re-defining a shorthand is possible is for the convenience of working with repl). This "feature" is in there because I wanted to think about recursive definitions like
(def fact (bind (0) 1
(n) (* n (fact (- n 1)))))
to actually mean an infinite expression
(bind (0) 1
(n) (* n ((bind (0) 1
(n) (* n ...)) (- n 1)))
in the spirit of Dana Scott's "Lattice of flow diagrams".
Note that infinite data structures like
(def evil `(ha ,evil))
do break the interpreter when you try to evaluate them, though I should probably make them legit [by means of partly-lazy evaluation or something] as well...
Back to your question, you might take a look at various Functional Reactive Programming languages/frameworks, as they provide the behaviors you ask for, at least for certain datatypes.
Svik's comment is also very nice, spreadsheet formulas work this way (and some people claim them to be an FRP language).
(The lazy evaluation thing is rather not the case, because variable scope in any "lazy" language I happen to know is lexical -- laziness+dynamic scoping would probaly be too confusing, as mcoblenz stated above).
Lazy evaluation is a method to evaluate a Haskell program. It means that expressions are not evaluated when they are bound to variables, but their evaluation is deferred until their results are needed by other computations.
https://wiki.haskell.org/Lazy_evaluation
What you need is call-by-name and mutable variables. One of the earliest languages with (optional) call-by-name was Algol 60.
A more modern language with (optional) call-by-name is Scala. Here is a port your sample code to Scala:
def log(a: Any) = println(a)
def func1(x: => Int) = x * x
def func2(x: => Int) = {
log("I'm func2!")
x + 1
}
var a = 0
def rest1(b: => Int) = {
def rest2(c: => Int) = {
a = 1
log(c); // Logs "I'm func2!", and then logs 2, which is ((a * a) + 1).
log(b); // Logs 1, which is (a * a).
a = 2;
log(c); // Logs "I'm func2!", and then logs 5, which is ((a * a) + 1).
log(b); // Logs 4, which is (a * a).
}
rest2(func2(b))
}
rest1(func1(a))
Parameters that are declared such as b: => Int are call-by-name (whereas b: Int would be call-by-value).

Need help understanding (\x -> ) in Haskell

On ZVON, one of the definitions provided for the takeWhile function is
Input: takeWhile (\x -> 6*x < 100) [1..20]
Output: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
Can someone explain what the portion (\x -> 6*x < 100) means?
It's an anonymous function definition, otherwise known as a lambda-expression. (\x -> 6*x < 100) is a function which takes a number, and returns the boolean result of the inequality.
Since functional languages like Haskell frequently take functions as arguments, it is convenient to be able to define simple functions in-line, without needing to assign them a name.
Originally, the story goes, Alonzo Church wanted to mark variables in functional expressions with a circumflex, like e.g. (ŷ.x(yz)) but the Princeton printing press just couldn't do that at the time. He then wanted at least to print carets before the vars, like this: (^y.x(yz)), but they couldn't do that either.
The next best option was to use the Greek letter lambda instead, and so they ended up writing (λy.x(yz)) etc., hence the "lambda" in lambda-expression. It was all just a typographical accident.
Today on ASCII terminals we can't even use the letter λ, and so in Haskell we use a backslash instead (and an arrow in place of a dot in original lambda-expressions notation):
(\y -> x (y z))
stands for a function g such that
g y = x (y z)
Source: read it somewhere, don't remember where.
(\x -> 6*x < 100) is a lambda, an anonymous function that takes one argument (here called x) and computes & returns 6*x < 100, i.e., tests whether that number multiplied by 6 is less than 100.
It is a lambda function, that is, a function that you define in the spot mostly for convenience. You read it as "take x as your input, multiply it by 6 and see if it is less than 100". There are some other amenities related, though. For example, in Haskell Lambda functions and ordinary functions have a lexical environment associated and are properly speaking closures, so that they can perform computations using the environment as input.

Representing undefined result in MIT Scheme

Imagine I have a function with a domain of all integers bigger than 0. I want the result of other inputs to be undefined. For the sake of simplicity, let's say this is the increment function. In Haskell, I could achieve this with something like
f :: Integer -> Integer
f x
| x > 0 = x + 1
| otherwise = undefined
Of course, the example is quite gimped but it should be clear what I want to achieve. I'm not sure how to achieve the similar in Scheme.
(define (f x)
(if (> x 0)
(+ x 1)
(?????)))
My idea is to just stick an error in there but is there any way to replicate the Haskell behaviour more closely?
Your question is related to this one which has answers pointing out that in R5RS (which I guess MIT scheme partially supports?), the if with one branch returns an "unspecified value". So the equivalent to the haskell code should be:
(define (f x)
(if (> x 0)
(+ x 1)))
You probably already know this: in haskell undefined is defined in terms of error, and is primarily used in development as a placeholder to be removed later. The proper way to define your haskell function would be to give it a type like: Integer -> Maybe Integer.
A common undefined value is void defined as (define void (if #f #f)).
Notice that not all Scheme implementations allow an if without the alternative part (as suggested in the other answers) - for instance, Racket will flag this situation as an error.
In Racket you can explicitly write (void) to specify that a procedure returns no useful result (check if this is available in MIT Scheme). From the documentation:
The constant #<void> is returned by most forms and procedures that have a side-effect and no useful result. The constant #<undefined> is used as the initial value for letrec bindings. The #<void> value is always eq? to itself, and the #<undefined> value is also eq? to itself.
(void v ...) → void?
Returns the constant #<void>. Each v argument is ignored.
That is, the example in the question would look like this:
(define (f x)
(if (> x 0)
(+ x 1)
(void)))
Speaking specifically to MIT Scheme, I believe #!unspecific is the constant that is returned from an if without an alternative.
(eq? (if (= 1 2) 3) #!unspecific) => #t

What is a "free variable"?

(I'm sure this must have been answered on this site already, but search gets inundated with the concept of calling free() on a variable in C.)
I came across the term "eta reduction," which was defined something like f x = M x ==> M if x is "not free in M". I mean, I think I understand the gist of what it's trying to say, it seems like what you do when you convert a function to point-free style, but I don't know what the qualifier about x not being free means.
Here's an example:
\f -> f x
In this lambda, x is a free variable. Basically a free variable is a variable used in a lambda that is not one of the lambda's arguments (or a let variable). It comes from outside the context of the lambda.
Eta reduction means we can change:
(\x -> g x) to (g)
But only if x is not free (i.e. it is not used or is an argument) in g. Otherwise we'd be creating an expression which refers to a unknown variable:
(\x -> (x+) x) to (x+) ???
Well, here's the relevant Wikipedia article, for what that's worth.
The short version is that such definitions elide the body of a lambda expression using a placeholder like "M", and so have to specify additionally that the variable being bound by that lambda isn't used in whatever the placeholder represents.
So, a "free variable" here roughly means a variable defined in some ambiguous or unknown outer scope--e.g., in an expression like \y -> x + y, x is a free variable but y is not.
Eta reduction is about removing a superfluous layer of binding and immediately applying a variable, which is (as you would probably imagine) only valid if the variable in question is only used in that one place.

What type of scope does Haskell use?

I'm trying to figure out if Haskell uses dynamic or static scoping.
I realize that, for example, if you define:
let x = 10
then define the function
let square x = x*x
You have 2 different "x's", and does that mean it is dynamically scoped? If not, what scoping does it use, and why?
Also, can Haskell variables have aliases (a different name for the same memory location/value)?
Thanks.
Haskell use (broadly speaking) exactly the same lexical scoping as most other languages.
eg.
x = 10
Results in a value referenced through x in the global scope, whereas
square x = x * x
will result in x being lexically scoped to the function square. It may help if you think of the above form being a syntactic nicety for:
square = \ x -> x * x
As to your other question i'm not sure what you mean by aliasing
Answering only the second part of the question:
You can have several aliases for the same "memory location", but since they are all immutable, it does not matter most of the time.
Dumb example:
foo x y = x * y
bar z = foo z z
When within foo called from bar, both x and y are clearly the same value. But since you cannot modify either x or y, you will not even notice.
There are some things wrong in your statements...
There are no mutable variables in Haskell just definitions (or immutable variables)
A variable memory location is a concept that do not exist in Haskell
In your example, x is not 10 in the function is just a argument to square, that can take any value (you can specify the type later) in this case 10 but just in this case.
Here is an example of aliases provided by Curt Sampson:
import Data.IORef
main :: IO ()
main = do x <- newIORef 0 -- write 0 into x
readIORef x >>= print -- x contains 0
let y = x
readIORef y >>= print -- y contains 0
writeIORef x 42 -- write 42 into x
readIORef y >>= print -- y contains 42
As the first part of the question is already answered by others, here is the second part:
I assume by aliasing you mean one name for another. As haskell is a functional language, and functions behave as normal identifiers in any case, you can do that like this:
y = x
which would define an alias y for the function x. Note that everything is a function. Even if it looks like a "variable", it's just a nullary function taking no arguments. Aliases for types look like this:
type Function = Double -> Double
which would define an alias Function for the type Double -> Double
Haskell uses static nested scopes. What is a bit confusing compared with other languages that have static nested scopes is that the scope of a name is a block which includes tests preceding its definition. For example
evens = 0 : map (+1) odds
odds = map : (+1) evens
here the name 'odds' is in scope in the definition of 'evens', despite the surprising fact that 'odds' has not yet been defined. (The example defines two infinite lists of even and odd numbers.)
A dead language with a similar scoping rule was Modula-3. But Haskell is a bit trickier in that you can attempt to 'redefine' a variable within the same scope but instead you just introduce another recursion equation. This is a pitfall for people who learned ML or Scheme first:
let x = 2 * n
x = x + 1 -- watch out!
This is perfectly good ML or Scheme let*, but Haskel has scheme letrec semantics, without the restriction to lambda values. No wonder this is tricky stuff!
In your example, the global definition of x is shadowed by the local definition of x. In Haskell, a variable's scope is determined by a static reading of the source code - this is called lexical scope, but can get something similar to dynamic scoping with implicit parameters (but that can lead to some unexpected behavior (I've read; never tried 'em myself)).
To sum up the other answers concisely:
lexical scope
aliasing is as easy as x = 1; y = x but doesn't usually matter because things are immutable.
The let syntax you use in your example looks like it's at the interactive ghci> prompt. Everything in interactive mode occurs within the IO monad so things may appear more mutable there than normal.
Well, as I think people have said already, Haskell doesn't have any variables as found in most other languages, it only has expressions. In your example let x = 10 x is an expression that always evaluates to 10. You can't actually change the value of x later on, though you can use the scoping rules to hide it by defining x to be another expression.
Yes, Haskell has aliases. Try out this little program:
import Data.IORef
main :: IO ()
main = do x <- newIORef 0 -- write 0 into x
readIORef x >>= print -- x contains 0
let y = x
readIORef y >>= print -- y contains 0
writeIORef x 42 -- write 42 into x
readIORef y >>= print -- y contains 42

Resources