Reputation: 3608
It seems pretty common to me to have an argument, in a dynamically typed language that is either an Object or a key to lookup that object. For instance when I'm working with a database I might have a method getMyRelatedStuff(person)
All I really need to lookup the related stuff is the id of the person so my method could look like this in python:
def getMyRelatedStuff(person_or_id):
id = person_or_id.id if isinstance(person,User) else person_or_id
#do some lookup
Or going the other direction:
def someFileStuff(file_or_name):
file = file_or_name if hasattr(file,'write') else open(file_or_name)
EDIT: I am looking for a built in syntax for this, the closest I can think of is implicit and explicit keywords in C# that allow you to define a cast between types.
Upvotes: 0
Views: 289
Reputation: 425
Lisp
This can easily be implemented using Lisp macros:
(defmacro get-if-not [func val alt]
`(if (~func ~val)
~val
~alt))
You can use that expression like this:
(get-if-not file? file_or_name (open file_or_name))
That will expand to:
(if (file? file_or_name) file_or_name (open file_or_name))
Macros are incredible. I personally refuse to use any language that doesn't have them.
Upvotes: 0
Reputation: 95961
I've never seen built-in syntax for this in any language I've used.
Note that in Python this is typically handled by exceptions:
def getMyRelatedStuff(person_or_id):
"The verbose way"
try:
my_id= person_or_id.id
except AttributeError:
my_id= person_or_id
but preferably:
def getMyRelatedStuff(person_or_id):
"The terse way"
my_id= getattr(person_or_id, "id", person_or_id)
and as for someFileStuff
:
def someFileStuff(file_or_name):
try:
fobj= open(file_or_name)
except TypeError:
fobj= file_or_name
Try to avoid using built-in names like id
and file
in your code; they introduce subtle bugs to your programs.
Upvotes: 1
Reputation: 629
Are you looking for function overloading? For example:
doSomething(Person p);
// these could do lookup and dispatch to doSomething(Person p)...
doSomething(String personName);
doSomething(Integer personId);
Any OO strongly-typed language should be able to do that.
For dynamically-typed languages though I'm not aware of any other way than manually doing some kind of type check (instanceof) operation, and that method can get nasty really fast. You're better off just doing what we did before OOP: use differently-named functions, for example:
doSomethingByName(personName);
doSomethingById(personId);
If your code is well-structured otherwise, most of these "duplicate" functions will be pretty small.
Upvotes: 3
Reputation: 202505
I study programming languages for a living. I've never seen a language with a built-in syntax for that operation. I'm not even sure what you want such a syntax to look like, especially since you can define a function for any of these patterns.
People who like extensible syntax tend to define Lisp macros :-)
Upvotes: 9
Reputation: 59451
You can do this in any language that doesn't check the type of function parameters at compile time.
JavaScript:
function doSomething(person)
{
var name;
if(typeof(person) == "string")
name = person;
else
name = person.name;
//you can simplify it to
name = (typeof(person) == "string") ? name : person.name;
}
Upvotes: 1