Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
it is not possible to apply an anonymous function

Subject: it is not possible to apply an anonymous function

From: Zaphod

Date: 23 Apr, 2010 02:43:21

Message: 1 of 25

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

Subject: it is not possible to apply an anonymous function

From: Doug Schwarz

Date: 23 Apr, 2010 04:35:53

Message: 2 of 25

In article <hqr1g9$t5p$1@fred.mathworks.com>,
 "Zaphod " <a3904429@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.

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 23 Apr, 2010 05:14:34

Message: 3 of 25

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.

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 23 Apr, 2010 06:05:23

Message: 4 of 25

Doug Schwarz <see@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

Subject: it is not possible to apply an anonymous function

From: Zaphod

Date: 23 Apr, 2010 06:18:09

Message: 5 of 25

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

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 23 Apr, 2010 06:19:08

Message: 6 of 25

"Zaphod " <a3904429@owlpic.com> wrote in message <hqr1g9$t5p$1@fred.mathworks.com>...
>
> My contention is essentially that Matlab should handle this case in the same way as every other language.

Agreed, this is due to the lack of support for cascading of indexing/evaluation, not only for anonymous functions but for generic functions/arrays.

Bruno

Subject: it is not possible to apply an anonymous function

From: us

Date: 23 Apr, 2010 06:51:05

Message: 7 of 25

"Zaphod " <a3904429@owlpic.com> wrote in message <hqr1g9$t5p$1@fred.mathworks.com>...
> 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.

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

i'm glad it's the way it is - and - i hope it will never change...

us

Subject: it is not possible to apply an anonymous function

From: Steve Eddins

Date: 23 Apr, 2010 13:42:17

Message: 8 of 25

On 4/23/2010 2:18 AM, Zaphod wrote:
> 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).

Hmm. You exclude feval, the documented way to call a function handle
without assigning it to a variable first, and then you complain that you
can't call a function handle without assigning it to a variable first.

:-)

Also, you seem to imply that defining a named function and assigning a
value to a variable (which has a name) are the same thing. They're not.

---
Steve Eddins
http://blogs.mathworks.com/steve/

Subject: it is not possible to apply an anonymous function

From: Doug Schwarz

Date: 23 Apr, 2010 13:57:20

Message: 9 of 25

Bruno Luong wrote:
> Doug Schwarz <see@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)

[snip]

> To me, there is no reason why Matlab parser won't be able to be extended
> to do cascade indexing.
>
> Bruno

Hi Bruno,

I pretty much agree with you -- TMW could implement it. As Walter
explained (better than I did) there are inherent ambiguities, but as
long as TMW defined how they behave they could do it.

The problem as I see it (and this is just my opinion) is that they (TMW)
might feel that such a syntax would be confusing, especially to a new
user. For example, what is the meaning of

   x = f(1)

if f is function that can take an argument or, optionally, require no
arguments. Does it mean

   temp = f;
   x = temp(1);

or does it mean to pass the 1 as the argument of f? If the latter then
how do you do the former? Of course,

   x = f()(1)

could work, but right now it is not necessary to use the empty
parentheses (indeed, it used to be a syntax error). I'm pretty sure TMW
doesn't want to *require* empty parentheses because then, to use
Walter's example, the use of true() or pi() become less intuitive.

Anyway, it's not that these issues couldn't be resolved, there just may
be non-technical reasons why they have not been.

--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.

Subject: it is not possible to apply an anonymous function

From: Doug Schwarz

Date: 23 Apr, 2010 13:58:53

Message: 10 of 25

Bruno Luong wrote:
> Doug Schwarz <see@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)

[snip]

> To me, there is no reason why Matlab parser won't be able to be extended
> to do cascade indexing.
>
> Bruno

Hi Bruno,

I pretty much agree with you -- TMW could implement it. As Walter
explained (better than I did) there are inherent ambiguities, but as
long as TMW defined how they behave they could do it.

The problem as I see it (and this is just my opinion) is that they (TMW)
might feel that such a syntax would be confusing, especially to a new
user. For example, what is the meaning of

   x = f(1)

if f is function that can take an argument or, optionally, require no
arguments. Does it mean

   temp = f;
   x = temp(1);

or does it mean to pass the 1 as the argument of f? If the latter then
how do you do the former? Of course,

   x = f()(1)

could work, but right now it is not necessary to use the empty
parentheses (indeed, it used to be a syntax error). I'm pretty sure TMW
doesn't want to *require* empty parentheses because then, to use
Walter's example, the use of true() or pi() become less intuitive.

Anyway, it's not that these issues couldn't be resolved, there just may
be non-technical reasons why they have not been.

--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 23 Apr, 2010 15:54:33

Message: 11 of 25

Zaphod wrote:
> 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).

Both parts of your gripe are mistaken.

Let us start with the second one first: what-ever other use the language
might have for them, () are used to denote argument lists to functions
in computer languages such as Fortran, LISP, BASIC, C, C++, perl, Maple,
  SNOBOL, m4, ALGOL -- need I go on? Algol 68 was one of the first
languages to treat procedures as first-class objects; it was also
considered for a number of years to be too complex for it to be
theoretically possible to build a parser for.

The first half of first gripe, that it is inconsistent with other
languages is trivially correct, but so what? The way python does it is
inconsistent with the way that Algol 68 does it, but do you see gripes
that python should be redesigned to be consistent with venerable
languages such as Algol 68?


The second half of your first gripe, that "many of which are quite
consistent in how this is handled" reflects a lack of experience and
reflection in the "use-mention" inconsistencies in most computer
languages. Every computer language that permits assignments of the form

name1 = name2
or
name1 := name2
or the like

where the names on the left and right side are not required to be in
syntactically different classes, suffers from use-mention
inconsistencies. The name being assigned to is being "mentioned" (the
value that is already stored there is not being used), whereas the name
being assigned from is being "used" (the value associated with the name
is being looked up and copied into the storage associated with the other
name). If there is no syntactical differentiation that a name is only
being mentioned instead of used (or, equivalently, that a name is being
used instead of being mentioned), then the programming language is
inconsistent.

In order to be consistent, after

name1 = name2

then any mention of name1 would have to be equivalent to a mention of
name2, even tracking through value changes to name2.

Now let name2 be an anonymous procedure whose _value_ (as an anonymous
procedure) has become the "use" of name2 . Then if you expect that
name1(argument) will invoke the anonymous procedure with the given
argument, you are expecting that the _mention_ of name1 will be
transformed into a _use_ of the anonymous procedure. And that requires
that the language knows *at run time* that the value associated with
name1 be examined and if it is an anonymous procedure than that
procedure is to be invoked, but if it is not an anonymous procedure than
the binding scope should be examined checking for a -non- anonymous
procedure with name 'name1' and invoke that. The anonymous procedure
case then becomes an active "use" of the value associated with 'name1',
but the non-anonymous case involves the "mention" of name1 up through
the binding hierarchy until something with the same _name_ is found.
Inconsistencies!! -- just ones you don't normally think about.


Oh, and by the way, if parens denote order of operations, then why is it
that the order of evaluation is unspecified for tuples in python, which
are a parenthesized notation ?
http://docs.python.org/reference/expressions.html#parenthesized-forms
Whereas the order is specified for "list displays",
"When a comma-separated list of expressions is supplied, its elements
are evaluated from left to right and placed into the list object in that
order." Isn't that a bit backwards from what you were saying, in that
brackets in the python language impose an order of evaluation, but
parens do not?

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 23 Apr, 2010 16:09:55

Message: 12 of 25

Doug Schwarz wrote:
> I'm pretty sure TMW
> doesn't want to *require* empty parentheses because then, to use
> Walter's example, the use of true() or pi() become less intuitive.

It would work out if the () could be omitted if the user did not code
further indexing of the returned object after the function name.

For example,

name{index} --> requires name to be a named cell array

name(){index} --> name is a function that is called with no arguments
and the resulting anonymous object is then indexed


An interesting case to consider is if the user used () around the name:

(name){index} --> is this the same as (name()){index} or as name{index} ?

At the moment, it is possible for this constuct to appear as a
subexpresison of code:

structname.(name){index}

To keep compatibility with this form, it would make the most sense for
(name) where name is a named function or the name of a function handle,
to continue to invoke the referenced function with no arguments. Thus

(colormap)(5)

would make sense as (colormap())(5) rather than as denoting colormap(5)

Subject: it is not possible to apply an anonymous function

From: Zaphod

Date: 23 Apr, 2010 22:55:21

Message: 13 of 25

Steve Eddins wrote:
------------------------
> exclude feval, the documented way to call a function handle 
without assigning it to a variable first, and then you complain that you 
can't call a function handle without assigning it to a variable first.

You have a fair point here. As I mentioned, my gripe is that it is syntactically inconsistent, not that the missing functionality is useful.


Walter Roberson wrote:
-----------------------------

> Both parts of your gripe are mistaken.

Nuh uh.. your a poopy head.

> Let us start with the second one first: what-ever other use the language
> might have for them, () are used to denote argument lists to functions
> in computer languages such as Fortran, LISP, BASIC, C, C++, perl, Maple,
> SNOBOL, m4, ALGOL -- need I go on? Algol 68 was one of the first
> languages to treat procedures as first-class objects; it was also
> considered for a number of years to be too complex for it to be
> theoretically possible to build a parser for.

It doesn't matter that () denotes function calls in these languages. It also denotes order of evaluation. As long as it is unambiguous, there should be no problem. Too complex to parse? Are you kidding? Parsing has been a solved problem in computer science for 20+ years. All you have to do is specify an unambiguous grammar and programs like lex and yacc automatically compile a parser and lexer. "It's too difficult to parse" is not a valid excuse for any competent computer scientist in 2010. Implementing a parser that can deal with this is undergraduate coursework nowadays.

>
> The first half of first gripe, that it is inconsistent with other
> languages is trivially correct, but so what? The way python does it is
> inconsistent with the way that Algol 68 does it, but do you see gripes
> that python should be redesigned to be consistent with venerable
> languages such as Algol 68?

You haven't actually shown an example in Algol 68 of how this would be handled differently. Furthermore, Algol 68 is archaic, whereas all of the examples I gave are modern languages in common use. My example works the same in C++, AS3, JavaScript, Python, SML, OCML, Haskell, and probably many others. Matlab is the only widely used modern language that claims to support anonymous functions, but does not handle this case consistently. If you can give a single example of a modern language other than Matlab where this doesn't hold, I would be prepared to consider that as a valid point.

> The second half of your first gripe, that "many of which are quite
> consistent in how this is handled" reflects a lack of experience and
> reflection in the "use-mention" inconsistencies in most computer
> languages. Every computer language that permits assignments of the form

First, your comments about 'use-mention' are totally irrelevant to the matter at hand. The fact that you are babbling about 'use-mention' indicates that you have missed the whole point of this discussion, which is applying a function without first naming it!

Second, it is a fact that most other languages handle this case consistently. Here are a few more examples:

Standard ML:
(fn x => x + 1)(2) ---> evaluates to 3

ActionScript 3 (i.e. Flash):
trace(function(x){return x+1;}(2)); ----> prints 3

Third, I do not lack experience or reflection. I have written compilers that support this case.

> Now let name2 be an anonymous procedure whose _value_ (as an anonymous 
> procedure) has become the "use" of name2 .

If you are naming a function 'name2', it is not anonymous (by definition). In the example I showed, I tried to apply a truly anonymous function, i.e. one that never has a name. There is a difference between an anonymous function (one that has no name), a value with type function, and a lambda-expression. A lambda-expression is part of the abstract syntax of a language, and evaluates to a value of type function. That value is anonymous if it does not have a name.

> And that requires 
> that the language knows *at run time* that the value associated with 
> name1 be examined and if it is an anonymous procedure

As I understand it, Matlab does a whole bunch of type checking at runtime to figure out how to apply a function.
Compilers are perfectly capable of figuring this stuff out at compile time, and have been for over 20 years (see 'The Implementation of Functional Programming Languages,' Simon Peyton Jones, 1987). Its called "static type inference." There are pros and cons to static vs. dynamic languages. As I understand it, Matlab is dynamic. Both static and dynamic languages are able to apply anonymous functions (SML is static, Python is dynamic).

> Oh, and by the way, if parens denote order of operations, then why is it
> that the order of evaluation is unspecified for tuples in python, which
> are a parenthesized notation ?
> http://docs.python.org/reference/expressions.html#parenthesized-forms
> Whereas the order is specified for "list displays",
> "When a comma-separated list of expressions is supplied, its elements
> are evaluated from left to right and placed into the list object in that
> order." Isn't that a bit backwards from what you were saying, in that
> brackets in the python language impose an order of evaluation, but
> parens do not?

In python you can write:

x = ((1+2)*3, 1)

after which x has the tuple value (9, 1). Python has no problem resolving ambiguity between parens for tuples, order of evaluation, and function calls, and handles them in a perfectly consistent way.

I think the point you are trying to make is that python's spec does not guarantee an order in which the elements of the tuple will be evaluated. The only case where this matters is if you are trying to create a tuple with values that are returned from functions with side-effects. For example:

def foo():
print "foo"
return 1

def bar():
print "bar"
return 2

x = (foo(), bar())

In this example, x will have the value (1,2), but the python spec is saying that there is no guarantee that it will print "foo" then "bar" instead of the other way around. In practice however, python 2.6 will actually output "foo" "bar", so evaluation order works the same as lists. The python spec does however say that if you did this:

x = [foo(), bar()]

it would output "foo" then "bar".

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 24 Apr, 2010 01:30:31

Message: 14 of 25

Zaphod wrote:
>> Algol 68 was one of
>> the first languages to treat procedures as first-class objects; it was
>> also considered for a number of years to be too complex for it to be
>> theoretically possible to build a parser for.

> It doesn't matter that () denotes function calls in these languages. It
> also denotes order of evaluation. As long as it is unambiguous, there
> should be no problem.

Then what is your complaint about Matlab's use of () ? Matlab's () denote
order of execution to pretty much the same extent that C's () denote order of
execution (Fortran is stricter.) A procedure call using () to denote the
argument list is *not* a matter of order of execution.

> Too complex to parse? Are you kidding? Parsing has
> been a solved problem in computer science for 20+ years. All you have to
> do is specify an unambiguous grammar and programs like lex and yacc
> automatically compile a parser and lexer. "It's too difficult to parse"
> is not a valid excuse for any competent computer scientist in 2010.
> Implementing a parser that can deal with this is undergraduate
> coursework nowadays.

"Those who do not study history are doomed to repeat it."

Amongst the authors of Algol 68 were Wirth and Hoar: they ensured that formal
definitions of everything were done, to the extent possible. However, the
generality of Algol 68 did not always make it possible: according to one of
the four major authors of Algol 68 (Koster,
http://www.cs.ru.nl/~kees/home/papers/psi96.pdf ), Algol 68 had, "infinite
productions (such as ALEPH), infinite modes (caused by recursive
type declarations) and an infinite number of Context-Free production rules.".
And when you have an infinite number of context-free production rules, you
cannot use lex and yacc, which depend upon there being a finite and
pre-defined set of production rules. I understand that in particular it was
impossible to create a formal definition for transputing (what we would now
call I/O operators, both formatted and unformatted.) In Koster's report,
notice the portion at the end of section 3 in which it is indicated that the
implementation of transputing led the authors of Algol 68 to include
identifiers with an infinite number (aleph-naught) of leading 'f' characters.
How, pray tell, would you implement that in lex? I have never heard of a
version of lex that permitted more than 2^63-1 characters per identifier. By
the way, were you aware that space characters are allowed characters in Algol
68 identifiers?


> You haven't actually shown an example in Algol 68 of how this would be
> handled differently.

Frank G. Pagan, "A Practical Guide to Algol 68", John Wiley and Sons, 1796,
section 5.2.1 "Procedures without parameters", page 100

   "The following phrase is an identity declaration for a simple procedure
with the identifyer xyz:

   proc void xyz = void: (x := 1; y := 2; z := 3)

   This is analogous to other identity declarations, and the right side could
be any unit yielding a routine of mode proc void, such as a previously
declared proci void identifier."

[In other words, the subsection void: (x := 1; y := 2; z := 3) is an anonymous
procedure.]

Page 101:

   "The trivial but valid program

   (int x, y, z;
   proc xyz = void: (x := 1; y := 2; z := 3);
   xyz; xyz; xyz )

   contains three invocations of xyz [...]

   At each invocation, xyz (mode proc void) is in effect converted to a void
value; it is said to undergo the coercion of DEPROCEDURING."

Notice the lack of () or any other indication that xyz is being used rather
than being mentioned. Indeed, in order to mention xyz instead of use it, Algol
68 required the addition of the reserved word ref in front of the item being
mentioned.

> Furthermore, Algol 68 is archaic, whereas all of
> the examples I gave are modern languages in common use.

Your posting said, and I quote,

"my gripe here isn't that missing this functionality is a big inconvenience,
but that it is inconsistent with other languages"

You did not, in your gripe, restrict yourself to "modern languages in common
use". Did you think that Fortran is not a "modern language in common use" ?
Fortran had a revision report in 2008, C had technical corrections to the
standard in 2004 ("TC3") and started the standards revision cycle in 2007;
perl is redefined every month or so (the implementation of perl is defined as
being the Standard for perl); Maple is a 2009 release and there are solid
rumours of a 2009 release; LISP had a very active 50th anniversary in 2008,
and its close descendant Scheme had a new standards release in 2008.

> My example works
> the same in C++, AS3, JavaScript, Python, SML, OCML, Haskell, and
> probably many others. Matlab is the only widely used modern language
> that claims to support anonymous functions, but does not handle this
> case consistently. If you can give a single example of a modern language
> other than Matlab where this doesn't hold, I would be prepared to
> consider that as a valid point.

Right. And if I point one out, you'll say it is not "modern" or "widely used".

MATLAB has never claimed more than limited support for anonymous functions.
For example, anonymous functions in MATLAB cannot do assignments (other than
via 'eval' or equivalent', cannot have conditional statements in which the
unselected condition is not elaborated, cannot contain compound statements.
cannot return multiple values. They are not, in fact, anonymous functions at
all, not even in the mathematical sense of the word 'function': they are
anonymous _expressions_


> First, your comments about 'use-mention' are totally irrelevant to the
> matter at hand. The fact that you are babbling about 'use-mention'
> indicates that you have missed the whole point of this discussion, which
> is applying a function without first naming it!

I missed nothing. You, on the other hand, missed the fact that you are being
hypocritical in your criticisms of inconsistencies, complaining bitterly over
a programming language that "grew" over more than 20 years from being a pure
matrix calculator as not having fully-refined function semantics. Well, your
cited languages such as python and C++ are also inconsistent in how they treat
  anonymous functions; the inconsistencies becomes most apparent when you
examine the bindings between names and values, but they can be found in other
places as well, such as the behaviour when multiple anonymous procedures are
generated and it is necessary to decide whether the adjacent action being
denoted is selection (the generalization of indexing), or tuple-building, or
attaching a context to the anonymous functions, or building an argument list
that is to be followed by an invocation of the anonymous functions -- and is
each of the anonymous function multiple to be invoked with the same set of
arguments after a single elaboration of the arguments, or are the arguments to
be elaborated once per anonymous function prior to the function call...

> As I understand it, Matlab does a whole bunch of type checking at
> runtime to figure out how to apply a function.
> Compilers are perfectly capable of figuring this stuff out at compile
> time, and have been for over 20 years (see 'The Implementation of
> Functional Programming Languages,' Simon Peyton Jones, 1987). Its called
> "static type inference." There are pros and cons to static vs. dynamic
> languages. As I understand it, Matlab is dynamic.

Not really, no. Matlab scripts are always dynamic. Matlab functions which
terminate in an 'end' statement are potentially closures. Matlab functions
which do not terminate in an 'end' statement (which can only be determined by
scanning the entire file to find out if the number of 'end' statements matches
the number of function declarations, as nested function definitions are
supported) are not closures. Matlab functions, whether closures or nested or
not, are subject to "Just In Time" compilation (with undefined scope of what
is translated when), with the known behaviour that if there is no direct
assignment to a name within a scope, and the name is a known function outside
of the scope (with a semi-dynamic first-found path search), then the name will
be considered to be a reference to the function and references to the name
that could potentially be function references are treated _as_ function
references in that unit -- even if at run time, one of the dynamic mechanisms
for creating variables "poofs" the same name into existence. The result *is*
inconsistencies of behaviour. The perils of interpreted languages that are
allowed to generate variable names.


> I think the point you are trying to make is that python's spec does not
> guarantee an order in which the elements of the tuple will be evaluated.

You took such pains to claim that parens denote order of execution, and yet in
your favorite example language, they do not!


Your gripes are a mish-mash of inconsistent ideas. You blame a language for
not being as you expect, and compare it to nameless "other computer languages"
and then reject it when I point out the long history of other computer
languages having the same behaviour. You blame a language for being
inconsistent with respect to certain functionality, and yet are unable to see
the inconsistencies in your chosen reference languages. You treat a complex
language that you do not know as being "archaic" and only worthy of attention
at the undergrad level, when in fact it was the only language jointly designed
by the founding fathers of strict formalism in computer languages, and takes
such extremes of consistency and flexibility that it in practice embeds an
extensive and extensible programming language of *types*, and as such cannot
be analyzed by any static set of production rules such as are embodied by lex
and yacc.

You have create compilers; did you study denotational semantics? Did you
pursue denotational semantics far enough to recognize that it is not able to
finitely represent all of mathematics (not even the mathematics of integers),
and thus that there will always be programs that *cannot* be represented with
*any* finite and consistent system of strong semantics (which other branches
would call "axioms")? Goedel's Incompleteness Theorems applies to computer
languages too -- and the only answer, if we wish to be able to reason in such
areas, is for us to accept inconsistencies in our computing languages.

Subject: it is not possible to apply an anonymous function

From: Zaphod

Date: 24 Apr, 2010 04:36:04

Message: 15 of 25

Walter Roberson <roberson@hushmail.com> wrote in message <hqthjq$96d$1@canopus.cc.umanitoba.ca>...
> Zaphod wrote:
> >> Algol 68 was one of
> >> the first languages to treat procedures as first-class objects; it was
> >> also considered for a number of years to be too complex for it to be
> >> theoretically possible to build a parser for.
>
> > It doesn't matter that () denotes function calls in these languages. It
> > also denotes order of evaluation. As long as it is unambiguous, there
> > should be no problem.
>
> Then what is your complaint about Matlab's use of () ? Matlab's () denote
> order of execution to pretty much the same extent that C's () denote order of
> execution (Fortran is stricter.) A procedure call using () to denote the
> argument list is *not* a matter of order of execution.

I said parens can denote several things in a language, namely order, invocation, tuples, etc. The key point here is that in this expression:

(@(x) x + 1)(2)

the reasonable result is 3, whereas in Matlab it is a syntax error. Also, it is not true that Matlab's parens denote order to the same extent as C. In C, you could write (slightly abbrevd):

void foo() {}

void main()
{
    void* f = (void*)foo;
    (f)();
}

In this case, the parens in (f) will be used for order of operation. The expression evaluates to a function pointer, which is then be applied. In Matlab, whether parens mean order of operation or syntax error (in cases where they unambiguously do not mean anything else), depends on if the enclosed expression is a function or not. That is the inconsistency.


I will admit that I don't know enough about Matlab to say that this is a completely unambiguous case. If you want to argue that I am wrong, this would be the place to make your point.


> "Those who do not study history are doomed to repeat it."

Right... the authors of Matlab didn't study the history of languages such as Algol, and thus repeated the mistake of defining a language that cannot be described with a context free grammar (or made a language that can be described with a CFG, but implemented an ad-hoc parser). Algol gained something in generality and power through its complex syntax. In the case I am pointing out, it is not clear that Matlab gains anything by failing to support this syntax.

> > You haven't actually shown an example in Algol 68 of how this would be
> > handled differently.
>
> (int x, y, z;
> proc xyz = void: (x := 1; y := 2; z := 3);
> xyz; xyz; xyz )

The example you give does not illustrate an attempt to apply an anonymous function, which is what all of my examples are about. In your example, the expression "void: (x := 1; y := 2; z := 3)" is assigned to the name xyz before it is applied. The fact that you don't need parens to indicate the application is irrelevant. I downloaded the Algol 68 Genie Mark 15.1 compiler (released January 2009) and attempted to run your example. It doesn't even compile. Here is an example in algol 68 that does compile, and illustrates that Algol 68 handles order of evaluation in the same way as every other language I gave as an example:

main: ( printf($"Hello World!"l$) )
---> prints "Hello World"

main: ( (printf)($"Hello World!"l$) )
---> not a syntax error, still prints "Hello World"

Algol 68 actually supports my perspective, not yours.

> > Furthermore, Algol 68 is archaic, whereas all of
> > the examples I gave are modern languages in common use.
>
> Your posting said, and I quote,
>
> "my gripe here isn't that missing this functionality is a big inconvenience,
> but that it is inconsistent with other languages"
>
> You did not, in your gripe, restrict yourself to "modern languages in common
> use". Did you think that Fortran is not a "modern language in common use" ?

I am aware that Fortan is still widely used. I don't know if it supports anonymous functions though. If it does, it would be interesting to know how it handles this case.

> Fortran had a revision report in 2008, C had technical corrections to the
> standard in 2004 ("TC3") and started the standards revision cycle in 2007;
> perl is redefined every month or so (the implementation of perl is defined as
> being the Standard for perl); Maple is a 2009 release and there are solid
> rumours of a 2009 release; LISP had a very active 50th anniversary in 2008,
> and its close descendant Scheme had a new standards release in 2008.
>

Is this your list of modern languages? Every one of them (with the possible exception of Maple, which I don't know about) would handle the case I am suggesting in the way I say should be expected. I have already illustrated this for JavaScript, AS3, Python, SML, C and Algol 68. Here's is yet another example, this time in Scheme:

((lambda (x) (+ x 1)) 2)
--> evaluates to 3

>
> Right. And if I point one out, you'll say it is not "modern" or "widely used".
>

I gave examples in 7 languages... you have given 0 legit examples (as your example of Algol 68 actually illustrates my point).


> > First, your comments about 'use-mention' are totally irrelevant to the
> > matter at hand.

The matter at hand is *applying an anonymous function*. Your comments about 'use-mention' are barely related. Demonstrating that other languages have inconsistencies isn't the point.

> Well, your cited languages such as python and C++ are also inconsistent in how they treat
> anonymous functions; the inconsistencies becomes most apparent when you
> examine the bindings between names and values

Yes, there are inconsistencies in other languages. Does this mean we cannot point out inconsistencies in Matlab? Pointing out flaws like this might lead to a better language. If you find these problems in other languages to be a grievance, bring it up in the appropriate forum (as I did here).


>
> > I think the point you are trying to make is that python's spec does not
> > guarantee an order in which the elements of the tuple will be evaluated.
>
> You took such pains to claim that parens denote order of execution, and yet in
> your favorite example language, they do not!
>

I said parens can denote order of evaluation, function application or tuples, and that in Python, the meaning is not ambiguous. You tried to represent an inconsequential footnote in Python's spec as though it were somehow a major inconsistency. As I showed in my examples, it is not. Even if you had successfully demonstrated an inconsistency in python, it would still boil down to an argument of 'don't criticize matlab because python is inconsistent also'. I never said other languages are perfectly consistent. I said that most languages are consistent in how they handle this particular case (applying an anonymous function), but Matlab isn't.

Also, C++ is my favorite.

>
> Your gripes are a mish-mash of inconsistent ideas. You blame a language for
> not being as you expect, and compare it to nameless "other computer languages"

I have given specific examples of how this case is handled consistently by C, JavaScript, Scheme, SML, Python, AS3 and Algol 68. These are not "nameless".


> and then reject it when I point out the long history of other computer
> languages having the same behaviour.

You pointed out one language that is ancient, not widely used, and gave a bogus example that actually illustrates my point and contradicts yours.

> You blame a language for being
> inconsistent with respect to certain functionality, and yet are unable to see
> the inconsistencies in your chosen reference languages.

I never said other languages were consistent in every way. I said that they are consistent in handling the case of applying an anonymous function.

 >You treat a complex
> language that you do not know as being "archaic"

You are saying Algol 68 is not archaic? The 68 stands for 1968.
I looked for lists of most used programming languages and couldn't even find one listing Algol.
http://www.devtopics.com/most-popular-programming-languages/
http://langpop.com/

> and only worthy of attention
> at the undergrad level,

I said that writing a parser that handles this case is undergraduate coursework. I did not say the study of programming languages was.

> when in fact it was the only language jointly designed
> by the founding fathers of strict formalism in computer languages, and takes
> such extremes of consistency and flexibility that it in practice embeds an
> extensive and extensible programming language of *types*, and as such cannot
> be analyzed by any static set of production rules such as are embodied by lex
> and yacc.
>
> You have create compilers; did you study denotational semantics? Did you
> pursue denotational semantics far enough to recognize that it is not able to
> finitely represent all of mathematics (not even the mathematics of integers),
> and thus that there will always be programs that *cannot* be represented with
> *any* finite and consistent system of strong semantics (which other branches
> would call "axioms")? Goedel's Incompleteness Theorems applies to computer
> languages too -- and the only answer, if we wish to be able to reason in such
> areas, is for us to accept inconsistencies in our computing languages.

You are misinterpreting Goedel's theorem in the context of programming languages. What Goedel's theorem says about languages is that there exist languages such that deciding if a string belongs to that language is not computable. The take-home message as it applies to programming language design is not that one must accept inconsistency, but that one should avoid designing languages that cannot be parsed.

Subject: it is not possible to apply an anonymous function

From: Zaphod

Date: 24 Apr, 2010 17:56:14

Message: 16 of 25

To be more correct, Goedel's theorem doesn't say anything about languages. It is about Peano arithmetic. However, the result I stated is the most closely analogous incompleteness result for languages.

Subject: it is not possible to apply an anonymous function

From: Neville Dempsey

Date: 25 Apr, 2010 02:25:30

Message: 17 of 25

On Apr 24, 2:36 pm, "Zaphod " <a3904...@owlpic.com> wrote:
> Walter Roberson <rober...@hushmail.com> wrote in message <hqthjq$96...@canopus.cc.umanitoba.ca>...
>
> You are saying Algol 68is not archaic? The 68 stands for 1968.
> I looked for lists of most used programming languages and couldn't even find one listing Algol.
http://www.devtopics.com/most-popular-programming-languages/
http://langpop.com/

I checked langpop, and the site does not specifically check for
Algol68 so it is probably a red herring. Indeed if you do the google
search, then Algol68 outranks several of the languages that are
listed.

Algol 68 appears on rosettacode, but that is - possibly - only because
it has a dedicated fan there... namely "yours truly!"
http://rosettacode.org/wiki/Sort_most_popular_programming_languages

Re: "Python has no problem resolving ambiguity between parens for
tuples, order of evaluation, and function calls, and handles them in a
perfectly consistent way. "

- - - - SNIP: 8>< - - - - - - - - - - - - - - -
$ cat lists.py
lists=(1,2,3),[4,5,6],"789",xrange(10,13)
for this_list in lists:
  try:
    print tuple(this_list),
    print "%r,%r,%r"%this_list
  except TypeError, type_error:
    print type_error,"%r"%this_list

- - - - snip: 8>< - - - - - - - - - - - - - - -
$ python lists.py
(1, 2, 3) 1,2,3
(4, 5, 6) not enough arguments for format string [4, 5, 6]
('7', '8', '9') not enough arguments for format string '789'
(10, 11, 12) not enough arguments for format string xrange(10, 13)

- - - - SNIP: 8>< - - - - - - - - - - - - - - -
Algol68 has some syntactic inconsistencies. eg:
$ cat case_ambig.a68
CASE 1 IN print("OK") ESAC;
( 1 | print("Ambig") )

- - - - snip: 8>< - - - - - - - - - - - - - - -
$ a68g case_ambig.a68
2 ( 1 | print("Ambig") )
a68g: error: INT cannot be coerced to BOOL in a meek-enquiry-clause
(detected in conditional-clause starting at "(" in this line).

And - I am sure - a few others. Algol 68 - as defined in the standard
- does have restricted

My pet python syntax error is:
- - - - SNIP: 8>< - - - - - - - - - - - - - - -
$ cat bool_ambig.py
if True == not False: print "?"

- - - - snip: 8>< - - - - - - - - - - - - - - -
$ python bool_ambig.py
  File "bool_ambig.py", line 1
    if True == not False: print "?"
                 ^
SyntaxError: invalid syntax
c.f. http://docs.python.org/library/stdtypes.html#boolean-operations-and-or-not

Apparently this is entirely logical.

It all reminds me a little of "Gödel's first incompleteness theorem"
which can be stated as:
> Any effectively generated theory capable of expressing elementary arithmetic cannot be both consistent and complete. In particular, for any consistent, effectively generated formal theory that proves certain basic arithmetic truths, there is an arithmetical statement that is true, but not provable in the theory (Kleene 1967, p. 250).
c.f. http://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems#First_incompleteness_theorem

Njoy
NevilleDNZ
--
To download Linux's Algol68 Compiler, Interpreter & Runtime:
* http://sourceforge.net/projects/algol68

Subject: it is not possible to apply an anonymous function

From: Neville Dempsey

Date: 25 Apr, 2010 03:27:16

Message: 18 of 25

On Apr 25, 12:25 pm, Neville Dempsey <neville...@gmail.com> wrote:

> And - I am sure - a few others.  Algol 68- as defined in the standard
> - does have restricted

Should read:
 "And - I am sure - a few others. Algol 68- as defined in the
standard - does have restrictive scoping rules for procedures and
formats"
c.f. http://www.cs.ru.nl/~kees/home/papers/psi96.pdf
It also talks about first class functions.

N

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 25 Apr, 2010 20:11:26

Message: 19 of 25

Zaphod wrote:

> I said parens can denote several things in a language, namely order,
> invocation, tuples, etc.

You are changing your story after the facts. Need I go back and
explicitly quote your postings about what you said when?

> The key point here is that in this expression:
>
> (@(x) x + 1)(2)
>
> the reasonable result is 3, whereas in Matlab it is a syntax error.

Is _that_ all we are discussing, a bit of syntactic sugar?

Apply = @(f,x) f(x);

Apply(@(x) x + 1, 2)


> Also, it is not true that Matlab's parens denote order to the same
> extent as C. In C, you could write (slightly abbrevd):
>
> void foo() {}
>
> void main() {
> void* f = (void*)foo;
> (f)();
> }

 > In this case, the parens in (f) will be used for order of operation.
 > The expression evaluates to a function pointer, which is then be
 > applied.

$ cat foo.c
void foo() {}

void main() {
    void* f = (void*)foo;
    (f)();
}

$ make foo
cc foo.c -o foo
foo.c: In function 'main':
foo.c:5: error: called object 'f' is not a function
foo.c:3: warning: return type of 'main' is not 'int'
make: *** [foo] Error 1

http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
Section 6.9.1 Function Declarations
Paragraph 14 (PDF page 155, document page 143)

   EXAMPLE 2 To pass one function to another,one might say
     int f(void);
     /*... */
     g(f);
   Then the definition of g might read
     void g(int (*funcp)(void))
     {
      /*... */
      (*funcp)(); /*or funcp(); ... */
     }
   or,equivalently,
     void g(int func(void))
     {
      /* ... */
      func(); /* or (*func)(); ... */
     }


Thus in your example, the call can either be written as f() or as (*f)()
. The (*f)() form _does_ involve order of operations, in that function
calls have a higher precedence than dereferencing, so a sequence written
as *f() would mean to call f with no parameters and then to dereference
the result. There is no reason in C why (f)() cannot be written: it is
just redundant, since the normal order of operations would be to
evaluate the function pointer f first anyhow before making the call.

I note, by the way, that despite your earlier protestations about names,
you resorted to binding the function pointer to a name in order to use it...

Your code for the declaration of the function pointer is quite wrong for
C. In C, your code coherces foo into a generic void* pointer named f. In
C, void* pointers can only be copied and not operated upon; it would be
necessary to coherce the void* pointer into a function pointer before it
could be applied. Unfortunately for your purposes, in C, it is a
constraint violation to coherce a function pointer to a void pointer.
Section 6.2.3.2 (pdf page 59). Paragraph 1 allows conversion between
void* and any _object type_ -- but functions are not objects. Paragraph
8 (pdf page 60) allows conversions between function pointer types -- but
not to void pointers. This is a topic that has been discussed a number
of times in comp.lang.c, including contributions by people who were on
the standards committee, and this interpretation (i.e., that function
pointers cannot be coherced to void pointers) was reinforced, under the
reasoning that function pointers are allowed to be indefinitely larger
than object pointers, as function pointers are allowed to include
implementation defined information about parameter signatures, and
functions are allowed to be further apart in virtual memory than the
maximum total object size that is required to be supported.

> In
> Matlab, whether parens mean order of operation or syntax error (in cases
> where they unambiguously do not mean anything else), depends on if the
> enclosed expression is a function or not. That is the inconsistency.

(2:2:10)(3)

is _not_ 6 in Matlab, it is an error. In matlab, an expression in () is
*always* invalid directly following _anything_ in (). For example,

 >> v = 1:5;
 >> (v)(3)

??? (v)(3)
        |
Error: Unbalanced or unexpected parenthesis or bracket.


It matters not whether v evaluates to a function or not.

In Matlab, you can chain {} but not (), and {} cannot appear directly
after (). Once you have a () in an indexing expression, the only syntax
that allows further {} or () is if the portion leading up and including
the () evaluates to a structure or structure field. For example, a
moment ago, I constructed these valid expression (for different foo)

foo{1}(1).bar{1}(2)
foo.(biz)(3)

In the second expression, biz had to be a character vector whose value
was the name of a field in the structure foo, so foo.(biz) evaluates to
a structure field; indexing of that structure field is then allowed. You
could call this an inconsistency if you wanted, that there -are- cases
where the value after () indexing determined whether a following () is
an error or not. On the other hand, these cases are syntactically
signaled in Matlab code by a '.' : .(value) is _always_ a structure
field access with the _value_ determining the field name, and '.' before
a name is _always_ a structue field access with a fixed field name;
these '.' allow static determination of whether further () will be
permitted or not (and if a structure or structure field was not arrived
at at run-time, it becomes a run-time error rather than a syntax error.)



> Right... the authors of Matlab didn't study the history of languages
> such as Algol, and thus repeated the mistake of defining a language that
> cannot be described with a context free grammar (or made a language that
> can be described with a CFG, but implemented an ad-hoc parser).

They didn't even try. Matlab started as a _practical_ tool. A lot of
people found it useful, and it grew from there. Everything beyond 2D
matrices of double precision numbers was warted on to what was already
there.


> You are misinterpreting Goedel's theorem in the context of programming
> languages. What Goedel's theorem says about languages is that there
> exist languages such that deciding if a string belongs to that language
> is not computable. The take-home message as it applies to programming
> language design is not that one must accept inconsistency, but that one
> should avoid designing languages that cannot be parsed.

Goedel's theorems (plural) extended to prove that once a system was
"sufficiently powerful" to be able to use the system to describe itself,
  that it was impossible to refine the system to be completely
consistent and computable, no matter how many rules you added to the
system. Therefor, any computing language that meets Turing Equivalency
(and even some that fall below that) must have inconsistancies in it.

In C and C++ you can see these inconsistancies in aspects such as
recursive type declarations:

struct linkedlist { struct linkedlist * next; double * valptr }
linkedlist_t;

The type of the field 'next' is not finitely definable in this
construct, so this syntax silently makes the type of 'next' the union of
an infinite number of types, making it impossible for the C language to
be finitely static type checked.. and that's without even touching the
void* "Get Out Of Type Checking Free" construct.

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 25 Apr, 2010 20:49:04

Message: 20 of 25

Walter Roberson <roberson@hushmail.com> wrote in message <hr27lf$svr$1@canopus.cc.umanitoba.ca>...
>

>
> Apply = @(f,x) f(x);
>
> Apply(@(x) x + 1, 2)
>

"Apply" has an built-in equivalent

feval(@(x) x + 1, 2)

Bruno

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 25 Apr, 2010 21:16:03

Message: 21 of 25

Walter Roberson <roberson@hushmail.com> wrote in message <hr27lf$svr$1@canopus.cc.umanitoba.ca>...
>
>
> Goedel's theorems (plural) extended to prove that once a system was
> "sufficiently powerful" to be able to use the system to describe itself,
> that it was impossible to refine the system to be completely
> consistent and computable, no matter how many rules you added to the
> system. Therefor, any computing language that meets Turing Equivalency
> (and even some that fall below that) must have inconsistancies in it.

??????????????? That is the most bizarre statement I read (Admittedly my course of formal logic was long ago). Who claims a Turing maching can ever describe itself?

Bruno

Subject: it is not possible to apply an anonymous function

From: Walter Roberson

Date: 25 Apr, 2010 23:44:45

Message: 22 of 25

Bruno Luong wrote:
> Walter Roberson <roberson@hushmail.com> wrote in message
> <hr27lf$svr$1@canopus.cc.umanitoba.ca>...
>>
>>
>> Goedel's theorems (plural) extended to prove that once a system was
>> "sufficiently powerful" to be able to use the system to describe
>> itself, that it was impossible to refine the system to be completely
>> consistent and computable, no matter how many rules you added to the
>> system. Therefor, any computing language that meets Turing Equivalency
>> (and even some that fall below that) must have inconsistancies in it.
>
> ??????????????? That is the most bizarre statement I read (Admittedly my
> course of formal logic was long ago). Who claims a Turing maching can
> ever describe itself?

Turing Machines to describe Turing Machines do tend to be glossed over
in formal logic courses, but they are also fundamental to a number of
the proofs involving Turing Machines. In particular the proofs about
order of magnitude of computability always have in them that the problem
can be solved in such-and-such magnitude "+ k" time, where k is linear
constant of undetermined value -- a constant that gets treated by
readers much the same as the "+ c" of an indefinite integration... which
is to say, often skipped and its purpose forgotten except by those who
are being rigidly formal.

The Turing Machine "k" is the adjustment of the algorithm being
discussed to the representation of a _particular_ Turing Machine, and
the exact representational efficiency is considered inconsequential
because given any _particular_ Turing Machine representation, one can
write a UTM, Universal Turing Machine, that will emulate the Turing
Machine of the problem in terms of the target Turing Machine.

This step is ideologically similar writing a modern day "Virtual
Machine" that will (for example) run MS Windows within (say) a Linux
system that might be based upon a different processor. Any particular
Virtual Machine might be slower or faster than another Virtual Machine,
but for order of magnitude computations that doesn't matter.

The *how* of writing a UTM is often treated pretty spottily in formal
logic: once it is demonstrated that it can be done in theory, everything
after that just assumes that it has been done.

If I recall correctly after these years (well, more from having
discussed Kolmogrov Complexity more recently than having studied Turing
Machines themselves), given any particular "target" Turing Machine, the
UTM needed to adapt a particular problem is given as input on the Tape
just before the usual input, and thus the UTM shim becomes the "program"
that is executed by the target Turing Machine, and which then knows how
to interpret the remaining input on the tape.


It is, of course, a step from knowing that (in theory) you can write a
Turing Machine to emulate any _other_ Turing Machine, to writing a
Turing Machine that can emulate _itself_. Regretably I will need to
defer on this point, as my text (Enderton, An Introduction to Formal
Logic, if I recall correctly) is at work.

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 26 Apr, 2010 06:26:10

Message: 23 of 25

At this point it seems a rigorous definition is needed to backup such or such claim, otherwise the discussion is a matter of interpretation and not logic (for instant I'm not even sure C is Turing language as you seems to imply Walter).

IIRC,UVM is incomplete (a classical example is: there is no program that can tells whereas any programs stops or run indefinitely; the fact that a given program stops run is then a (true) is a function that is not computable by UTM). I never heard UVM is inconsistent, that must implies CATASTROPHIC consequences, and I'll certainly throw my PC over the window right a away if it was true.

This is however far away from the original topic, which is much simpler and less philosophic.

Bruno

Subject: it is not possible to apply an anonymous function

From: Steven Lord

Date: 26 Apr, 2010 14:59:55

Message: 24 of 25


"Zaphod " <a3904429@owlpic.com> wrote in message
news:hqtsfk$a64$1@fred.mathworks.com...
> Walter Roberson <roberson@hushmail.com> wrote in message
> <hqthjq$96d$1@canopus.cc.umanitoba.ca>...
>> Zaphod wrote:
>> >> Algol 68 was one of the first languages to treat procedures as
>> >> first-class objects; it was also considered for a number of years to
>> >> be too complex for it to be theoretically possible to build a parser
>> >> for.
>>
>> > It doesn't matter that () denotes function calls in these languages. It
>> > also denotes order of evaluation. As long as it is unambiguous, there
>> > should be no problem.
>>
>> Then what is your complaint about Matlab's use of () ? Matlab's () denote
>> order of execution to pretty much the same extent that C's () denote
>> order of execution (Fortran is stricter.) A procedure call using () to
>> denote the argument list is *not* a matter of order of execution.
>
> I said parens can denote several things in a language, namely order,
> invocation, tuples, etc. The key point here is that in this expression:
>
> (@(x) x + 1)(2)
>
> the reasonable result is 3, whereas in Matlab it is a syntax error.

For quite some time, MATLAB permitted arrays of function handles, so this:

S = [@sin, @cos, @tan];

was legal. In that case, what would you have expected this to do?

([@sin, @cos, @tan])(2)

Should this return @cos, the second element of the array of function
handles, or [sin(2) cos(2) tan(2)], the result of evaluating each function
handle in the array with 2 as input?

Note that we have, in the past few releases, deprecated (warned on) the use
of arrays of function handles in favor of cell arrays of function handles;
one main reason for this deprecation was to allow users to call function
handles without FEVAL:

http://www.mathworks.com/access/helpdesk/help/techdoc/rn/f8-1009921.html#f8-1012879

Allowing both arrays of function handles and FEVAL-less invocation would
have lead to this ambiguity.

*snip*

> Yes, there are inconsistencies in other languages. Does this mean we
> cannot point out inconsistencies in Matlab? Pointing out flaws like this
> might lead to a better language. If you find these problems in other
> languages to be a grievance, bring it up in the appropriate forum (as I
> did here).

Pointing them out in this newsgroup may cause some discussion ... but if you
really want to bring it to the attention of the developers, you should
describe your concerns to Technical Support. Keep in mind, though, that
"making MATLAB work like language X" or even "making MATLAB work like
languages X, Y, Z, and Q" may not be a sufficient reason to change the
behavior of MATLAB. After all, to use a different example, C++ is
inconsistent with MATLAB in that its basic data type is not the matrix.
Does that mean C++ should be changed to make its basic data type be a
matrix -- or more to the point, do you think C++ will every be changed that
way? I highly doubt it.

And before you say anything about the relative creation time of those
languages, Cleve said he created the first version of MATLAB in "the late
1970s":

http://www.mathworks.com/company/newsletters/news_notes/clevescorner/dec04.html

Wikipedia indicates Stroustrup began working on C++ in 1979.

http://en.wikipedia.org/wiki/C%2B%2B

Having two languages do things differently is not necessarily a bad thing.
After all, if every language did everything the same as every other
language, we'd have only one language. And I, for one, would not look
forward to learning the new
JavaFortranMATLABSchemeLispSmalltalkShakespeareWhitespacePascalLogoPythonRubyVisualBasicC++
language.

--
Steve Lord
slord@mathworks.com
comp.soft-sys.matlab (CSSM) FAQ: http://matlabwiki.mathworks.com/MATLAB_FAQ

Subject: it is not possible to apply an anonymous function

From: Bruno Luong

Date: 27 Apr, 2010 05:30:21

Message: 25 of 25

"Steven Lord" <slord@mathworks.com> wrote in message <hr49p0$273$1@fred.mathworks.com>...

>
> For quite some time, MATLAB permitted arrays of function handles, so this:
>
> S = [@sin, @cos, @tan];
>
> was legal. In that case, what would you have expected this to do?
>
> ([@sin, @cos, @tan])(2)
>
> Should this return @cos, the second element of the array of function
> handles, or [sin(2) cos(2) tan(2)], the result of evaluating each function
> handle in the array with 2 as input?

Logically, it should return the same as - whatever it is:
  af = [@sin, @cos, @tan];
  af(2)

I short, it is The Mathworks's call. There is not issue with such syntax.

*I* would prefer it returns "@cos" for array with length>1. We can alway call

  feval(af,2)

to return [sin(2) cos(2) tan(2)].

The same ambiguity some how exists currently in Matlab. For example:

function bar = foo(f)
bar = f(2)
end

Calling
  foo(@sin)
  foo([1 2 3])

does two different things.

Bruno

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us