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

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).

Related

Common Lisp the Language: "dynamic shadowing cannot occur"

Near the end of chapter 3 of Common Lisp the Language, Steele writes "Constructs that use lexical scope effectively generate a new name for each established entity on each execution. Therefore dynamic shadowing cannot occur (though lexical shadowing may)". I am confused as to what exactly he means by "dynamic shadowing cannot occur". What would an example of "dynamic shadowing" look like?
Here is an example of what he might have meant:
(defun f (g)
(let ((a 2))
(funcall g a)))
(let ((a 1))
(f (lambda (x) (- x a))))
This returns 1 in Common Lisp because the lexical binding of a in f does not affect the binding of a in the top-level let, so, when f calls g, it subtracts 1 from 2 because the lambda gets a from the top-level binding.
Contrast this with the dynamic binding in Emacs Lisp, where the return value is 0.
You might also find it instructive to work out the contorted-example and try it in CL and ELisp.

Why should I use case expressions if I can use "equations"?

I'm learning Haskell, from the book "Real World Haskell". In pages 66 and 67, they show the case expressions with this example:
fromMaybe defval wrapped =
case wrapped of
Nothing -> defval
Just value -> value
I remember a similar thing in F#, but (as shown earlier in the book) Haskell can define functions as series of equations; while AFAIK, F Sharp cannot. So I tried to define this in such a way:
fromMaybe2 defval Nothing = defval
fromMaybe2 defval (Just value) = value
I loaded it in GHCi and after a couple of results, I convinced myself it was the same However; this makes me wonder, why should there be case expressions when equations:
are more comprehensible (it's Mathematics; why use case something of, who says that?);
are less verbose (2 vs 4 lines);
require much less structuring and syntatic sugar (-> could be an operator, look what they've done!);
only use variables when needed (in basic cases, such as this wrapped just takes up space).
What's good about case expressions? Do they exist only because similar FP-based languages (such as F#) have them? Am I missing something?
Edit:
I see from #freyrs's answer that the compiler makes these exactly the same. So, equations can always be turned into case expressions (as expected). My next question is the converse; can one go the opposite route of the compiler and use equations with let/where expressions to express any case expression?
This comes from a culture of having small "kernel" expression-oriented languages. Haskell grows from Lisp's roots (i.e. lambda calculus and combinatory logic); it's basically Lisp plus syntax plus explicit data type definitions plus pattern matching minus mutation plus lazy evaluation (lazy evaluation was itself first described in Lisp AFAIK; i.e. in the 70-s).
Lisp-like languages are expression-oriented, i.e. everything is an expression, and a language's semantics is given as a set of reduction rules, turning more complex expressions into simpler ones, and ultimately into "values".
Equations are not expressions. Several equations could be somehow mashed into one expression; you'd have to introduce some syntax for that; case is that syntax.
Rich syntax of Haskell gets translated into smaller "core" language, that has case as one of its basic building blocks. case has to be a basic construct, because pattern-matching in Haskell is made to be such a basic, core feature of the language.
To your new question, yes you can, by introducing auxiliary functions as Luis Casillas shows in his answer, or with the use of pattern guards, so his example becomes:
foo x y | (Meh o p) <- z = baz y p o
| (Gah t q) <- z = quux x t q
where
z = bar x
The two functions compile into exactly the same internal code in Haskell ( called Core ) which you can dump out by passing the flags -ddump-simpl -dsuppress-all to ghc.
It may look a bit intimidating with the variable names, but it's effectively just a explicitly typed version of the code you wrote above. The only difference is the variables names.
fromMaybe2
fromMaybe2 =
\ # t_aBC defval_aB6 ds_dCK ->
case ds_dCK of _ {
Nothing -> (defval_aB6) defval_aB6;
Just value_aB8 -> (value_aB8) value_aB8
}
fromMaybe
fromMaybe =
\ # t_aBJ defval_aB3 wrapped_aB4 ->
case wrapped_aB4 of _ {
Nothing -> (defval_aB3) defval_aB3;
Just value_aB5 -> (value_aB5) value_aB5
}
The paper "A History of Haskell: Being Lazy with Class" (PDF) provides some useful perspective on this question. Section 4.4 ("Declaration style vs. expression style," p.13) is about this topic. The money quote:
[W]e engaged in furious debate about which style was “better.” An underlying assumption was that if possible there should be “just one way to do something,” so that, for example, having both let and where would be redundant and confusing. [...] In the end, we abandoned the underlying assumption, and provided full syntactic support for both styles.
Basically they couldn't agree on one so they threw both in. (Note that quote is explicitly about let and where, but they treat both that choice and the case vs. equations choice as two manifestations of the same basic choice—what they call "declaration style" vs. "expression style.")
In modern practice, the declaration style (your "series of equations") has become the more common one. case is often seen in this situation, where you need to match on a value that is computed from one of the arguments:
foo x y = case bar x of
Meh o p -> baz y p o
Gah t q -> quux x t q
You can always rewrite this to use an auxiliary function:
foo x y = go (bar x)
where go (Meh o p) = baz y p o
go (Gah t q) = quux x t q
This has the very minor disadvantage that you need to name your auxiliary function—but go is normally a perfectly fine name in this situation.
Case expression can be used anywhere an expression is expected, while equations can't. Example:
1 + (case even 9 of True -> 2; _ -> 3)
You can even nest case expression, and I've seen code that does that. However I tend to stay away from case expressions, and try to solve the problem with equations, even if I have to introduce a local function using where/let.
Every definition using equations is equivalent to one using case. For instance
negate True = False
negate False = True
stands for
negate x = case x of
True -> False
False -> True
That is to say, these are two ways of expressing the same thing, and the former is translated to the latter by GHC.
From the Haskell code that I've read, it seems canonical to use the first style wherever possible.
See section 4.4.3.1 of the Haskell '98 report.
The answer to your added question is yes, but it's pretty ugly.
case exp of
pat1 -> e1
pat2 -> e2
etc.
can, I believe, be emulated by
let
f pat1 = e1
f pat2 = e2
etc.
in f exp
as long as f is not free in exp, e1, e2, etc. But you shouldn't do that because it's horrible.

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

Practical use of curried functions?

There are tons of tutorials on how to curry functions, and as many questions here at stackoverflow. However, after reading The Little Schemer, several books, tutorials, blog posts, and stackoverflow threads I still don't know the answer to the simple question: "What's the point of currying?" I do understand how to curry a function, just not the "why?" behind it.
Could someone please explain to me the practical uses of curried functions (outside of languages that only allow one argument per function, where the necessity of using currying is of course quite evident.)
edit: Taking into account some examples from TLS, what's the benefit of
(define (action kind)
(lambda (a b)
(kind a b)))
as opposed to
(define (action kind a b)
(kind a b))
I can only see more code and no added flexibility...
One effective use of curried functions is decreasing of amount of code.
Consider three functions, two of which are almost identical:
(define (add a b)
(action + a b))
(define (mul a b)
(action * a b))
(define (action kind a b)
(kind a b))
If your code invokes add, it in turn calls action with kind +. The same with mul.
You defined these functions like you would do in many imperative popular languages available (some of them have been including lambdas, currying and other features usually found in functional world, because all of it is terribly handy).
All add and sum do, is wrapping the call to action with the appropriate kind. Now, consider curried definitions of these functions:
(define add-curried
((curry action) +))
(define mul-curried
((curry action) *))
They've become considerable shorter. We just curried the function action by passing it only one argument, the kind, and got the curried function which accepts the rest two arguments.
This approach allows you to write less code, with high level of maintainability.
Just imagine that function action would immediately be rewritten to accept 3 more arguments. Without currying you would have to rewrite your implementations of add and mul:
(define (action kind a b c d e)
(kind a b c d e))
(define (add a b c d e)
(action + a b c d e))
(define (mul a b c d e)
(action * a b c d e))
But currying saved you from that nasty and error-prone work; you don't have to rewrite even a symbol in the functions add-curried and mul-curried at all, because the calling function would provide the necessary amount of arguments passed to action.
They can make code easier to read. Consider the following two Haskell snippets:
lengths :: [[a]] -> [Int]
lengths xs = map length xs
lengths' :: [[a]] -> [Int]
lengths' = map length
Why give a name to a variable you're not going to use?
Curried functions also help in situations like this:
doubleAndSum ys = map (\xs -> sum (map (*2) xs) ys
doubleAndSum' = map (sum . map (*2))
Removing those extra variables makes the code easier to read and there's no need for you to mentally keep clear what xs is and what ys is.
HTH.
You can see currying as a specialization. Pick some defaults and leave the user (maybe yourself) with a specialized, more expressive, function.
I think that currying is a traditional way to handle general n-ary functions provided that the only ones you can define are unary.
For example, in lambda calculus (from which functional programming languages stem), there are only one-variable abstractions (which translates to unary functions in FPLs). Regarding lambda calculus, I think it's easier to prove things about such a formalism since you don't actually need to handle the case of n-ary functions (since you can represent any n-ary function with a number of unary ones through currying).
(Others have already covered some of the practical implications of this decision so I'll stop here.)
Using all :: (a -> Bool) -> [a] -> Bool with a curried predicate.
all (`elem` [1,2,3]) [0,3,4,5]
Haskell infix operators can be curried on either side, so you can easily curry the needle or the container side of the elem function (is-element-of).
We cannot directly compose functions that takes multiple parameters. Since function composition is one of the key concept in functional programming. By using Currying technique we can compose functions that takes multiple parameters.
I would like to add example to #Francesco answer.
So you don't have to increase boilerplate with a little lambda.
It is very easy to create closures. From time to time i use SRFI-26. It is really cute.
In and of itself currying is syntactic sugar. Syntactic sugar is all about what you want to make easy. C for example wants to make instructions that are "cheap" in assembly language like incrementing, easy and so they have syntactic sugar for incrementation, the ++ notation.
t = x + y
x = x + 1
is replaced by t = x++ + y
Functional languages could just as easily have stuff like.
f(x,y,z) = abc
g(r,s)(z) = f(r,s,z).
h(r)(s)(z) = f(r,s,z)
but instead its all automatic. And that allows for a g bound by a particular r0, s0 (i.e. specific values) to be passed as a one variable function.
Take for example perl's sort function which takes
sort sub list
where sub is a function of two variables that evaluates to a boolean and
list is an arbitrary list.
You would naturally want to use comparison operators (<=>) in Perl and have
sortordinal = sort (<=>)
where sortordinal works on lists. To do this you would sort to be a curried function.
And in fact
sort of a list is defined in precisely this way in Perl.
In short: currying is sugar to make first class functions more natural.

Typed FP: Tuple Arguments and Curriable Arguments

In statically typed functional programming languages, like Standard ML, F#, OCaml and Haskell, a function will usually be written with the parameters separated from each other and from the function name simply by whitespace:
let add a b =
a + b
The type here being "int -> (int -> int)", i.e. a function that takes an int and returns a function which its turn takes and int and which finally returns an int. Thus currying becomes possible.
It's also possible to define a similar function that takes a tuple as an argument:
let add(a, b) =
a + b
The type becomes "(int * int) -> int" in this case.
From the point of view of language design, is there any reason why one could not simply identify these two type patterns in the type algebra? In other words, so that "(a * b) -> c" reduces to "a -> (b -> c)", allowing both variants to be curried with equal ease.
I assume this question must have cropped up when languages like the four I mentioned were designed. So does anyone know any reason or research indicating why all four of these languages chose not to "unify" these two type patterns?
I think the consensus today is to handle multiple arguments by currying (the a -> b -> c form) and to reserve tuples for when you genuinely want values of tuple type (in lists and so on). This consensus is respected by every statically typed functional language since Standard ML, which (purely as a matter of convention) uses tuples for functions that take multiple arguments.
Why is this so? Standard ML is the oldest of these languages, and when people were first writing ML compilers, it was not known how to handle curried arguments efficiently. (At the root of the problem is the fact that any curried function could be partially applied by some other code you haven't seen yet, and you have to compile it with that possibility in mind.) Since Standard ML was designed, compilers have improved, and you can read about the state of the art in an excellent paper by Simon Marlow and Simon Peyton Jones.
LISP, which is the oldest functional language of them all, has a concrete syntax which is extremely unfriendly to currying and partial application. Hrmph.
At least one reason not to conflate curried and uncurried functional types is that it would be very confusing when tuples are used as returned values (a convenient way in these typed languages to return multiple values). In the conflated type system, how can function remain nicely composable? Would a -> (a * a) also transform to a -> a -> a? If so, are (a * a) -> a and a -> (a * a) the same type? If not, how would you compose a -> (a * a) with (a * a) -> a?
You propose an interesting solution to the composition issue. However, I don't find it satisfying because it doesn't mesh well with partial application, which is really a key convenience of curried functions. Let me attempt to illustrate the problem in Haskell:
apply f a b = f a b
vecSum (a1,a2) (b1,b2) = (a1+b1,a2+b2)
Now, perhaps your solution could understand map (vecSum (1,1)) [(0,1)], but what about the equivalent map (apply vecSum (1,1)) [(0,1)]? It becomes complicated! Does your fullest unpacking mean that the (1,1) is unpacked with apply's a & b arguments? That's not the intent... and in any case, reasoning becomes complicated.
In short, I think it would be very hard to conflate curried and uncurried functions while (1) preserving the semantics of code valid under the old system and (2) providing a reasonable intuition and algorithm for the conflated system. It's an interesting problem, though.
Possibly because it is useful to have a tuple as a separate type, and it is good to keep different types separate?
In Haskell at least, it is quite easy to go from one form to the other:
Prelude> let add1 a b = a+b
Prelude> let add2 (a,b) = a+b
Prelude> :t (uncurry add1)
(uncurry add1) :: (Num a) => (a, a) -> a
Prelude> :t (curry add2)
(curry add2) :: (Num a) => a -> a -> a
so uncurry add1 is same as add2 and curry add2 is the same as add1. I guess similar things are possible in the other languages as well. What greater gains would there be to automatically currying every function defined on a tuple? (Since that's what you seem to be asking.)
Expanding on the comments under namin's good answer:
So assume a function which has type 'a -> ('a * 'a):
let gimme_tuple(a : int) =
(a*2, a*3)
Then assume a function which has type ('a * 'a) -> 'b:
let add(a : int, b) =
a + b
Then composition (assuming the conflation that I propose) wouldn't pose any problem as far as I can see:
let foo = add(gimme_tuple(5))
// foo gets value 5*2 + 5*3 = 25
But then you could conceive of a polymorphic function that takes the place of add in the last code snippet, for instance a little function that just takes a 2-tuple and makes a list of the two elements:
let gimme_list(a, b) =
[a, b]
This would have the type ('a * 'a) -> ('a list). Composition now would be problematic. Consider:
let bar = gimme_list(gimme_tuple(5))
Would bar now have the value [10, 15] : int list or would bar be a function of type (int * int) -> ((int * int) list), which would eventually return a list whose head would be the tuple (10, 15)? For this to work, I posited in a comment to namin's answer that one would need an additional rule in the type system that the binding of actual to formal parameters be the "fullest possible", i.e. that the system should attempt a non-partial binding first and only try a partial binding if a full binding is unattainable. In our example, it would mean that we get the value [10, 15] because a full binding is possible in this case.
Is such a concept of "fullest possible" inherently meaningless? I don't know, but I can't immediately see a reason it would be.
One problem is of course if you want the second interpretation of the last code snippet, then you'd need to go jump through an extra hoop (typically an anonymous function) to get that.
Tuples are not present in these languages simply to be used as function parameters. They are a really convenient way to represent structured data, e.g., a 2D point (int * int), a list element ('a * 'a list), or a tree node ('a * 'a tree * 'a tree). Remember also that structures are just syntactic sugar for tuples. I.e.,
type info =
{ name : string;
age : int;
address : string; }
is a convenient way of handling a (string * int * string) tuple.
There's no fundamental reason you need tuples in a programming language (you can build up tuples in the lambda calculus, just as you can booleans and integers—indeed using currying*), but they are convenient and useful.
* E.g.,
tuple a b = λf.f a b
fst x = x (λa.λb.a)
snd x = x (λa.λb.b)
curry f = λa.λb.f (λg.g a b)
uncurry f = λx.x f

Resources