views:

180

answers:

5

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.

+1  A: 

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;
}
Amarghosh
+8  A: 

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

Norman Ramsey
I'm not entirely sure that's entirely true (You're the expert and I mean no disrespect, but hear me out). C++ has the (condition)?(execute on pass):(execute on fail); syntax. So perhaps, that's what @Michael is referring to?)
inspectorG4dget
Python has ternary operator too and it is even used in the question.
wRAR
I really do need to learn Lisp! And I want your job :)
Michael
@inspector, @wRAR, @Michael: If the expresion form of if-then-else is all Michael is looking for, then it is indeed in C, C++, Haskell, Icon, Lisp, ML, Scheme, Smalltalk, and probably a whole bunch of others I can't think of off the top of my head. I thought Michael was looking for something more specific along the lines of syntax for "If I'm the object you're looking for, return me, otherwise send me this message."
Norman Ramsey
+2  A: 

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.

Tore A.
+2  A: 

Scheme, LISP, or just about any language with macro's.

leppie
A: 

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.

ΤΖΩΤΖΙΟΥ