Naming convention for function

Hi,

I am confused as to what the preferred way to name a function is.

Purpose of function: function to update image status

Option 1:

func update(imageStatus: ImageStatus)

Option 2:

func updateImageStatus(_ imageStatus: ImageStatus)

Questions:

  1. Which is the preferred option (or please feel free to suggest any other alternate)?
  2. Is it ok to use Option 1 which is shorter but needs the first argument name to explain what the function does or should the function name be self explanatory even without the first argument name?

Thanks

  1. Option 1 is much more Swifty, while Option 2 sounds like coming from an old Obj-C library.
  2. Functions should be self explanatory with all required arguments. Allowing call site to include function arguments is one of the best design for clarity. Thereā€™s no good reason not to take advantage of that.
2 Likes

Thanks a lot @Lantua that is a very clear detailed answer.

You may also want to check out APIā€™s Design Guideline.

1 Like

Thanks a lot, that is very helpful

I do not agree with @Lantua on this one. Well, maybe I do, but probably not. It depends on context.

A function should be named such that its base name explains what it does. update is a poor name on its own, unless it clearly updates self. If this is a method on a type, say, Image, then image.update() may be a great name. But if it's a free function, better name it so it better reflects what it does.

You state that the purpose of the function is to update an image status, but you also pass it an image status as an argument.

If this is updating (mutatin) its argument, maybe the function instead should be a method on ImageStatus.update. Or, if it is a setter function, maybe it instead should be a property?

7 Likes

Thank @sveinhal I have some concurrent code in my model class Service

class Service {

    struct ImageStatus { }

    private var imageStatus: ImageStatus

    @MainActor
    func update(imageStatus: ImageStatus) { }
}

Question:

I have one more scenario where I have processTransactions(_ transactions: [Transaction])
Transaction is not my class should I extend it and add my custom logic in it or is processTransactions ok?

Note: English is not my first language.

This Swift.org - API Design Guidelines part of the Swift API Design Guideline answers the questions but it is relatively hard to grasp especially when English is not your first language.

In this case I would say that:

func updateImageStatus(ImageStatus) { }

or even

func update(_ status: ImageStatus) { }

// Probably most of the time passed parameter would be self-explanatory.
service.update(imageStatus)

fits better

It's very similar to the

x.addSubview(y)

In addition, if you will take a look at the API that has update method on Apple Documentation you will find that non of them use argument label.

1 Like

Thanks @nonameplum I think I should go through all the guidelines carefully (I have only looked at them superficially)

Yea, rereading the call site; update(imageStatus: ...) does sound like youā€™re updating something with image status, rather than updating the image status with the new value.

My second point still stands, that one should take advantage of the arguments, even if not for stating the function's primary purpose.


Ah yes, the guideline does say to omit type names in particular because they are generally known by the reader (if they arenā€™t, they should read previous lines and work their way down anyway). I forgot about that part.

So I think update(_:) does fit this particular case.


Always take a grain of salt when looking up Apple's API, though. Albeit being much rarer nowadays, some are remnants of the Obj-C designs.


If it isnā€™t confusing with other functions with similar names, maybe just process(_:)?

1 Like

Thanks @Lantua I think I understand better now

I think this is the most relevant guideline in the context of your question:

  • Include all the words needed to avoid ambiguity for a person reading code where the name is used.

    For example, consider a method that removes the element at a given position within a collection.

    extension List {
      public mutating func remove(at position: Index) -> Element
    }
    employees.remove(at: x)
    

    If we were to omit the word at from the method signature, it could imply to the reader that the method searches for and removes an element equal to x , rather than using x to indicate the position of the element to remove.

    employees.remove(x) // unclear: are we removing x?
    

I think there is an (maybe slight) ambiguity in both of your functions: are you updating a image status that currently is the given value, or are you changing the image status to the given value. To disambiguate, the second function with preposition "to" as argument label should be a better option:

class Service {
    func updateImageStatus(to newImageStatus: ImageStatus)
}

Having "ImageStatus" in the function's name is good because the function is not defined in ImageStatus. But if the function is in ImageStatus, then the function's name should omit it:

struct ImageStatus {
    mutating func update(to newStatus: Self)
    func updated(to newStatus: Self) -> Self
}
6 Likes

Thanks @wowbagger I think that is a good suggestion definitely adds more clarity, it is interesting how trying to improve the name results in improving the design

Interesting, but not surprising. Choosing a good name means you have to understand the intent. Communicating that intent relies not just on the name, but also how that name fits into the larger context.

4 Likes
class Service {

    struct ImageStatus { }

     @MainActor
     var imageStatus: ImageStatus {
        didSet { }
    }
}

One alternative would be to expose the imageStatus and do the side-effects in the didSet. So the call site would be clear.

let service = Service()

let newImageStatus = Service.ImageStatus()

service.imageStatus = newImageStatus

The func update(imageStatus:)seemed a lot like func setImageStatus(_:) which seems to be usually handled with property observers in swift. (instead of the getter/settter method common in, say, the java language)

1 Like

@andybezaire I think that is a good idea, thanks a lot!