Michael
Michael

Reputation: 3608

Does a syntax for this exist? In any language?

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

Answers (6)

jhuni
jhuni

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

tzot
tzot

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

leppie
leppie

Reputation: 117250

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

Upvotes: 2

Tore A.
Tore A.

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

Norman Ramsey
Norman Ramsey

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

Amarghosh
Amarghosh

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

Related Questions