Arugment label에 관하여

들어가기 전

  • 함수(메서드)이름을 만들 때 마다 헷갈려서 정리해보았다.
  • 왜 Argument 라고 했을까?

    Argument label은 함수 혹은 메서드 호출 시 프로그래머에게 보여진다.
    즉 아래의 move함수를 호출할 때 from, to 는 보이지만 start, end레이블(parameter label)은 보이지 않는다.
    argument는 논쟁,논의,증명 등의 뜻을 가진다.
    결국 Argument label은 함수(혹은 메서드)호출 시 입력하는 값을 언급할 때 사용하라는 뜻으로 만든게 아닐까

최종 요약

  1. omit하는 경우

    1. 전달인자를 명확히 구분하지 못하는 경우
    2. 첫 번째 전달인자를 통해 값은 그대로, 타입만 바꾸는 함수(메서드)의 경우 전달인자를 omit 한다.
      (단 타입변경의 대상이 첫 번째 전달인자이고, 값을 보존하면서 타입을 바꾸는 단형성을 만족할 때)
    3. 첫 번째 전달인자가 문법구문(동사+주어를 제외한 의미덩어리)의 중간에 위치하는 경우
  2. 반드시(or 추천) 명시해야하는 경우

    1. 단형성을 만족하면서 타입변환하는 함수(메서드)의 대상의 범위가 정해진 경우(추천)
    2. 그 외 모든 경우
  3. 전달인자 레이블에 전치사구가 포함된 경우

    1. 전달인자의 추상화 레벨이 다른 경우 각각 전달인자 레이블을 명시한다
    2. 전달인자가 여러개인데 각 인자의 추상화 레벨이 동일한 경우 전치사를 함수(메서드)이름에 추가한다.
    3. 그 외의 경우에는 전달인자 레이블을 전치사구부터 시작하도록 한다.

Argument Labels(전달인자 레이블)

Value preserving type conversion

요약

  1. 전달인자 레이블을 이용해 구분할 필요가 없는 경우 omit
  2. 첫 번째 전달인자를 값은 그대로, 타입만 바꾸는 함수(메서드)의 경우 전달인자를 omit 한다.
  3. 타입변경 대상의 범위가 한정된 경우 범위를 전달인자 레이블로 명시한다.
  4. 값을 보존하면서 타입이 바뀌는 단형성을 만족할 때 1,2의 규칙을 따른다.

본문 번역

func move(from start: Point, to end: Point)
x.move(from: x, to: y) 
  • Omit all labels when arguments can’t be usefully distinguished, e.g. min(number1, number2), zip(sequence1, sequence2).

  • 전달인자 레이블이 전달인자들을 유용하게 구분하지 못하는 경우 모든 전달인자 레이블을 무시합니다. 예시 : min(number1, number2), zip(sequence1, sequence2).

  • In initializers that perform value preserving type conversions, omit the first argument label, e.g. Int64(someUInt32)

  • 값은 보존하고 타입만 변경하는 이니셜라이저의 경우 첫 번째 전달인자 레이블을 무시합니다. 예시 : Int64(someUInt32)

    The first argument should always be the source of the conversion.

    타입 변환의 대상은 반드시 첫 번째 전달인자여야 합니다.

    extension String {
    // Convert `x` into its textual representation in the given radix
    // `x`를 주어진 기수(기초가되는 수, radix)내에서 문자적인 표현으로 바꿉니다. 
    init(_ x: BigInt, radix: Int = 10)Note the initial underscore (초기의 언더스코어를 참고합니다.)
    }
    
    text = "The value is: "
    text += String(veryLargeNumber)
    text += " and in hexadecimal, it's"
    text += String(veryLargeNumber, radix: 16)

    In “narrowing” type conversions, though, a label that describes the narrowing is recommended.

    그러나 타입변환 대상의 범위가 한정된 경우, 전달인자 레이블을 통해 그 범위를 나타내는 것을 추천합니다.

    extension UInt32 {
    /// Creates an instance having the specified `value`.
    /// 특정한 값을 가지는 인스턴스를 만듭니다. 
    init(_ value: Int16)Widening, so no label(범위가 넓기 때문에 레이블이 없습니다.)
    /// Creates an instance having the lowest 32 bits of `source`.
    /// 가장 낮은 32비트를 자원으로 가지는 인스턴스를 만듭니다.
    init(truncating source: UInt64)
    /// Creates an instance having the nearest representable
    /// approximation of `valueToApproximate`.
    /// `valueToApproximate`의 표현가능하고 
    /// 가장 근접한 추정치를 가지는 인스턴스를 만듭니다. 
    init(saturating valueToApproximate: UInt64)
    }

    A value preserving type conversion is a monomorphism, i.e. every difference in the value of the source results in a difference in the value of the result. For example, conversion from Int8 to Int64 is value preserving because every distinct Int8 value is converted to a distinct Int64 value. Conversion in the other direction, however, cannot be value preserving: Int64 has more possible values than can be represented in an Int8.

    값을 보존하면서 타입을 바꾸는것을 단형성이라고 합니다. 즉 타입변환 대상의 값이 다르면 결과도 다릅니다. 예를 들어 Int8에서 Int64로 타입을 바꾸는 경우 값이 보존되지만 반대의 경우엔 값이 보존되지 않습니다. 왜냐하면 Int64는 Int8타입으로 바뀌면서 다양한 값으로 표현될 수 있기 때문입니다.

    Note: the ability to retrieve the original value has no bearing on whether a conversion is value preserving.

    참고 : 원래의 값을 검색할 수 있는지의 여부는 (타입)변환이 값을 보존하는지의 여부와 관계없습니다.


Argument label and Prepositional phrase(전치사구)

요약

전치사구 : 전치사 + 명사
1. 만약 argument label로 전달받는 값의 의미가 함수(혹은 메서드)의 전치사구에 위치한다면 전치사구의 전치사 위치부터 arguement label로 만든다.
2. 전달인자가 여러개인 함수(혹은 메서드)에서 전달인자의 abstraction level이 동일(단일, single)한 경우 전달인자 레이블의 전치사를(전치사가 있는 경우) 함수이름의 위치로이동한다.
3. 첫 번째 전달인자가 문법구문에(의미덩어리 내부) 위치하는 경우
(ex : x.addSubview(y)

보충개념

Method Abstraction
1. 부모 클래스를 상속하는 여러 클래스에서 비슷한 역할을 하는 메서드를 사용하는 경우 부모 클래스에서 abstraction method를 선언

```swift
    //example
    class Base {
        func printDum() {
            
        }
    }

    class SubA: Base {
        override func printDum() {
            print("sub")
            //
        }
    }

    class func SubB: Base {
        override func printDum() {
            print("dumdum")
        }
    } 
```
  1. 스위프트에선 프로토콜을 이용해 method abstraction을 구현

       //example
       protocol Base: AnyObject {
           func printDum() 
       }
    
       class SubA: Base {
           func printDum() {
               print("sub")
           }
       }
    
       class func SubB: Base {
           func printDum() {
               print("dumdum")
           }
       } 

    (참고)

singe level of abstraction

  • level : 정말 간단하게 말하자면 코드를 읽을 때 생기는 뎁스라고 생각하면 될 것 같다. {} 로 묶이는 코드블럭, 전달인자 등을 abstraction이라고 생각할 수 있음. 추상화의 단위, 코드를 읽을 때 하나의 개념으로 묶이는 단위

    Abstraction is a fundamental concept in OOPS. In brief and layman’s term and it talks about hiding the “how” part and only expose “what” to the outer world. Maybe in some other blog I will elaborate on this and explain its true meaning.

    Level of abstraction comes to the point where our mental grouping comes into effect. It’s best imagined like our cognitive ability to continue being abstracted from details of operations. In general, different “blocks” of code inside a method is a classic indicator of different level of abstractions. This means, the reader of the code now has to create a “branch” in their mental grouping to read that condition or loop block and merge back to the same level where the block ended.
    (출처)

본문의 single abstraction의 예시

// X : 여기서 x,y 는 동일한 abstraction levle이다. 
// 즉 이 함수(혹은메서드)는 (x,y)위치로 이동하는 것을 의미하고 있지 
// x따로 y따로 이동하라는것을 의미하지 않는다. 
// 동일한 레벨에 위치하고 있음. 
 func move(to x: Int, y: Int) { }

// O : x 라는 위치로의 이동표현. 명확히해야하는 추가적인 인자(동일선상의 abstraction level)가 없다.
func move(to x: Int) { }

// O
func moveTo(x: Int, y: Int) { }

//O : market, customer는 각각 다른 abstraction level을 의미
func move(to market: Int, from customer: Int) { }

gramatical phrase

  • 문법구문(gramatical phrase) : 전치사구, 명사구 등을 의미
  • 구(phrase) : 2개 이상의 의미를 가진 단어의 합. 단어들이 주어 + 동사 역할의 단어가 없는 것.
    - I study Swift from home - gramatical phrase : from home
    - 본문의 예시 :x.addSubview(y)
    - subview + y 가 하나의 phrase 라서 레이블을 omit한 듯 하다.

본문

  • When the first argument forms part of a prepositional phrase, give it an argument label. The argument label should normally begin at the preposition, e.g. x.removeBoxes(havingLength: 12).

  • 첫 번째 전달인자가 전치사구의 일부라면, 전달인자 레이블을 줍니다. 이 때 이 전달인자 레이블은 반드시 전치사 위치에서 시작합니다. 예 : x.removeBoxes(havingLength: 12)

    An exception arises when the first two arguments represent parts of a single abstraction.

    예외가 발생하는 경우가 있는데 첫 번째 두 전달인자들이 단일 추상화의 일부로 표현될 때 입니다.

    ❌
    a.move(toX: b, y: c)
    a.fade(fromRed: b, green: c, blue: d)

    In such cases, begin the argument label after the preposition, to keep the abstraction clear.

    이런 경우에는 추상화를 정확히 하기 위해 전달인자 레이블을 전치사 다음에 시작하도록 합니다.

    ✅
    a.moveTo(x: b, y: c)
    a.fadeFrom(red: b, green: c, blue: d)
  • Otherwise, if the first argument forms part of a grammatical phrase, omit its label, appending any preceding words to the base name, e.g. x.addSubview(y)

  • 첫 번째 전달인자가 문법구문의 일부라면 전달인자 레이블을 무시하고 기본이름에 선행단어를 추가합니다. 예 :x.addSubview(y)

    This guideline implies that if the first argument doesn’t form part of a grammatical phrase, it should have a label.

    이 가이드라인이 의미하는 것은 첫 번째 전달인자가 문법구문의 일부가 아니라면 반드시 레이블을 가져야한다는것 입니다.

    ✅
    view.dismiss(animated: false)
    let text = words.split(maxSplits: 12)
    let studentsByName = students.sorted(isOrderedBefore: Student.namePrecedes)

    Note that it’s important that the phrase convey the correct meaning. The following would be grammatical but would express the wrong thing.

    문구가 올바른 의미를 전달하고 있는지가 중요합니다. 아래의 내용은 문법적으로는 맞지만 잘못된 의미입니다.

    ❌
    view.dismiss(false)   Don't dismiss? Dismiss a Bool? (해제하지 말아라? Bool을 해제해라?)
    words.split(12)       Split the number 12?(숫자 12를 나눠라?)

    Note also that arguments with default values can be omitted, and in that case do not form part of a grammatical phrase, so they should always have labels.

    또한 기본값을 가지는 전달인자는 무시될 수 있습니다. 이 경우에는 문법구문의 일부가 아니기 때문에 항상 레이블을 가져야 합니다.

  • Label all other arguments.

  • 그 외 다른 모든 인자들에 이름을 붙입니다.

좋은 웹페이지 즐겨찾기