[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
I couldn't make the presentation (new kid born on Tuesday) so sorry about that.
> You said that = was in reality a binding instead of an assignment. > I'm not sure I understand. Are you saying that in erlang this > statement: > > Var = 2 + 2 > > puts something besides the number 4 into Var?
No, at the end of that expression evaluation, Var will surely point to the value 4. However, Erlang's = is a binding operator, not an assignment operator. Assignments insert a value into a memory location. Bindings associated a name with a value. In Erlang, the = is "overloaded" (so to speak) by also performing Prolog-style pattern matching. So, this statement:
A way that was useful for me to think about it is that saying 'Var = 2 + 2' is like an assertion. You're saying that the symbol Var is (the result of) 2 + 2 (or 4). So you can also assert: 'Var = 2 + 1 + 1' or 'Var = 2 * 2' or 'Var = 4 - 2' all within the same scope and Erlang will be ok with it since you're not contradicting what you said earlier (Var = 2 + 2).
But what you can not do (in the same scope) is try to assert that Var has a different value: 'Var = 7' would throw an error.
{car, Type, Power} = Car.
indicates multiple bindings.
I called it a "binding" operator because Erlang doesn't really have "assignment" like imperative languages do. When you use = in Erlang, you're not telling the compiler what to do with some particular piece of memory, you're just telling it that "from now on, when I use X, I mean Y".
In this case Car has to be a tuple of 3 values, the literal 'car', and two other elements which will be then bound to Type and Power. So if Car was { car, "Coupe", 400 }, Type would be "Coupe" and Power would be 400. That statement would fail if Car were { foo, "Coupe", 400 }, since the assertion that the first element of the tuple is 'car' would fail.
This feature exists in some other languages, too, in more limited form. Lisp and Scheme have something called a "destructuring bind" which is like the example above. This is less powerful than Erlang's pattern matching, since it only "explodes" a list and nothing else. Prolog has full pattern matching, however, as Erlang's was inspired by Prolog.
Common Lisp has a destructuring bind which can pick apart a tree (represented as lists):
(destructuring-bind (a (b c)) '(1 (2 3) (format t "a:~a b:~a c:~a~&" a b c))
would print a:1 b:2 c:3
Scheme doesn't have one (as part of the standard library), but you could (obviously) write one. Scheme does have something which uses the Erlang style of destructuring that is part of it's syntax-rules system (http://www.xs4all.nl/~hipster/lib/scheme/gauche/define-syntax-primer.txt).
Tail recursion is a way to formulate a recursive function such that the function does not need to return to its parent caller to calculate the correct value. Its an optimization technique: using tail recursion allows the compiler to reuse the existing stack frame for the function call rather than having to create another one (as with regular recursive functions). This saves a lot of space and allows for indefinite recursion as your per-function space overhead is amortized to near zero on very deep recursions.
In order to really be able to use tail recursion, though, your compiler or language platform has to support it. Erlang supports it. C compilers do not, in general. I think Java does not support it, either.
Java definitely does not support tail call optimization. Newer gccs have a compiler flag for it. Most Lisps support it - and to be a 'real' Scheme the implementation must support it (the Scheme standard requires it of its implementations). Haskell and other FP languages also support it. Have a look at:
http://www-128.ibm.com/developerworks/linux/library/l-recurs.html?ca=dgr-lnxw02Recursion
which discusses tail recursion in Lisp(s) and C.
Kyle
Anything that can be expressed recursively, however, can also be expressed iteratively. Thus, if you're using a language/platform that does not support tail recursion, you can always drop back to the iterative form of the algorithm(s) when you might be recursing a lot of using multiple recursive functions concurrently.
> Thanks again for a very interesting presentation.
Doitashimashite (^_^) I was glad that you guys liked it :)
-- Toby DiPasquale
___________________________________________________________________________ Philadelphia Linux Users Group -- http://www.phillylinux.org Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce General Discussion -- http://lists.phillylinux.org/mailman/listinfo/plug