prototyping functions in SML - functional-programming

I have two functions, f and g, which call each other recursively. Unfortunately, when f calls g, it has not yet been declared, so I get an "unbound variable" error. How can I prototype (or whatever the equivalent vocabulary is) this function in SML/NJ?

Use and:
fun f x = ...
and g x = ...
More info here.

Mutual Recursion. Use and instead of fun between the two functions.

Related

What are the differences between the 4 ways to define a function? [duplicate]

In Julia, I know of three ways to define a named multiline function:
1.
function f(x, y)
...
end
2.
f = function(x, y)
...
end
3.
f(x, y) = begin
...
end
They all seem to produce the same outcome.
Is there any difference? Which one should be used and why?
1 and 3 are functionally identical, but 1 is preferred stylistically. The "short form function declaration" f(x,y) = … is typically used (and encouraged) for one-line definitions — that is, without a begin block.
2 is different. It's creating an anonymous function, and then assigning it to f. Note that unlike the bindings created by 1 and 3, you can actually reassign f to completely different things. This means that Julia cannot assume that f will always call that function, which means that it cannot do any of its normal optimizations. Now, if you used const f = function(x, y) …, then f is a constant binding and it should behave similarly to the other declarations. But note that f is still just a binding to an anonymous function — the function itself doesn't know what its name is! So it'll print as #1 (generic function with 1 method) instead of f (generic function with 1 method).
See https://docs.julialang.org/en/stable/manual/functions/ for more details.
Definitions 1 and 3 are equivalent (the difference is only style, option 1 is usually preferred). They define function f for which you can implement multiple methods (https://docs.julialang.org/en/v1/manual/methods/).
Definition 2 creates an anonymous function and assigns it to a global variable f. I would not encourage it in general.
If you would call such a function inside other function using name f the result would not be type stable (variable f from global scope would have to be resolved). Anonymous functions are usually used in situations where the name is not important.
Actually there are two other ways to define multiple line anonymous function (again - I do not encourage it but show it for completeness):
f = x -> begin
...
end
and
f = identity() do x
...
end

Define the notion of "pairs" using higher-order logic

Revising for a course on automated reasoning and I don't quite understand how to answer this question:
Show how the notion of pairs (x, y) can be defined in higher-order logic using a lambda abstraction. Define a function π1 that returns the first element of such a pair. Finally, show that π1(x, y) = x.
I've found similar questions on stackoverflow, but they're all to do with scheme, which I've never used. An explanation in English/relevant mathematical notation would be appreciated
Here you go
PAIR := λx. λy. λp. p x y
π1 := λp. p (λx. λy. x)
π2 := λp. p (λx. λy. y)
π1 (PAIR a b) => a
π2 (PAIR a b) => b
Check the wiki entry on Church encoding for some good examples, too
The main topic of this question is to understand how data can be represented as functions. When you're working with other paradigms , the normal way of thinking is "data = something that's stored in a variable" (could be an array, object, whatever structure you want).
But when we're in functional programming, we can also represent data as functions.
So let's say you want a function pair(x,y)
This is "pseudo" lisp language:
(function pair x y =
lambda(pick)
if pick = 1 return x
else return y )
That example, is showing a function that returns a lambda function which expects a parameter.
(function pi this-is-pair = this-is-pair 1)
this-is-pair should be constructed with a pair function, therefore, the parameter is a function which expects other parameter (pick).
And now, you can test what you need
(pi (pair x y ) ) should return x
I would highly recommend you to see this video about compound data. Most of the examples are made on lisp, but it's great to understand a concept like that.
Pairs or tuples describes Products Domain, is the union of all elements of the set A and all elements of the set B:
A × B = { (a, b) | a ∈ A, b ∈ B }
Here, A and B are diferent types, so if you for example are in a laguage program like C, Java, you can have pair like (String, Integer), (Char, Boolean), (Double, Double)
Now, the function π1, is just a function that takes a pair and returns the first element, this function is called in usually first, and that's how it looks like π1(x, y) = x, on the other hand you have second, doing the same thing but returning the second element:
fst(a, b) = a
snd(a, b) = b
When I studied the signature "Characteristics of the programming languages" in college our professor recommended this book, see the chapter Product Domain to understand well all this concepts.

Lists of Functions and their execution Erlang

Is it possible to create and send a list of functions as an argument to another function, and then have some functions within this list call other functions in this list?
For example, I want a function that works on a list passed as an argument, and then performs the first function in the list of functions on this list of numbers, and if that function makes calls to other functions within that list, they can be retrieved and used.
e.g.: deviation(Numbers, Functions) -> %Functions = [fun master/1, fun avg/1, fun meanroots/1]
Master calls avg, then passes that result into meanroots, etc. but at the end of the call chain the master is the one that will return a value.
I'd like to know if this is functionally possible, whether within OTP alone or using NIFs, and if there are samples of implementation to look at.
How would your function know whether one of the functions in the list called another function in the list? I think your question is worded confusingly.
You could create a function to chain the results through a series of functions:
chain(Nums, []) -> Nums;
chain(Nums, [H | T]) -> chain(H(Nums), T).
which could be done with a standard function:
lists:foldl(fun (F, V) -> F(V) end, Nums, Funcs)
Of course you can:
1> F1 = fun(A) -> A*A end.
#Fun<erl_eval.6.50752066>
2> F2 = fun(A) -> A+A end.
#Fun<erl_eval.6.50752066>
3> F3 = fun(A) -> A*A+A end.
#Fun<erl_eval.6.50752066>
4> Funs = [F1, F2, F3].
[#Fun<erl_eval.6.50752066>,#Fun<erl_eval.6.50752066>,
#Fun<erl_eval.6.50752066>]
5> [F(X) || X <- [1,2,3], F <- Funs].
[1,2,2,4,4,6,9,6,12]
You could create tagged tuples with functions, e.g. {tag1, F1} (where F1 is defined as above), pass them to functions and do with them all sort of stuff you would normally do with any other variable in Erlang.

Can we pass a function as an argument

I'm using R to build a mathematical model. I want to write a function f(a, b, g) that takes in 3 arguments and the last one is a function. I want to know can I pass a function as an argument to another function? If this is possible, can you guys give me a simple example?
It is certainly legitimate to pass a function as an argument to another function. Many elementary R functions do this. For example,
tapply(..., FUN)
You can check them by ?tapply.
The thing is, you only treat the name of the function as a symbol. For example, in the toy example below:
foo1 <- function () print("this is function foo1!")
foo2 <- function () print("this is function foo2!")
test <- function (FUN) {
if (!is.function(FUN)) stop("argument FUN is not a function!")
FUN()
}
## let's have a go!
test(FUN = foo1)
test(FUN = foo2)
It is also possible to pass function arguments of foo1 or foo2 to test, by using .... I leave this for you to have some research.
If you are familiar with C language, then it is not difficult to understand why this is legitimate. R is written in C (though its language syntax belongs to S language), so essentially this is achieved by using pointers to function. If case you want to learn more on this, see How do function pointers in C work?
Here's a really simple example from Hadley's text:
randomise <- function(f) f(runif(1e3))
randomise(mean)
#> [1] 0.5059199
randomise(mean)
#> [1] 0.5029048
randomise(sum)
#> [1] 504.245

What’s the environment and enclosure of nested `eval`?

Background
I’m in the process of creating a shortcut for lambdas, since the repeated use of function (…) … clutters my code considerably. As a remedy, I’m trying out alternative syntaxes inspired by other languages such as Haskell, as far as this is possible in R. Simplified, my code looks like this:
f <- function (...) {
args <- match.call(expand.dots = FALSE)$...
last <- length(args)
params <- c(args[-last], names(args)[[last]])
function (...)
eval(args[[length(args)]],
envir = setNames(list(...), params),
enclos = parent.frame())
}
This allows the following code:
f(x = x * 2)(5) # => 10
f(x, y = x + y)(1, 2) # => 3
etc.
Of course the real purpose is to use this with higher-order functions1:
Map(f(x = x * 2), 1 : 10)
The problem
Unfortunately, I sometimes have to nest higher-order functions and then it stops working:
f(x = Map(f(y = x + y), 1:2))(10)
yields “Error in eval(expr, envir, enclos): object x not found”. The conceptually equivalent code using function instead of f works. Furthermore, other nesting scenarios also work:
f(x = f(y = x + y)(2))(3) # => 5
I’m suspecting that the culprit is the parent environment of the nested f inside the map: it’s the top-level environment rather than the outer f’s. But I have no idea how to fix this, and it also leaves me puzzled that the second scenario above works. Related questions (such as this one) suggest workarounds which are not applicable in my case.
Clearly I have a gap in my understanding of environments in R. Is what I want possible at all?
1 Of course this example could simply be written as (1 : 10) * 2. The real application is with more complex objects / operations.
The answer is to attach parent.frame() to the output function's environment:
f <- function (...) {
args <- match.call(expand.dots = FALSE)$...
last <- length(args)
params <- c(args[-last], names(args)[[last]])
e <- parent.frame()
function (...)
eval(args[[length(args)]],
envir = setNames(list(...), params),
enclos = e)
}
Hopefully someone can explain well why this works and not yours. Feel free to edit.
Great question.
Why your code fails
Your code fails because eval()'s supplied enclos= argument does not point far enough up the call stack to reach the environment in which you are wanting it to next search for unresolved symbols.
Here is a partial diagram of the call stack from the bottom of which your call to parent.frame() occurs. (To make sense of this, it's important to keep in mind that the function call from which parent.frame() is here being called is not f(), but a call the anonymous function returned by f() (let's call it fval)).
## Note: E.F. = "Evaluation Frame"
## fval = anonymous function returned as value of nested call to f()
f( <------------------------- ## E.F. you want, ptd to by parent.frame(n=3)
Map(
mapply( <-------------------- ## E.F. pointed to by parent.frame(n=1)
fval( |
parent.frame(n=1 |
In this particular case, redefining the function returned by f() to call parent.frame(n=3) rather than parent.frame(n=1) produces working code, but that's not a good general solution. For instance, if you wanted to call f(x = mapply(f(y = x + y), 1:2))(10), the call stack would then be one step shorter, and you'd instead need parent.frame(n=2).
Why flodel's code works
flodel's code provides a more robust solution by calling parent.frame() during evaluation of the inner call to f in the nested chain f(Map(f(), ...)) (rather than during the subsequent evaluation of the anonymous function fval returned by f()).
To understand why his parent.frame(n=1) points to the appropriate environment, it's important to recall that in R, supplied arguments are evaluated in the the evaluation frame of the calling function. In the OP's example of nested code, the inner f() is evaluated during the processing of Map()'s supplied arguments, so it's evaluation environment is that of the function calling Map(). Here, the function calling Map() is the outer call to f(), and its evaluation frame is exactly where you want eval() to next be looking for symbols:
f( <--------------------- ## Evaluation frame of the nested call to f()
Map(f( |
parent.frame(n=1 |

Resources