Function name assignment for "convert foo to bar"

I have a very common template "given by a Foo , return a Bar ", for example, with a user_id , return a User .

Is there a regular name pattern for these kinds of functions? Following Joel on Software , I personally used a lot of bar_from_foo() , but I rarely see other people doing this and it quickly becomes verbose, like

 widgets = user_widgets_from_user(user_from_param_map(params)) 

Is there a common way to name or namespace (e.g. User.from_map() ) in any of the popular languages? I'm particularly interested in Python, but any language you might think of would be helpful.

+6
source share
5 answers

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

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

For conversions, I usually like to write conversion methods to make them easier to use in higher order functions. For example, in ruby, conversions are often performed using the to_* instance methods, for example, to convert a Foo to Bar it would be advisable 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 has Foo.parse(str) to convert a string to an object.


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

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

And then you can also redraw it (using the underscore in this example):

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

The standard ML convention is structure (class) methods. Examples of fn types:

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

And you would use it like:

 val bar = Foo.toBar foo; val bars = map Foo.toBar foos; 
+3
source

I would use Clojure's name flexibility and name it:

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

For me, this makes the intention perfectly clear, and it is quite short.

+15
source

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

If the recipient is too general to assign such a method, for example, if user_id is a simple string and defining a method to String to convert it to User does not look right, then you must define the constructor method for the class for which you expect the return value to be as follows: User.new or User.from_id .

+5
source

In Python and other OO languages, this should be a panel constructor that takes a single Foo as its only argument. Since Python does not overload the method (and attempts to mimic it are usually fragile), if Bar.__init__ already accepts another signature, then the convention is your last. It is important to note that this is usually defined as a class method, not a static method (in the interests of subclasses):

  class Bar: @classmethod def from_foo(cls, f): '''Create a new Bar from the given Foo''' ret = cls() # ... 
+5
source

Why set parameter type for function name? I think it would be clearer something like

 a_bar = bar_from(a_foo) 

then you can rely on dynamic dispatch or overloading in many languages ​​... for example, in Python, an implementation can try to call x.toBar() , if any, or can check the global registry, for example Bar_builders[type(x)](x) ; in Lisp, you can rely on methods; in C ++ during overloads ...

+1
source

All Articles