Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function name convention for "convert foo to bar"

I have a very common pattern of "given a Foo, return a Bar," for example, given a user_id, return a User.

Is there a conventional naming pattern for these sorts of functions? Following Joel on Software, I've personally used a lot of bar_from_foo(), but I rarely see other people do this and it quickly becomes verbose, e.g.

widgets = user_widgets_from_user(user_from_param_map(params))

Is there a conventional way to name, or namespace (e.g. User.from_map()) in any of the popular languages out there? I am particularly interested in Python but any language you can think of would br useful.

like image 829
elliot42 Avatar asked Apr 12 '13 03:04

elliot42


People also ask

What is the naming convention for functions?

Naming Convention for Functions So, similar to variables, the camel case approach is the recommended way to declare function names. In addition to that, you should use descriptive nouns and verbs as prefixes. For example, if we declare a function to retrieve a name, the function name should be getName.


5 Answers

I would take advantage of Clojure's naming flexibility and call it:

(defn foo->bar [] ...)

To me that makes the intent quite clear and it's pretty short.

like image 103
leonardoborges Avatar answered Oct 04 '22 06:10

leonardoborges


In Python, and various other OO languages, this should be a constructor on Bar that takes a single Foo as its only argument. Since Python doesn't do method overloading (and attempts to emulate it are usually fragile), if Bar.__init__ already takes a different signature, then the convention is exactly your last one. Importantly, this is usually defined as a class method rather than a static method (for the benefit of subclasses):

 class Bar:
      @classmethod
      def from_foo(cls, f):
          '''Create a new Bar from the given Foo'''
          ret = cls()
          # ...
like image 29
lvc Avatar answered Oct 05 '22 06:10

lvc


If you want to convert something into another, for example a string to an integer, the method is to be defined on the receiver, and hence its class is clear, so you should not put the receiver class as part of the method name: String#to_i, not String#string_to_i. This in one of the core ideas of object oriented programming (polymorphism).

If the receiver is too general to be assigned such method, for example if user_id is a mere string, and defining a method on String to convert it to a User does not look right, then you should define a constructor method on the class that you expect the return value to be: User.new or User.from_id.

like image 23
sawa Avatar answered Oct 01 '22 06:10

sawa


I think it depends a lot on context and choosing a meaningful metaphor. ActiveRecord for instance uses the class method "find" for finding records in the database, a more meaningful idea than "input a user_id, output a user". For example:

User.find(user_id)
User.find_by_email(user_email)

For conversions, I usually like to write the conversion methods to make it easy to use in higher order functions. For example in ruby, conversions are often done with to_* instance methods, for example to convert a Foo to a Bar it would make sense to have a to_bar method for all foos, so you could write:

foo = Foo.new(...)   # make a new Foo
bar = foo.to_bar     # convert it to a Bar

And then to convert a bunch of foos, you could simply:

bars = foos.map(&:to_bar)

Ruby also tends to have Foo.parse(str) for converting a string to the object.


For javascript, I like having class methods (which I got from standard ml), for example:

Foo.toBar = function(foo) {
   return new Bar(...);
};

And then you can map over it as well (using underscore in this example):

var bars = _.map(foos, Foo.toBar);

the Standard ML convention is structure (class) methods. Example fn types:

Foo.toBar : foo -> bar
Foo.fromBar : bar -> foo

And you'd use it like:

val bar = Foo.toBar foo;
val bars = map Foo.toBar foos;
like image 29
AJcodez Avatar answered Oct 05 '22 06:10

AJcodez


Why placing the type of the parameter the name of the function? I think it would be clearer something like

a_bar = bar_from(a_foo)

then you can rely on dynamic dispatch or overload in many languages... for example in Python the implementation could try to call x.toBar() if present or it could check for a global registry like Bar_builders[type(x)](x); in Lisp you could rely on methods; in C++ on overloads...

like image 32
6502 Avatar answered Oct 01 '22 06:10

6502