functions without parentheses

J

Jerry He

Hi,
Is it possible to create a function that you can use
without parenthesizing the arguments? for example, for

def examine(str):
.....
.....

Is there some way to define it so that I can call it
like

examine "string"
instead of examine("string")?

thanks in advance

-Jerry



____________________________________________________
Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs
 
S

Steven D'Aprano

Hi,
Is it possible to create a function that you can use
without parenthesizing the arguments?

What problem are you trying to solve that requires this sort of syntax,
and why can't it be solved with parentheses?
 
S

Simon Dahlbacka

If you actually want that kind of syntax, then why don't you use Visual
Basic? ;)
 
S

Steve Holden

Simon Dahlbacka wrote [about function calls without parenthesis]:
If you actually want that kind of syntax, then why don't you use Visual
Basic? ;)
Because Perl is far too tempting to ignore.

The serious answer to the OP's question, however, is that Python refuses
to guess whether a function reference not followed by a left parenthesis
is a reference to a function or a reference to the result of calling the
function. Perl and VB(Script) make more use of context, in ways that
confuse many users.

Time for someone to try

import this

regards
Steve
 
S

Steven Bethard

Jerry said:
def examine(str):
.....
.....

Is there some way to define it so that I can call it
like

examine "string"
instead of examine("string")?

What do you want to happen when someone types:

examine

??? Or better yet, what if you do something like:

map(examine, list_of_strs)

??? Should examine be called with no arguments? Or should it be passed
as a function object to map?

STeVe
 
S

Scott David Daniels

Jerry said:
... Is there some way to define [examine] so I can call it like
examine "string"
instead of examine("string")?

Perhaps you are looking for ipython (google for it) if
all you are looking for is ease of interactive entry.

--Scott David Daniels
(e-mail address removed)
 
B

bruno modulix

Jerry said:
Hi,
Is it possible to create a function that you can use
without parenthesizing the arguments? for example, for

def examine(str):
.....
.....

Is there some way to define it so that I can call it
like

examine "string"
instead of examine("string")?

No.

The reason (well, one of the reasons) is that, given a function my_func

def my_func(*args, **kwargs):
print "in my_func:"
print "+ args : %s" % ", ".join(args)
print "+ kwargs %s" % ", ".join(["%s=%s" % keyval \
for keyval in kwargs.items()])
return True


the expressions

my_func
and
my_func()

have very different semantics. (hint: copy/paste this code in your
python interactive interpreter).

The first expression has exactly the same semantic as it would have with
any other object[1] : it returns a reference to the function object
referenced by the name 'my_func' according to namespace rules.

[1] remember, in Python, functions are objects too.


The second expression has the usual 'function call' semantic.

The first expression allow to write code like:
my_func_alias = my_func
my_func_alias()

or
def my_caller_func(any_func, *args, **kwargs):
print "calling %s with *args %s and **kwargs %s" \
% (any_func,
", ".join(args),
", ".join(["%s=%s" % keyval for keyval in kwargs.items()])

result = any_func(*args, **kwargs)
print "result :%s" % result
return result

my_caller_func(my_func)


In fact, '()' is the 'call' operator, that is then applied to the
callable object[2] referenced by 'my_func'. So a function call like

my_func()

is in fact made in two steps:
- retrieving the object referenced by the name 'my_func'
- trying to apply the '()' call operator on it.


[2] Functions are just one special case of callable object. Lambda are
another, as any instance of a class defining the __call__ method.


the call operator could be implemented like this:
def __call_op__(func_name, *args, **kwargs):
if hasattr(func_name, __call__):
return func_name.__call__(*args, **kwargs)
else:
raise TypeError("%s object is not callable" % type(func_name))


Ok. Now that you know this, if Python was to support the

result = my_func "arg1", "arg2"

syntax, how should the expression

result = my_func

be interpreted ?-)

(hint: remember that the prototype of my_func allow us to call it with
no args at all)

There are good reasons for trying to have a clear and unambigous syntax.
functions-being-objects (as wall as 'other-objects-being-callable) is
one of the strength of Python, and it's a common idiom in Python to pass
functions (or any other callable) around.

BTW, note that there are few languages that doesn't inforce one (and
only one) unambigous syntax for function calls (even VB has a defined
and mandatory syntax for function calls, which is the same as Python's.
What VB has that Python has not is the semantic difference between
functions and procedures, and different syntaxes for both).


HTH
 
B

Bengt Richter

Hi,
Is it possible to create a function that you can use
without parenthesizing the arguments? for example, for

def examine(str):
.....
.....

Is there some way to define it so that I can call it
like

examine "string"
instead of examine("string")?
I suggested in a previous thread that one could support such a syntax by
supporting an invisible binary operator between two expressions, so that
examine "string" translates to examine.__invisbinop__("string") if
examine as an expression evaluates to an object that has a __invisbinop__ method.

Then you wouldn't define examine as a function, you would define it as an instance
of a class like
class Examine(object):
define __invisbinop__(self, other):
#...whatever
examine = Examine()
and then
examine "string"

Of course this is a strange syntax mod to the language, and undoubtedly
would have many strange effects, but superficially, it seems like something
could be done. But a consequence of white space as potential invisible operator
would be that foo() and foo () might be foo.__call__() vs foo.__invisbinop_(())

Regards,
Bengt Richter
 
S

Steven D'Aprano

I suggested in a previous thread that one could support such a syntax by
supporting an invisible binary operator between two expressions, so that
examine "string" translates to examine.__invisbinop__("string") if
examine as an expression evaluates to an object that has a __invisbinop__ method.

Why would you want to?
 
J

Josef Meile

Steven said:
Why would you want to?
My best guest is that the OP uses VB, where you can do that. I
personally hate this feature because it just makes me do a lot of
mistakes. ie: In VB you can do:

fooFunction fooParameter

but if you want to assign this to a variable you **must** use this:

fooVer = fooFunction(fooParaMeter)

I really get confused because I automatically use the braces.

Regards,
Josef
 
P

phil hunt

I suggested in a previous thread that one could support such a syntax by
supporting an invisible binary operator between two expressions,

That's a truely appalling idea.
so that
examine "string" translates to examine.__invisbinop__("string") if
examine as an expression evaluates to an object that has a __invisbinop__ method.

Then you wouldn't define examine as a function, you would define it as an instance
of a class like
class Examine(object):
define __invisbinop__(self, other):
#...whatever
examine = Examine()
and then
examine "string"

Pass the sick bucket.
 
B

Bengt Richter

Why would you want to?
Mainly to say that I think there is way to do it (and thus further to mulch the idea garden ;-)
whatever the merits. As to the merits, I haven't thought about it much, but ISTM for limited
contexts it would allow you to spell concatenating/aggregating expressions without the
"line noise" of intervening operator glyphs, e.g.,

agg = Aggregate() first_thing second_thing 3 "four" etc.and.so.forth ;
or

mypath = Path() prefix middle filename+'.ext' ; # explicit terminating ';' or (...) might be needed
# if EOL can be part of whitespace delim as below

or
arr = (ArrayElementAggregator()
11 12 13
21 22 23
)


The latter presupposes that white-space including an EOL causes attempt to access an alternate
__invisbinop__ (e.g., __invisbinopNL__) that one could define to aggregate new rows of expressions,
but would not be an error if absent, and thus end a single-line aggregator without explict ';' or parens.

I haven't thought of all the ramifications, I was just playing with the idea ;-)

Others might think of other ways to answer your "why" ;-)

Regards,
Bengt Richter
 
D

Dan Sommers

On Sat, 30 Jul 2005 18:42:59 GMT,
or
arr = (ArrayElementAggregator()
11 12 13
21 22 23
)

What was that again about every other computer language wanting to be
Lisp? ;-)

Regards,
Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top