I have learned (from a SML book) that functions in SML always takes just one argument: a tuple. A function that takes multiple arguments is just a function that takes one tuple as argument, implemented with a tuple binding in function binding. I understand this point.
But after this, the book says something that I don't understand:
this point makes SML language flexible and elegant design, and you can do something useful that you cannot do in Java.
Why does this design make the language Flexible? What is the text referring to, that SML can but java cannot?
Using tuples instead of multiple arguments adds flexibility in the sense that higher-order functions can work with functions of any "arity". For example to create the list [f x, f y, f z], you can use the higher-order function map like this:
map f [x, y, z]
That's easy enough - you can do that in any language. But now let's consider the case where f actually needs two arguments. If f were a true binary function (supposing SML had such functions), we'd need a different version of map that can work with binary functions instead of unary functions (and if we'd want to use a 3-ary functions, we'd need a version for those as well). However using tuples we can just write it like this:
map f [(x,a), (y,b), (z,c)]
This will create the list [f (x,a), f (y,b), f (z,c)].
PS: It's not really true that all functions that need multiple arguments take tuples in SML. Often functions use currying, not tuples, to represent multiple arguments, but I suppose your book hasn't gotten to currying yet. Curried functions can't be used in the same way as described above, so they're not as general in that sense.
Actually I don't think you really understand this at all.
First of all, functions in SML doesn't take a tuple as argument, they can take anything as argument. It is just sometimes convenient to use tuples as a means of passing multiple arguments. For example a function may take a record as argument, an integer, a string or it may even take another function as argument. One could also say that it can take "no arguments" in the sense that it may take unit as the argument.
If I understand your statement correctly about functions that takes "multiple arguments" you are talking about currying. For example
fun add x y = x + y
In SML, currying is implemented as a derived form (syntactic sugar). See this answer for an elaboration on how this actually works. In summary there is only anonymous functions in SML, however we can bind them to names such that they may "referred to"/used later.
Behold, ramblings about to start.
Before talking about flexibility of anything, I think it would be in order to state how I think of it. I quite like this definition of flexibility of programming languages: "[...] the unexpectedly many ways in which utterings in the language can be used"
In the case of SML, a small and simple core language has been chosen. This makes implementing compilers and interpreters easy. The flexibility comes in the form that many features of the SML language has been implemented using these core language features such as anonymous functions, pattern matching and the fact that SML has higher-order functions.
Examples of this is currying, case expressions, record selectors, if-the-else expressions, expression sequences.
I would say that this makes the SML core language very flexible and frankly quite elegant.
I'm not quite sure where the author was going regarding what SML can do, that java can't (in this context). However I'm quite sure that the author might be a bit biased, as you can do anything in java as well. However it might take immensely amounts of coding :)
Related
I have a huge lib of math functions, like pdf or cdf of statistical distributions. But often e.g. the inverse cdf can be only calculated numerically, e.g. using Newton-Raphson or bisection, in the latter we would need to check if cdf(x) is > or < then the target y0.
However, many functions have further parameters like a Gaussian distribution having certain mean and sigma, so cdf is cdf(x,mean,sigma). Whereas other functions, such as standard normal cdf, have no further parameters, or some have even 3 or 4 further parameters.
A similar problem would happen if you want to apply bisection for either linear functions (2 parameters) or parabolas (3 parameters). Or if you want not the inverse function, but e.g. the integral of f.
The easiest implementation would be to define cdf as global function f(x); and to check for >y0 or global variables.
However, this is a very old-fashioned way, and Freepascal also supports procedural parameters, for calls like x=icdf(0.9987,#cdfStdNorm)
Even overloading is supported to allow calls like x2=icdf(0.9987,0,2,#cdfNorm) to pass also mean and sigma.
But this ends up still in two separate code blocks (even whole functions), because in one case we need to call cdf only with x, and in 2nd example also with mean and sigma.
Is there an elegant solution for this problem in Freepascal? Maybe using variant records? Or an object-oriented approach? I have no glue about OO, but I know the variant object style would require to change at least the headers of many functions because I want to apply the technique not only for inverse cdf calculation, but also to numerical integration, root finding, optimization, etc.
Or is it "best" just to define a real function type with e.g. x + 5 parameters (maybe as array), and to ignore the unused parameters? But for me it looks that then I would need many "wrapper" functions or to re-code all the existing functions (to use the arrays, even if they are sometimes not needed!).
Maybe macros can help as well? Any Freepascal hints are very welcome!
If you make it a (function .. of object), mean and sigma could be part of the class, and the function could internally just access it. Only the really changing parameters during the iteration would be parameters. (read: x)
Anonymous methods as talked about by David and Rudy is a further step to avoid having to declare a class for each such invocation, but that is convenience thing and IMHO not the core of the question. At the expense of declaring the class, your core code is free of global variable use and anonymous methods might also come with a performance cost, depending on usage.
Free Pascal also supports nested functions (function... is nested), which is the original Pascal closure-like way which was never adopted by Pascal compilers from Borland. A nested procedure passed as callback can access local variables in the procedure where it was declared. The Free Pascal numlib numeric math package uses this in some cases for similar cases like yours. For math it is even more natural.
Delphi never implements old constructs because borrowing syntax from other languages looks better on bulletlists and keeps the subscriptions flowing.
Are there any macros that:
Cannot be expressed as a equivalent function, or:
Are difficult to express as a equivalent function, or:
Are significantly worse in terms of performance than equivalent function?
Can you give an example of such a macro (and function)?
My question refers specifically to Lisp's macros and functions, but you may treat this question more generally. I'm particularly interested in recursive macros.
Edit:
I should've been more specific. When I asked the above question, I kept in mind specific context of my Lisp project, which is kind of mathematical symbolic programming calculator.
I was wondering if there is good reason to use macro for any of the mathematical operations, like:
analytical integration,
analytical differentiation,
polynomial operations,
computing Taylor series for given function,
computing trigonometric identities,
and so on...
For some reason I need to use a few recursive macros for this project. So, if I can reformulate my question:
Can you give examples of smart use of [recursive] macros in a symbolic calculation?
Are there any macros that:
Cannot be expressed as a equivalent function, or:
Are difficult to express as a equivalent function, or:
Are significantly worse in terms of performance than equivalent function?
The answer is never quite this simple. It's typically "yes and no". As I see it, there are two big advantages of macros: syntactic sugar delayed evaluation. For instance, macros like with-open-file, which lets you write:
(with-open-file (var "some-filename")
; operations with var
)
is pretty much just syntactic sugar for
(let ((x (open ...)))
(unwind-protect
(funcall (lambda (var)
; operations with var
)
x)
; cleanup forms
))
That's sort of a mix of delayed evaluation and syntactic sugar, depending on how you look at it. It's delayed evaluation, in that all the operations with var are wrapped up into a lambda function. It's also syntactic sugar, because you could obviously abstract the above into:
(defun call-with-open-file (open-args function)
(let ((x (apply 'open open-args)))
(unwind-protect (funcall function x)
; cleanup forms
)))
and then with-open-file is just syntactic sugar:
(defmacro with-open-file ((var &rest open-args) &body body)
`(call-with-open-file (list ,#open-args)
(lambda (,var) ,#body)))
That's a typical case that exhibits both delayed evaluation (of the body forms) and syntactic sugar around a functional interface. You can typically always do that. E.g., with if, you could write a functional interface:
(defun %if (condition then &optional (else (constantly nil)))
`(funcall (cond (condition then) (t else))))
Then if can be implemented as a macro:
(defmacro if (condition then &optional else)
`(%if condition (lambda () ,then) (lambda () ,else)))
if and other conditional forms are a bit unique, in this sense, though, because the implementation ultimately has to provide you some conditional operation. That operator typically isn't a macro, though, but a special form.
What about other special macros like loop, that define domain specific languages? You can do those too, but you pretty much would just end up having the function accept the "body" of the macro version and interpret it at runtime. E.g., you could do
(defun %loop (&rest loop-body)
; interpret body
)
but that's obviously going to be a big performance hit.
So, I'd posit that there are no macros that don't have a semantic equivalent, but these will require somewhat different arguments. Some of those semantically equivalent functions will be difficult to expression, and some of them (e.g., when passing anonymous functions around) will certainly have significantly worse performance.
I think your question is not well posed since it is based on the ambiguous use of the term “equivalent”. At a first sight, it seems that you intend “equivalent” as: “calculating the same value” (and this is confirmed by your third question about performance).
But they are not equivalent at all, because functions produce (or calculate) values, while macros produce (or calculate) programs! (and when you understand this, you will understand that a macro actually is a function, a function from s-expressions (the “quoted arguments”) to s-expressions).
So, I think that the answer to your questions should be given in these terms:
1) If you stretch the meaning of equivalence as “when the result of a macro, (i.e. a program), is further evaluated by the system”, than an answer like that of Joshua Taylor is to be taken into consideration;
2) If you are asking about macros and functions per se, they are not equivalent at all.
And concerning their use in the task you are addressing: macros can be really useful in defining particular control structures, or specialized ways of performing computation, like in DSL (Domain Specific Languages), but my advice is to use them only when you think that your problem could be solved in an easier way by adding to the usual tools (i.e. predefined functions, special forms and macros) new powerful tools, and when you have experience in writing complex macros (to practice this, see for instance the book of Paul Graham On Lisp).
Are there any macros that cannot be expressed as a function?
Yes; all macros in any expertly written Lisp program!
There are sometimes macros that can be replaced by functions, if you radically change or augment underlying language implementation.
For instance, a macro might be simulating something that otherwise requires continuations in a Lisp dialect that doesn't have them. Or it might be doing something that looks like non-strict evaluation, over a strict language. Something can can be done just with functions in a call-by-name language can be expressed with macros over pure call-by-value.
Macros go away when they are expanded; all that is left is special operators and functions. What functions can or cannot do depends on the available special operators. For instance without a operators to capture a continuation, a function cannot abandon its evaluation in such a way that it can be later restarted.
Therefore it is a false dichotomy to think about the power as being divided between macros and functions, while ignoring special operators.
A given problem can be solved by a combination of functions and special operators. If it requires certain special operators, then we cannot say that
the problem is solved by functions alone.
Macros can be used in such a way that they hide the use of special operators. Macros which conceal the essential use of special operators cannot be rewritten as functions.
For instance, a macro that provides syntactic sugar over a lambda operator cannot be written as a function. The macro's essential functionality depends on the fact that it expands to a lambda operator which captures a closure in the original lexical environment where the macro call occurs.
When Lisp language designers extend a dialect with new core functionality, they do so by adding new special forms. Macros are added at the same time to make the forms easier to use. For instance, I recently added delimited continuations to a Lisp dialect. The underlying API is not the easiest thing to use for certain simple tasks, so I also provided macros which provide an easy-to-use "generator" abstraction. Needless to say, these generator macros cannot be implemented with functions. Not only that, those macros cannot be implemented at all without the delimited continuation support; all they do is write code that depends on using these new special forms, and those special forms are implemented by hacks deep the language core which do nasty things like copying sections of the run-time stack to the heap, and back to a different area of the stack.
Now in a purely interpretive Lisp that runs programs by evaluating raw source code, you can have a form of function which is as powerful as a macro (in fact, more so). This is a function which, when it is called at run-time, receives its argument expressions unevaluated, together with the run-time environment needed to evaluate them. Essentially, such a function, though written by the user, acts as an "interpreter plugin", called upon to interpret code in an arbitrary way. In historic Lisp terminology, this kind of function is called a "fexpr".
The relationship between macros and fexprs is that macros are to fexprs what compilers are to interpreters. If you have a dialect with fexprs, then there is no reason to use macros if the only requirement is to support some syntax with some semantics, without caring about performance. A macro may be able to do the same thing by compiling to a more efficient translation. Even though the dialect is purely interpretive, it's nevertheless faster to have the interpreter run some macro-generated code, than for the interpreter to interpret a function, which itself interprets code.
But, of course, though fexprs are functions, they are not ordinary functions; ordinary functions receive evaluated arguments and no environment. So that just changes the question to: are there essential fexprs that cannot be replaced by ordinary functions?
The answer is: yes, any fexprs in an expertly written program ...
Any Lisp macro which does not evaluate ("twice", since it is a macro) its arguments cannot be expressed as a function, since function application is done on evaluated arguments. For example you could define a macro my-if which behaves exactly like if (and if cannot be a function)
C.Queinnec's book Lisp In Small Pieces explains that in great detail (and has several chapters about macros). I strongly recommend to read it (since answering your too broad question may require an entire book, not a paragraph).
If a macro expands one of its arguments several times, it might be slower than the equivalent function (because some sub-computations could be done twice if expanded twice).
(of course, the answer to all your questions can be yes; I leave up to you how to find some examples).
PS. BTW, this is even true in C....
In Haskell function type (->) is given, it's not an algebraic data type constructor and one cannot re-implement it to be identical to (->).
So I wonder, what languages will allow me to write my version of (->)? How does this property called?
UPD Reformulations of the question thanks to the discussion:
Which languages don't have -> as a primitive type?
Why -> is necessary primitive?
I can't think of any languages that have arrows as a user defined type. The reason is that arrows -- types for functions -- are baked in to the type system, all the way down to the simply typed lambda calculus. That the arrow type must fundamental to the language comes directly from the fact that the way you form functions in the lambda calculus is via lambda abstraction (which, at the type level, introduces arrows).
Although Marcin aptly notes that you can program in a point free style, this doesn't change the essence of what you're doing. Having a language without arrow types as primitives goes against the most fundamental building blocks of Haskell. (The language you reference in the question.)
Having the arrow as a primitive type also shares some important ties to constructive logic: you can read the function arrow type as implication from intuition logic, and programs having that type as "proofs." (Namely, if you have something of type A -> B, you have a proof that takes some premise of type A, and produces a proof for B.)
The fact that you're perturbed by the use of having arrows baked into the language might imply that you're not fundamentally grasping why they're so tied to the design of the language, perhaps it's time to read a few chapters from Ben Pierce's "Types and Programming Languages" link.
Edit: You can always look at languages which don't have a strong notion of functions and have their semantics defined with respect to some other way -- such as forth or PostScript -- but in these languages you don't define inductive data types in the same way as in functional languages like Haskell, ML, or Coq. To put it another way, in any language in which you define constructors for datatypes, arrows arise naturally from the constructors for these types. But in languages where you don't define inductive datatypes in the typical way, you don't get arrow types as naturally because the language just doesn't work that way.
Another edit: I will stick in one more comment, since I thought of it last night. Function types (and function abstraction) forms the basis of pretty much all programming languages -- at least at some level, even if it's "under the hood." However, there are languages designed to define the semantics of other languages. While this doesn't strictly match what you're talking about, PLT Redex is one such system, and is used for specifying and debugging the semantics of programming languages. It's not super useful from a practitioners perspective (unless your goal is to design new languages, in which case it is fairly useful), but maybe that fits what you want.
Do you mean meta-circular evaluators like in SICP? Being able to write your own DSL? If you create your own "function type", you'll have to take care of "applying" it, yourself.
Just as an example, you could create your own "function" in C for instance, with a look-up table holding function pointers, and use integers as functions. You'd have to provide your own "call" function for such "functions", of course:
void call( unsigned int function, int data) {
lookup_table[function](data);
}
You'd also probably want some means of creating more complex functions from primitive ones, for instance using arrays of ints to signify sequential execution of your "primitive functions" 1, 2, 3, ... and end up inventing whole new language for yourself.
I think early assemblers had no ability to create callable "macros" and had to use GOTO.
You could use trampolining to simulate function calls. You could have only global variables store, with shallow binding perhaps. In such language "functions" would be definable, though not primitive type.
So having functions in a language is not necessary, though it is convenient.
In Common Lisp defun is nothing but a macro associating a name and a callable object (though lambda is still a built-in). In AutoLisp originally there was no special function type at all, and functions were represented directly by quoted lists of s-expressions, with first element an arguments list. You can construct your function through use of cons and list functions, from symbols, directly, in AutoLisp:
(setq a (list (cons 'x NIL) '(+ 1 x)))
(a 5)
==> 6
Some languages (like Python) support more than one primitive function type, each with its calling protocol - namely, generators support multiple re-entry and returns (even if syntactically through the use of same def keyword). You can easily imagine a language which would let you define your own calling protocol, thus creating new function types.
Edit: as an example consider dealing with multiple arguments in a function call, the choice between automatic currying or automatical optional args etc. In Common LISP say, you could easily create yourself two different call macros to directly represent the two calling protocols. Consider functions returning multiple values not through a kludge of aggregates (tuples, in Haskell), but directly into designated recepient vars/slots. All are different types of functions.
Function definition is usually primitive because (a) functions are how programmes get things done; and (b) this sort of lambda-abstraction is necessary to be able to programme in a pointful style (i.e. with explicit arguments).
Probably the closest you will come to a language that meets your criteria is one based on a purely pointfree model which allows you to create your own lambda operator. You might like to explore pointfree languages in general, and ones based on SKI calculus in particular: http://en.wikipedia.org/wiki/SKI_combinator_calculus
In such a case, you still have primitive function types, and you always will, because it is a fundamental element of the type system. If you want to get away from that at all, probably the best you could do would be some kind of type system based on a category-theoretic generalisation of functions, such that functions would be a special case of another type. See http://en.wikipedia.org/wiki/Category_theory.
Which languages don't have -> as a primitive type?
Well, if you mean a type that can be named, then there are many languages that don't have them. All languages where functions are not first class citiziens don't have -> as a type you could mention somewhere.
But, as #Kristopher eloquently and excellently explained, functions are (or can, at least, perceived as) the very basic building blocks of all computation. Hence even in Java, say, there are functions, but they are carefully hidden from you.
And, as someone mentioned assembler - one could maintain that the machine language (of most contemporary computers) is an approximation of the model of the register machine. But how it is done? With millions and billions of logical circuits, each of them being a materialization of quite primitive pure functions like NOT or NAND, arranged in a certain physical order (which is, obviously, the way hardware engeniers implement function composition).
Hence, while you may not see functions in machine code, they're still the basis.
In Martin-Löf type theory, function types are defined via indexed product types (so-called Π-types).
Basically, the type of functions from A to B can be interpreted as a (possibly infinite) record, where all the fields are of the same type B, and the field names are exactly all the elements of A. When you need to apply a function f to an argument x, you look up the field in f corresponding to x.
The wikipedia article lists some programming languages that are based on Martin-Löf type theory. I am not familiar with them, but I assume that they are a possible answer to your question.
Philip Wadler's paper Call-by-value is dual to call-by-name presents a calculus in which variable abstraction and covariable abstraction are more primitive than function abstraction. Two definitions of function types in terms of those primitives are provided: one implements call-by-value, and the other call-by-name.
Inspired by Wadler's paper, I implemented a language (Ambidexer) which provides two function type constructors that are synonyms for types constructed from the primitives. One is for call-by-value and one for call-by-name. Neither Wadler's dual calculus nor Ambidexter provides user-defined type constructors. However, these examples show that function types are not necessarily primitive, and that a language in which you can define your own (->) is conceivable.
In Scala you can mixin one of the Function traits, e.g. a Set[A] can be used as A => Boolean because it implements the Function1[A,Boolean] trait. Another example is PartialFunction[A,B], which extends usual functions by providing a "range-check" method isDefinedAt.
However, in Scala methods and functions are different, and there is no way to change how methods work. Usually you don't notice the difference, as methods are automatically lifted to functions.
So you have a lot of control how you implement and extend functions in Scala, but I think you have a real "replacement" in mind. I'm not sure this makes even sense.
Or maybe you are looking for languages with some kind of generalization of functions? Then Haskell with Arrow syntax would qualify: http://www.haskell.org/arrows/syntax.html
I suppose the dumb answer to your question is assembly code. This provides you with primitives even "lower" level than functions. You can create functions as macros that make use of register and jump primitives.
Most sane programming languages will give you a way to create functions as a baked-in language feature, because functions (or "subroutines") are the essence of good programming: code reuse.
Suppose I have the following clojure functions:
(defn a [x] (* x x))
(def b (fn [x] (* x x)))
(def c (eval (read-string "(defn d [x] (* x x))")))
Is there a way to test for the equality of the function expression - some equivalent of
(eqls a b)
returns true?
It depends on precisely what you mean by "equality of the function expression".
These functions are going to end up as bytecode, so I could for example dump the bytecode corresponding to each function to a byte[] and then compare the two bytecode arrays.
However, there are many different ways of writing semantically equivalent methods, that wouldn't have the same representation in bytecode.
In general, it's impossible to tell what a piece of code does without running it. So it's impossible to tell whether two bits of code are equivalent without running both of them, on all possible inputs.
This is at least as bad, computationally speaking, as the halting problem, and possibly worse.
The halting problem is undecidable as it is, so the general-case answer here is definitely no (and not just for Clojure but for every programming language).
I agree with the above answers in regards to Clojure not having a built in ability to determine the equivalence of two functions and that it has been proven that you can not test programs functionally (also known as black box testing) to determine equality due to the halting problem (unless the input set is finite and defined).
I would like to point out that it is possible to algebraically determine the equivalence of two functions, even if they have different forms (different byte code).
The method for proving the equivalence algebraically was developed in the 1930's by Alonzo Church and is know as beta reduction in Lambda Calculus. This method is certainly applicable to the simple forms in your question (which would also yield the same byte code) and also for more complex forms that would yield different byte codes.
I cannot add to the excellent answers by others, but would like to offer another viewpoint that helped me. If you are e.g. testing that the correct function is returned from your own function, instead of comparing the function object you might get away with just returning the function as a 'symbol.
I know this probably is not what the author asked for but for simple cases it might do.
A reddit thread brought up an apparently interesting question:
Tail recursive functions can trivially be converted into iterative functions. Other ones, can be transformed by using an explicit stack. Can every recursion be transformed into iteration?
The (counter?)example in the post is the pair:
(define (num-ways x y)
(case ((= x 0) 1)
((= y 0) 1)
(num-ways2 x y) ))
(define (num-ways2 x y)
(+ (num-ways (- x 1) y)
(num-ways x (- y 1))
Can you always turn a recursive function into an iterative one? Yes, absolutely, and the Church-Turing thesis proves it if memory serves. In lay terms, it states that what is computable by recursive functions is computable by an iterative model (such as the Turing machine) and vice versa. The thesis does not tell you precisely how to do the conversion, but it does say that it's definitely possible.
In many cases, converting a recursive function is easy. Knuth offers several techniques in "The Art of Computer Programming". And often, a thing computed recursively can be computed by a completely different approach in less time and space. The classic example of this is Fibonacci numbers or sequences thereof. You've surely met this problem in your degree plan.
On the flip side of this coin, we can certainly imagine a programming system so advanced as to treat a recursive definition of a formula as an invitation to memoize prior results, thus offering the speed benefit without the hassle of telling the computer exactly which steps to follow in the computation of a formula with a recursive definition. Dijkstra almost certainly did imagine such a system. He spent a long time trying to separate the implementation from the semantics of a programming language. Then again, his non-deterministic and multiprocessing programming languages are in a league above the practicing professional programmer.
In the final analysis, many functions are just plain easier to understand, read, and write in recursive form. Unless there's a compelling reason, you probably shouldn't (manually) convert these functions to an explicitly iterative algorithm. Your computer will handle that job correctly.
I can see one compelling reason. Suppose you've a prototype system in a super-high level language like [donning asbestos underwear] Scheme, Lisp, Haskell, OCaml, Perl, or Pascal. Suppose conditions are such that you need an implementation in C or Java. (Perhaps it's politics.) Then you could certainly have some functions written recursively but which, translated literally, would explode your runtime system. For example, infinite tail recursion is possible in Scheme, but the same idiom causes a problem for existing C environments. Another example is the use of lexically nested functions and static scope, which Pascal supports but C doesn't.
In these circumstances, you might try to overcome political resistance to the original language. You might find yourself reimplementing Lisp badly, as in Greenspun's (tongue-in-cheek) tenth law. Or you might just find a completely different approach to solution. But in any event, there is surely a way.
Is it always possible to write a non-recursive form for every recursive function?
Yes. A simple formal proof is to show that both µ recursion and a non-recursive calculus such as GOTO are both Turing complete. Since all Turing complete calculi are strictly equivalent in their expressive power, all recursive functions can be implemented by the non-recursive Turing-complete calculus.
Unfortunately, I’m unable to find a good, formal definition of GOTO online so here’s one:
A GOTO program is a sequence of commands P executed on a register machine such that P is one of the following:
HALT, which halts execution
r = r + 1 where r is any register
r = r – 1 where r is any register
GOTO x where x is a label
IF r ≠ 0 GOTO x where r is any register and x is a label
A label, followed by any of the above commands.
However, the conversions between recursive and non-recursive functions isn’t always trivial (except by mindless manual re-implementation of the call stack).
For further information see this answer.
Recursion is implemented as stacks or similar constructs in the actual interpreters or compilers. So you certainly can convert a recursive function to an iterative counterpart because that's how it's always done (if automatically). You'll just be duplicating the compiler's work in an ad-hoc and probably in a very ugly and inefficient manner.
Basically yes, in essence what you end up having to do is replace method calls (which implicitly push state onto the stack) into explicit stack pushes to remember where the 'previous call' had gotten up to, and then execute the 'called method' instead.
I'd imagine that the combination of a loop, a stack and a state-machine could be used for all scenarios by basically simulating the method calls. Whether or not this is going to be 'better' (either faster, or more efficient in some sense) is not really possible to say in general.
Recursive function execution flow can be represented as a tree.
The same logic can be done by a loop, which uses a data-structure to traverse that tree.
Depth-first traversal can be done using a stack, breadth-first traversal can be done using a queue.
So, the answer is: yes. Why: https://stackoverflow.com/a/531721/2128327.
Can any recursion be done in a single loop? Yes, because
a Turing machine does everything it does by executing a single loop:
fetch an instruction,
evaluate it,
goto 1.
Yes, using explicitly a stack (but recursion is far more pleasant to read, IMHO).
Yes, it's always possible to write a non-recursive version. The trivial solution is to use a stack data structure and simulate the recursive execution.
In principle it is always possible to remove recursion and replace it with iteration in a language that has infinite state both for data structures and for the call stack. This is a basic consequence of the Church-Turing thesis.
Given an actual programming language, the answer is not as obvious. The problem is that it is quite possible to have a language where the amount of memory that can be allocated in the program is limited but where the amount of call stack that can be used is unbounded (32-bit C where the address of stack variables is not accessible). In this case, recursion is more powerful simply because it has more memory it can use; there is not enough explicitly allocatable memory to emulate the call stack. For a detailed discussion on this, see this discussion.
All computable functions can be computed by Turing Machines and hence the recursive systems and Turing machines (iterative systems) are equivalent.
Sometimes replacing recursion is much easier than that. Recursion used to be the fashionable thing taught in CS in the 1990's, and so a lot of average developers from that time figured if you solved something with recursion, it was a better solution. So they would use recursion instead of looping backwards to reverse order, or silly things like that. So sometimes removing recursion is a simple "duh, that was obvious" type of exercise.
This is less of a problem now, as the fashion has shifted towards other technologies.
Recursion is nothing just calling the same function on the stack and once function dies out it is removed from the stack. So one can always use an explicit stack to manage this calling of the same operation using iteration.
So, yes all-recursive code can be converted to iteration.
Removing recursion is a complex problem and is feasible under well defined circumstances.
The below cases are among the easy:
tail recursion
direct linear recursion
Appart from the explicit stack, another pattern for converting recursion into iteration is with the use of a trampoline.
Here, the functions either return the final result, or a closure of the function call that it would otherwise have performed. Then, the initiating (trampolining) function keep invoking the closures returned until the final result is reached.
This approach works for mutually recursive functions, but I'm afraid it only works for tail-calls.
http://en.wikipedia.org/wiki/Trampoline_(computers)
I'd say yes - a function call is nothing but a goto and a stack operation (roughly speaking). All you need to do is imitate the stack that's built while invoking functions and do something similar as a goto (you may imitate gotos with languages that don't explicitly have this keyword too).
Have a look at the following entries on wikipedia, you can use them as a starting point to find a complete answer to your question.
Recursion in computer science
Recurrence relation
Follows a paragraph that may give you some hint on where to start:
Solving a recurrence relation means obtaining a closed-form solution: a non-recursive function of n.
Also have a look at the last paragraph of this entry.
It is possible to convert any recursive algorithm to a non-recursive
one, but often the logic is much more complex and doing so requires
the use of a stack. In fact, recursion itself uses a stack: the
function stack.
More Details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions
tazzego, recursion means that a function will call itself whether you like it or not. When people are talking about whether or not things can be done without recursion, they mean this and you cannot say "no, that is not true, because I do not agree with the definition of recursion" as a valid statement.
With that in mind, just about everything else you say is nonsense. The only other thing that you say that is not nonsense is the idea that you cannot imagine programming without a callstack. That is something that had been done for decades until using a callstack became popular. Old versions of FORTRAN lacked a callstack and they worked just fine.
By the way, there exist Turing-complete languages that only implement recursion (e.g. SML) as a means of looping. There also exist Turing-complete languages that only implement iteration as a means of looping (e.g. FORTRAN IV). The Church-Turing thesis proves that anything possible in a recursion-only languages can be done in a non-recursive language and vica-versa by the fact that they both have the property of turing-completeness.
Here is an iterative algorithm:
def howmany(x,y)
a = {}
for n in (0..x+y)
for m in (0..n)
a[[m,n-m]] = if m==0 or n-m==0 then 1 else a[[m-1,n-m]] + a[[m,n-m-1]] end
end
end
return a[[x,y]]
end