Prev: Is Matlab "libstruct" able to recognize the nested-C structure?
Next: Mex error directory invalid
From: Zaphod on 22 Apr 2010 22:43 Disclaimer: I don't use Matlab much, and have expectations formed from years of programming in other languages. Taking this into consideration, I think that Matlab does not correctly implement anonymous functions. To illustrate this point, consider the following code examples: python: f = lambda x: x + 1 f(1) javascript: f = function(x) { return x + 1; } f(1) matlab: f = @(x) x + 1 f(1) all of the above examples essentially do the same thing. the variable f is assigned to an anonymous function which increments its argument, then f is applied to the argument 1, and returns 2. however, consider these examples: python: (lambda x: x + 1)(1) ---> evaluates to 2 javascript: (function(x) {return x + 1;})(1) ---> evaluates to 2 matlab: (@(x) x + 1)(1) ----> syntax error, unbalanced or unexpected paren I think that (@(x) x + 1) should be evaluated first (the outer parens denoting order of operations) and return a value of type int->int, then that function should be applied to the argument 1. This behavior seems particularly inconsistent because the following matlab code works: f = @(x) @(y) x + y f(4) ----> evaluates to @(y) x + y The above example shows that at least in some sense, matlab is capable of evaluating an expression to a value with a function type. My contention is essentially that Matlab should handle this case in the same way as every other language (I gave examples in python and javascript, but I think that an analogous example can be made in AS3, C++ with Boost, SML and Haskell as well).
From: Doug Schwarz on 23 Apr 2010 00:35 In article <hqr1g9$t5p$1(a)fred.mathworks.com>, "Zaphod " <a3904429(a)owlpic.com> wrote: > Disclaimer: I don't use Matlab much, and have expectations formed from years > of programming in other languages. Taking this into consideration, I think > that Matlab does not correctly implement anonymous functions. > > To illustrate this point, consider the following code examples: > > python: > f = lambda x: x + 1 > f(1) > > javascript: > f = function(x) { return x + 1; } > f(1) > > matlab: > f = @(x) x + 1 > f(1) > > all of the above examples essentially do the same thing. the variable f is > assigned to an anonymous function which increments its argument, then f is > applied to the argument 1, and returns 2. however, consider these examples: > > python: > (lambda x: x + 1)(1) ---> evaluates to 2 > > javascript: > (function(x) {return x + 1;})(1) ---> evaluates to 2 > > matlab: > (@(x) x + 1)(1) ----> syntax error, unbalanced or unexpected paren > > I think that (@(x) x + 1) should be evaluated first (the outer parens > denoting order of operations) and return a value of type int->int, then that > function should be applied to the argument 1. This behavior seems > particularly inconsistent because the following matlab code works: > > f = @(x) @(y) x + y > f(4) ----> evaluates to @(y) x + y > > The above example shows that at least in some sense, matlab is capable of > evaluating an expression to a value with a function type. > > My contention is essentially that Matlab should handle this case in the same > way as every other language (I gave examples in python and javascript, but I > think that an analogous example can be made in AS3, C++ with Boost, SML and > Haskell as well). MATLAB's parser is limited, partly for historical reasons. It has never been possible to do something like f(4)(1) because of the ambiguity. Does it mean that f(4) is a function handle and then we want to pass 1 into that function or does it mean that f is a function, we pass 4 into that function, it returns a vector and then we index into the first element of that? Well, the parser doesn't know either. It could be defined, but it hasn't up till now. I know this isn't quite what you had in mind, but you can sort of do what you want with feval: feval(@(x)x+1,1) returns 2. -- Doug Schwarz dmschwarz&ieee,org Make obvious changes to get real email address.
From: Walter Roberson on 23 Apr 2010 01:14 Zaphod wrote: > Disclaimer: I don't use Matlab much, and have expectations formed from > years of programming in other languages. Taking this into consideration, > I think that Matlab does not correctly implement anonymous functions. > matlab: > (@(x) x + 1)(1) ----> syntax error, unbalanced or unexpected paren It is not a matter that Matlab does not correctly implement anonymous functions: it is a problem of backwards compatibility of code that Mathworks does not wish to break. In the languages you cite, python and javascript, in order to call a function, you must mention the function name and then provide a {possibly empty} argument list in order for the function to be called. In Matlab, due to long historical practice, at execution time, functions are called if they are mentioned by name (outside of a string) _unless_ they are proceeded by @, even if there is no argument list or () . For example, in matlab, Done = true; sets the variable named 'Done' to the logical true value, data class logical, numeric value 1. Looks simple and obvious enough, but it hides the fact that true is actually a function being called here with no arguments. Matlab doesn't special case this in any way, such as by immediately substituting the logical truth value upon recognizing that true is being called without any arguments: it just calls the function named 'true' and lets the function itself figure out that it was called with no arguments and lets the function decide what that means. It happens that for Matlab, all of the following are equivalent: Done = true; Done = true(); Done = true(1); Done = true(1,1); The numbers for the arguments are array sizes: true with no arguments or the empty argument constructs a 1 x 1 array of logical true values. If the programmer had instead coded Done = true(5,1); then that would set 'Done' to the column vector, 5 rows by 1 column, each with the logical true value. Now, because of this historical precedent and the amount of code that could end up broken if it were changed, Matlab simply disallows further indexing or invocation *of any kind* after a function call. You cannot, for example, in Matlab meaningfully write true(5,1)(2:4,1) to construct the 5 x 1 column vector of true values and then extract the 2nd, 3rd and 4th row of that anonymous column vector. There are lots of times when it would nice to be able to do something like that, but Matlab prohibits it. It isn't a "bug" in the handling of anonymous functions or of anonymous objects: it is simply part of the language definition. The reasons that have been sometimes stated by Mathworks employees as to why one cannot do further indexing or invocation is that apparently if they were to allow that, it would not be possible to differentiate between foo(2,4) meaning "call foo with no arguments and index the result at row 2 column 4" versus foo(2,4) meaning "call foo with the list of arguments 2 and then 4." With anonymous functions thrown in, there is also a third potential meaning: "call foo with no arguments and if it returns a function hsndle, call that function with the list of arguments 2 and then 4." My _personal_ view (as a user who happens to be delegated by my systems administrator as being eligible to submit bug reports myself without going through him, but who has no other closer contact to Mathworks), is that probably there is no _real_ conflict, if Mathworks were to simply require the call-with-no-arguments cases to supply the empty argument list, such as foo()(2,4) . After all, since that syntax is currently prohibited, there are no valid existing programs that can possibly use it, so enhancing the syntax by adding it as a possibility would not break any backwards compatibility. However, I understand that the Mathworks parser is.. ummm, not exactly modular, shall we say. Apparently there are some nasty context- dependencies in the interpretation of some expressions that make the parser tricky code. I think I could name a few of the more troublesome spots; the ones I am thinking of are mostly for backwards compatibility, but at least one of them is a nice syntactical sugar that people would likely begrudge having eliminated.
From: Bruno Luong on 23 Apr 2010 02:05 Doug Schwarz <see(a)sig.for.address.edu> wrote in message > > MATLAB's parser is limited, partly for historical reasons. It has never > been possible to do something like > > f(4)(1) > > because of the ambiguity. Does it mean that f(4) is a function handle > and then we want to pass 1 into that function or does it mean that f is > a function, we pass 4 into that function, it returns a vector and then > we index into the first element of that? Well, the parser doesn't know > either. It could be defined, but it hasn't up till now. > Sorry but I don't buy. Let's consider f(1)(4) Let's us try to do the same work as the more advanced parser. First we have to evaluate f(1) f(1) (4) -> g=f(1); g(4) Matlab currently are perfectly capable to determine what to do with g=f(1): if f is a non-scalar array : >> f={@(x) 1, @(x) 2} f = @(x)1 @(x)2 % if f is a single function handle >> f(1) ans = @(x)1 >> f=@(x) 1 f = @(x)1 >> f(1) ans = 1 Then it can go on as such for successive parenthesis. To me, there is no reason why Matlab parser won't be able to be extended to do cascade indexing. Bruno
From: Zaphod on 23 Apr 2010 02:18 Thanks for your responses... very detailed and interesting. It seems like a big part of this issue is maintaining backward compatibility, and not stepping on other syntax. This is a nitpick, but the reason I think it is dubious to refer to them as "anonymous" is that in every use case I can think of except for feval / arrayfun, a function must have a name before it is called (i.e. even when you pass an "annon" function as an argument to another function, it is given an name in the scope of the function being called before it can ever be used). I will admit however that I can't think of a practical use for fail case I showed. As such my gripe here isn't that missing this functionality is a big inconvenience, but that it is inconsistent with other languages (many of which are quite consistent in how this is handled) as well as somewhat internally inconsistent (i.e. with the fact that you can return anonymous functions as values, and the fact that parens normally denote order of evaluation).
|
Next
|
Last
Pages: 1 2 3 4 Prev: Is Matlab "libstruct" able to recognize the nested-C structure? Next: Mex error directory invalid |