Skip to content
Historical revision
Programming Idioms โ€” 2026-05-17 16:55 UTC
Edit summary: AI translation (ko -> en-US)
rev_67188a63139c4a15a045d04ca7de65a8

Programming Idioms

Programming Idioms

A Programming Idiom is a conventional way to write relatively small code constructs within a specific programming language or programming context. In Korean, it is commonly translated as ๊ด€์šฉ๊ตฌ (idiomatic expression).

An idiom is not part of the language definition itself, but forms within the range of expressions the language permits. This mirrors the structure of linguistic idioms, which exist within the rules of words and grammar yet cannot be derived from those rules alone.1

Code that conforms to idioms is called idiomatic, while code that deviates from them is called idiosyncratic. Idiosyncratic code may be grammatically correct but reads as unnatural to someone familiar with the language.

Code
ํŒจ๋Ÿฌ๋‹ค์ž„ = ํ”„๋กœ๊ทธ๋žจ์„ ๋ฐ”๋ผ๋ณด๋Š” ์‚ฌ๊ณ ๋ฐฉ์‹
์›์น™     = ํŒ๋‹จ์„ ์ด๋„๋Š” ์ถ”์ƒ ๊ทœ์น™
ํŒจํ„ด     = ๋ฐ˜๋ณต๋˜๋Š” ์„ค๊ณ„ ๋ฌธ์ œ์˜ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ ํ•ด๋ฒ•
์ด๋””์—„   = ๊ทธ ์–ธ์–ด/๋งฅ๋ฝ์—์„œ ์ž์—ฐ์Šค๋Ÿฌ์šด ์ž‘์€ ํ‘œํ˜„ ๋ฐฉ์‹
๋ฌธ๋ฒ•     = ์–ธ์–ด๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ํ‘œํ˜„ ๊ทœ์น™

The five levels above represent an abstraction hierarchy from thought to expression. Idioms apply at a smaller unit than patterns and are more abstract than syntax.

Core Definition

A Programming Idiom satisfies the following conditions.

Code
1. ํŠน์ • ์–ธ์–ด/์ƒํƒœ๊ณ„/ํ”„๋ ˆ์ž„์›Œํฌ์— ๊ฐ•ํ•˜๊ฒŒ ๋ฌถ์—ฌ ์žˆ๋‹ค.
2. ๋น„๊ต์  ์ž‘์€ ์ฝ”๋“œ ๊ตฌ์„ฑ์š”์†Œ(ํ•œ ์ค„์—์„œ ์ˆ˜์‹ญ ์ค„ ์ˆ˜์ค€)์— ์ ์šฉ๋œ๋‹ค.
3. ๋ฌธ์ œ ์ž์ฒด๋ณด๋‹ค ํ‘œํ˜„ ๋ฐฉ์‹์— ๊ฐ€๊น๋‹ค.
4. ์ฝ”๋“œ ์ฝ๊ธฐ์™€ ์œ ์ง€๋ณด์ˆ˜์˜ ๊ธฐ๋Œ€๊ฐ’์„ ๋งŒ๋“ ๋‹ค.
5. ๋ฌธ๋ฒ•์ ์œผ๋กœ ํ•„์ˆ˜๋Š” ์•„๋‹ˆ์ง€๋งŒ, ์‹ค๋ฌด์ ์œผ๋กœ๋Š” ์‚ฌ์‹ค์ƒ ํ‘œ์ค€์ฒ˜๋Ÿผ ์ž‘๋™ํ•œ๋‹ค.

In terms of scale, idioms are smaller than Design Patterns. Both are templates to follow rather than code to copy and paste, but Design Patterns typically deal with the interactions of multiple objects or modules, whereas idioms address expression at the level of one to a few dozen lines.[1] For example, the Singleton pattern is a Design Pattern, while releasing resources via a using block in C# is an idiom.

Why It Matters

The value of idioms is most clearly apparent in team settings. When multiple expressions are possible for the same task in a given language, following the idiomatic expression reduces the cognitive load on the reader.[1] It takes less time to read the code, there is no need to infer intent, and unexpected behavior can be ruled out more quickly.

Without knowing the idioms:

Code
- ๋ฌธ๋ฒ•์€ ๋งž์ง€๋งŒ ์–ด์ƒ‰ํ•œ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜จ๋‹ค.
- ์ƒํƒœ๊ณ„์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ถฉ๋Œํ•œ๋‹ค.
- ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ๋•Œ ์˜๋„๋ฅผ ์ถ”๋ก ํ•ด์•ผ ํ•œ๋‹ค.
- ์–ธ์–ด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์•ˆ์ „์žฅ์น˜์™€ ์ตœ์ ํ™” ๊ฒฝ๋กœ๋ฅผ ๋†“์นœ๋‹ค.
- ์ฝ”๋“œ ๋ฆฌ๋ทฐ์—์„œ ์ง€์†์ ์œผ๋กœ ๊ฐ™์€ ์ง€์ ์„ ๋ฐ›๋Š”๋‹ค.

Conversely, when you know the idioms:

Code
- ์ฝ”๋“œ์˜ ์˜๋„๊ฐ€ ๋นจ๋ฆฌ ์ฝํžŒ๋‹ค.
- ์–ธ์–ด์˜ ๊ธฐ๋ณธ ์ œ์•ฝ์„ ๊ฑฐ์Šค๋ฅด์ง€ ์•Š๋Š”๋‹ค.
- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋„๊ตฌ๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ํ˜•ํƒœ์— ๋งž๋Š”๋‹ค.
- ๋ฒ„๊ทธ๋ฅผ ๋ง‰๋Š” ๊ด€๋ก€๋ฅผ ์ž๋™์œผ๋กœ ๋”ฐ๋ฅธ๋‹ค.
- ํ˜‘์—… ๋น„์šฉ์ด ์ค„์–ด๋“ ๋‹ค.

Code frequently shared in crowdsourced environments such as StackOverflow and GitHub effectively becomes the medium through which idioms are learned, and this is known to play a key role in helping developers cross language barriers.2

Personal note: In that sense, being Korean is itself a kind of curse as a programmer. The gap between not being a native English speaker and thinking in Korean is significant.

Idioms vs. Design Patterns

Design Patterns address recurring design problems that transcend any particular language, while idioms are closer to the expressive conventions of a specific language. That said, the two form a continuous spectrum, and idioms can reasonably be viewed as small patterns.

Code
๋””์ž์ธ ํŒจํ„ด:
๋ฐ˜๋ณต๋˜๋Š” ์„ค๊ณ„ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ถ”์ƒ์  ํ•ด๊ฒฐ ๊ตฌ์กฐ
์—ฌ๋Ÿฌ ๊ฐ์ฒด/๋ชจ๋“ˆ์˜ ์ƒํ˜ธ์ž‘์šฉ ์ˆ˜์ค€
์–ธ์–ด ๋…๋ฆฝ์  (๊ตฌํ˜„ ํ˜•ํƒœ๋Š” ์–ธ์–ด๋ณ„๋กœ ๋ณ€ํ˜•)

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ด๋””์—„:
ํŠน์ • ์–ธ์–ด์—์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ๊ด€๋ก€์ ์ธ ๊ตฌํ˜„ ๋ฐฉ์‹
ํ•œ ์ค„์—์„œ ์ˆ˜์‹ญ ์ค„ ์ˆ˜์ค€์˜ ํ‘œํ˜„
์–ธ์–ด ์ข…์†์ 

For example, the Strategy pattern can be implemented in many languages, but the form of the implementation varies from language to language.

Code
Java:       interface + class
Python:     callable / duck typing
JavaScript: function object
C#:         interface / delegate
Rust:       trait / enum dispatch
Haskell:    ํ•จ์ˆ˜ ์ธ์ž๋กœ ์ „๋‹ฌ, ๋˜๋Š” type class

Even the same pattern must be expressed in a way that fits each language's idioms. Directly transcribing the UML structure from a pattern book may be grammatically correct but can produce code that feels awkward in the target language.

Idioms vs. Paradigms

A Programming Paradigm is a broad way of thinking about programs. Object-oriented programming, functional programming, and procedural programming all fall into this category.

Idioms are smaller in scope. If a paradigm addresses "how to think," an idiom is closer to "how to naturally express that thinking in this particular language."

Summarized as five levels of abstraction, they are as follows.

Code
[ํฐ ์ถ”์ƒ]
ํŒจ๋Ÿฌ๋‹ค์ž„  : ์‚ฌ๊ณ ๋ฐฉ์‹          (๊ฐ์ฒด์ง€ํ–ฅ, ํ•จ์ˆ˜ํ˜•, ์ ˆ์ฐจ์ )
์›์น™      : ํŒ๋‹จ ๊ธฐ์ค€          (SOLID, DRY, KISS, YAGNI)
ํŒจํ„ด      : ๋ฐ˜๋ณต ๋ฌธ์ œ์˜ ํ•ด๋ฒ•    (์ „๋žต, ์˜ต์ €๋ฒ„, ํŒฉํ† ๋ฆฌ)
์ด๋””์—„    : ์–ธ์–ด๊ถŒ์˜ ์ž์—ฐ ํ‘œํ˜„  (RAII, list comprehension)
๋ฌธ๋ฒ•      : ๊ฐ€๋Šฅํ•œ ํ‘œํ˜„ ๊ทœ์น™    (if, for, class ์„ ์–ธ)
[์ž‘์€ ๋‹จ์œ„]

Moving from top to bottom, language dependency increases and the unit of application becomes smaller.

Language-Specific Examples

Python

Python's idioms are commonly referred to as Pythonic.

Python
# Less Pythonic
result = []
for i in range(len(items)):
    result.append(items[i].name)

# More Pythonic
result = [item.name for item in items]

Representative Python Idioms:

  • list / dict / set comprehension

  • context manager (with)

  • iterator / generator

  • enumerate, zip

  • EAFP (Easier to Ask Forgiveness than Permission): exception-based control flow

  • The contrasting concept, LBYL (Look Before You Leap): pre-check-based control flow. In Python, EAFP is considered more idiomatic.

  • duck typing

  • __init__.py-based module boundaries

Python
with open("data.txt", "r", encoding="utf-8") as file:
    text = file.read()

The code above never calls file close directly. Having the with statement guarantee resource release is the standard idiom in the Python ecosystem.

C++

The defining idiom of C++ is RAII.

C++
{
    std::lock_guard<std::mutex> lock(mutex);
    // critical section
}

Lock acquisition and release are tied to the object's lifetime. This approach guarantees that the lock is released even if an exception is thrown or an early return occurs.

Representative C++ Idioms:

Category

Idiom

Resource Management

RAII, Rule of Zero/Three/Five, Smart pointer ownership, copy-and-swap

Encapsulation

Pimpl, NVI

Type Representation

std::optional, std::variant + std::visit

Compile-Time

CRTP, Type erasure, EBO

STL

Erase-remove

(Language Feature)

range-based for, move semantics

Idioms are especially important in C++. Because the language provides many powerful but dangerous low-level features, idioms effectively serve as safety mechanisms.

For detailed C++ idioms, see here.

Personal note: Personally, I think C++'s biggest problem is that there are too many versions and it is heavily fragmented. I enjoy using programs written in C++, but I'd rather not encounter it in codebases I have to work on.

JavaScript / TypeScript

In JavaScript and TypeScript, asynchronous handling and object composition patterns are important idioms.

TypeScript
// Less idiomatic
fetch(url)
  .then((response) => response.json())
  .then((data) => {
    console.log(data);
  });

// More common form in modern TypeScript
const response = await fetch(url);
const data = await response.json();
console.log(data);

Representative JS/TS Idioms:

  • async / await

  • object destructuring, spread/rest

  • immutable update

  • discriminated union

  • type guard

  • optional chaining (?.)

  • nullish coalescing (??)

  • module boundary-centered design

In TypeScript, rather than simply attaching types, what matters is making types describe the runtime structure.

TypeScript
type Result<T> =
  | { ok: true; value: T }
  | { ok: false; error: string };

function handle(result: Result<number>) {
  if (result.ok) {
    return result.value;
  }

  throw new Error(result.error);
}

This kind of discriminated union is the representative TypeScript idiom for explicitly expressing error paths.

C#

In C#, LINQ, using, async/await, properties, and dependency injection all function as strong idioms.

C#
using var stream = File.OpenRead(path);

Delegating the lifetime of IDisposable resources to using is the C# way.

Representative C# idioms:

  • using / IDisposable

  • LINQ

  • property

  • async/await + Task<T>

  • extension method

  • nullable reference type (string?)

  • dependency injection

  • record type

  • pattern matching (switch expression)

Go

Go's idioms place a strong emphasis on explicitness and simplicity.

Go
result, err := doSomething()
if err != nil {
    return fmt.Errorf("doing something: %w", err)
}

Representative Go idioms:

  • explicit error return + err != nil check

  • error wrapping with fmt.Errorf + %w

  • goroutine + channel-based concurrency

  • resource release scheduling with defer

  • implicit interface satisfaction (in contrast to explicit declaration in Java/C#)

  • preference for small interfaces (io.Reader, io.Writer)

  • simple import paths matching the package name

Go
type Reader interface {
    Read(p []byte) (n int, err error)
}

Keeping interfaces small and letting implementations satisfy them implicitly reflects Go's expressive philosophy.

Rust

Rust's idioms are shaped around the ownership model and explicit error handling.

Rust
fn read_config(path: &Path) -> Result<Config, ConfigError> {
    let contents = fs::read_to_string(path)?;
    let config: Config = toml::from_str(&contents)?;
    Ok(config)
}

Representative Rust idioms:

  • Result<T, E> + ? operator

  • Option<T> + pattern matching

  • ownership transfer (move) vs. borrowing (&, &mut)

  • trait-based abstraction

  • match with exhaustiveness checking

  • builder pattern (StructBuilder::new().with_x().build())

  • newtype wrapper for semantic separation

  • avoiding gratuitous .clone() calls

Rust
match value {
    Some(x) if x > 0 => println!("positive: {}", x),
    Some(_) => println!("non-positive"),
    None => println!("missing"),
}

What reflects Rust's expressive sensibility is that pattern matching is used not merely as branching, but as a direct query against data structure.

Haskell

Haskell's idioms center on function composition and leveraging the type system.

Haskell
processItems :: [RawData] -> [Result]
processItems = map transform . filter isValid

Representative Haskell idioms:

  • function composition (.) and point-free style

  • expressing monadic computation with do-notation

  • ad-hoc polymorphism via type classes

  • Maybe / Either for representing absence and failure

  • pattern matching + guards

  • infinite data structures leveraging lazy evaluation

  • Functor / Applicative / Monad abstractions

Haskell
readConfig :: FilePath -> IO (Either String Config)
readConfig path = do
    contents <- readFile path
    return (parseConfig contents)

In Haskell, idioms are often directly tied to mathematical abstractions such as monads and functors, making this the area where the most is lost in translation to other languages.

Anti-idioms: Expressions to Explicitly Avoid

Negative examples are often more effective than positive ones when teaching idioms. Each language ecosystem has a catalog of anti-idioms that are explicitly considered "do not write it this way."

Code
Python:
- mutable default argument: def f(x=[]):
- bare except ์ ˆ: except:  (์˜ˆ์™ธ ์ข…๋ฅ˜ ๋ช…์‹œ ์—†์ด)
- ์ „์—ญ ๋ณ€์ˆ˜ ๋ณ€๊ฒฝ (global ํ‚ค์›Œ๋“œ)
- type hint ์—†๋Š” ๊ณต๊ฐœ API

C++:
- ํ—ค๋”์— using namespace std;
- raw new / delete (์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ๋Œ€์‹ )
- C ์Šคํƒ€์ผ ์บ์ŠคํŠธ ((int)x)
- ๊ฐ€์ƒ ์†Œ๋ฉธ์ž ์—†๋Š” ๋‹คํ˜•์„ฑ ํด๋ž˜์Šค

JavaScript / TypeScript:
- == (๋А์Šจํ•œ ๋น„๊ต, === ์‚ฌ์šฉ)
- var (let / const ์‚ฌ์šฉ)
- any๋กœ ํƒ€์ž… ์‹œ์Šคํ…œ ์šฐํšŒ (TypeScript)
- ์ง์ ‘ mutation์œผ๋กœ React ์ƒํƒœ ๋ณ€๊ฒฝ

C#:
- async void (์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ œ์™ธ)
- .Result / .Wait() ๋™๊ธฐ ์ฐจ๋‹จ
- ๋นˆ catch ๋ธ”๋ก
- IDisposable์„ using ์—†์ด ์‚ฌ์šฉ

Go:
- ์—๋Ÿฌ ๋ฌด์‹œ (_ = err)
- nil ์ฑ„๋„/์Šฌ๋ผ์ด์Šค์— ๋Œ€ํ•œ ๊ฐ€์ •
- goroutine ๋ˆ„์ˆ˜ (context ์—†์ด ๋ฌดํ•œ ๋Œ€๊ธฐ)
- panic์„ ์ผ๋ฐ˜ ์—๋Ÿฌ ํ๋ฆ„์— ์‚ฌ์šฉ

Rust:
- ๋ฌด๋ถ„๋ณ„ํ•œ .clone()์œผ๋กœ borrow checker ์šฐํšŒ
- unwrap() ๋‚จ์šฉ (Result/Option ์ง์ ‘ ์ฒ˜๋ฆฌ)
- unsafe ๋ธ”๋ก ๋‚จ์šฉ
- ํฐ enum variant๋ฅผ Box ์—†์ด ์‚ฌ์šฉ

Anti-idioms are not merely style issues. Most have real impact on safety or performance, and they are actively detected by linters and static analysis tools.

The Temporal Nature of Idioms

Idioms are not fixed constants. They change across generations as language standards are revised, standard libraries evolve, and community consensus shifts. Therefore, when discussing idioms, a temporal coordinate of "which era's idioms" is needed alongside the discussion.

Generational Changes in C++

Code
C++98 ์‹œ๋Œ€:
- std::auto_ptr
- raw new / delete
- ์ง์ ‘ ์ž‘์„ฑํ•œ ์ปจํ…Œ์ด๋„ˆ ์ˆœํšŒ

C++11 ์ดํ›„:
- std::unique_ptr / std::shared_ptr
- range-based for
- auto, lambda, move semantics

C++17 / C++20 ์ดํ›„:
- std::optional, std::variant
- structured bindings
- ์ปจ์…‰(concepts), ๋ชจ๋“ˆ, ์ฝ”๋ฃจํ‹ด

C++98 code still works if left as-is, but from a modern C++ perspective, it is no longer idiomatic.

Generational Changes in Python

Code
Python 2:
- print ๋ฌธ, unicode ๋ช…์‹œ (u"...")
- xrange / range ๊ตฌ๋ถ„
- new-style class ๋Œ€ old-style class

Python 3:
- print ํ•จ์ˆ˜, ๋ฌธ์ž์—ด = unicode ๊ธฐ๋ณธ
- f-string (3.6+)
- type hint (3.5+, 3.10+์—์„œ |๋กœ union)
- dataclass, asyncio
- ๊ตฌ์กฐ ๋ถ„ํ•ด์™€ match-case (3.10+)

Generational Changes in JavaScript

Code
ES5 ์‹œ๋Œ€:
- var, function ์„ ์–ธ
- prototype ๊ธฐ๋ฐ˜ ์ƒ์†
- callback hell

ES6 ์ดํ›„:
- let / const, arrow function
- class ํ‚ค์›Œ๋“œ, ๋ชจ๋“ˆ import/export
- Promise, async/await
- destructuring, spread/rest
- optional chaining, nullish coalescing (ES2020)

Even within the same language, when writing or reviewing code, one should be conscious of "which generation's idioms this belongs to." When maintaining an older codebase, consistently preserving the idioms of that era may be preferable to mixing in newer-generation idioms.

Sources and Authority of Idioms

Who decides idioms? There is no single authority; they emerge from the interaction of multiple sources.

Code
1. ์–ธ์–ด ์„ค๊ณ„์ž / ๊ณต์‹ ์ œ์•ˆ
   - Python์˜ PEP, Rust์˜ RFC, JS์˜ TC39 proposal
   - ๊ณต์‹ ๊ถŒ์žฅ ์‚ฌํ•ญ์ด ์ด๋””์—„์˜ ์ถœ๋ฐœ์ 

2. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ž๊ธฐ ์‚ฌ์šฉ ๋ฐฉ์‹
   - ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ž๊ธฐ API๋ฅผ ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”์ง€๊ฐ€ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€
   - Python์˜ itertools, Go์˜ io ํŒจํ‚ค์ง€, Rust์˜ std ๋ชจ๋“ˆ

3. ๋ฆฐํ„ฐ / ํฌ๋งคํ„ฐ์˜ ๊ธฐ๋ณธ ๊ทœ์น™
   - rustfmt, gofmt, prettier, eslint, ruff, pylint
   - ์ž๋™ ์ ์šฉ๋˜๋ฏ€๋กœ ์‚ฌ์‹ค์ƒ ๊ฐ€์žฅ ๊ฐ•ํ•œ ๊ฐ•์ œ๋ ฅ

4. ์œ ๋ช… ์˜คํ”ˆ์†Œ์Šค์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€
   - React ์ฝ”๋“œ๋ฒ ์ด์Šค, Django ํ”„๋กœ์ ํŠธ, Kubernetes ์†Œ์Šค
   - ํฐ ํ”„๋กœ์ ํŠธ์˜ ๊ด€๋ก€๊ฐ€ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ „์ฒด๋กœ ํ™•์‚ฐ

5. ๊ถŒ์œ„ ์žˆ๋Š” ์ฑ…๊ณผ ๊ฐ€์ด๋“œ
   - Effective C++, Effective Java, Fluent Python
   - The Rust Book, Real World Haskell
   - Google Style Guide

When these sources conflict (for example, when the style recommended by rustfmt differs from community practice), deciding which to follow is a matter of practical judgment. Generally, (3) linters/formatters > (2) standard library > (1) official proposals carry stronger enforcement, while the weight of (4) and (5) varies by context.

Idioms Reveal a Language's Philosophy

The reason idioms differ across languages is not merely that the syntax differs; it is that the mindset each language encourages is different.

Code
Python:     ๋ช…ํ™•ํ•จ, ๊ฐ„๊ฒฐํ•จ, ๋™์  ํ”„๋กœํ† ์ฝœ
C++:        ์ž์› ์ˆ˜๋ช…, ๊ฐ’ ์˜๋ฏธ, ๋น„์šฉ ๋ชจ๋ธ
Java:       ๋ช…์‹œ์  ํƒ€์ž…, ์ธํ„ฐํŽ˜์ด์Šค, ๊ฐ์ฒด ๋ชจ๋ธ
JavaScript: ํ•จ์ˆ˜ ๊ฐ’, ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด
Rust:       ์†Œ์œ ๊ถŒ, ๋นŒ๋ฆผ, ๋ช…์‹œ์  ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ
Go:         ๋‹จ์ˆœํ•œ ์ œ์–ด ํ๋ฆ„, ๋ช…์‹œ์  ์—๋Ÿฌ ๋ฐ˜ํ™˜
Haskell:    ์ˆœ์ˆ˜์„ฑ, ํƒ€์ž…, ํ•ฉ์„ฑ

As a result, directly transplanting the idioms of one language into another produces awkward code.

Code
Java์‹ class hierarchy๋ฅผ Python์— ๊ทธ๋Œ€๋กœ ์˜ฎ๊ธฐ๋ฉด ๊ณผํ•˜๊ฒŒ ๋ฌด๊ฒ๋‹ค.
Python์‹ duck typing์„ Java์— ๊ทธ๋Œ€๋กœ ์˜ฎ๊ธฐ๋ฉด ํƒ€์ž… ์‹œ์Šคํ…œ๊ณผ ์ถฉ๋Œํ•œ๋‹ค.
C++์‹ ์ˆ˜๋ช… ์ œ์–ด ๊ฐ๊ฐ ์—†์ด C++ ์ฝ”๋“œ๋ฅผ ์“ฐ๋ฉด ์ž์› ๋ˆ„์ˆ˜๊ฐ€ ๋‚œ๋‹ค.
JavaScript์‹ ๋™์  ๊ฐ์ฒด ๊ฐ๊ฐ์„ Rust์— ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ์†Œ์œ ๊ถŒ ๋ชจ๋ธ๊ณผ ์ถฉ๋Œํ•œ๋‹ค.
Haskell์‹ ํ•จ์ˆ˜ ํ•ฉ์„ฑ์„ Java์— ๊ทธ๋Œ€๋กœ ์˜ฎ๊ธฐ๋ฉด ์–ด์ƒ‰ํ•œ functional interface ํญ์ฆ์œผ๋กœ ๋๋‚œ๋‹ค.

What Makes a Good Idiom

A good idiom is not simply short code.

Code
์ข‹์€ ์ด๋””์—„ =
์–ธ์–ด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์•ˆ์ „์žฅ์น˜๋ฅผ ํ™œ์šฉํ•˜๊ณ 
์ƒํƒœ๊ณ„๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ํ˜•ํƒœ๋ฅผ ๋”ฐ๋ฅด๋ฉฐ
์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋น ๋ฅด๊ฒŒ ๋“œ๋Ÿฌ๋‚ด๋Š” ํ‘œํ˜„

A good idiom has the following properties.

  • The reader can immediately grasp the intent.

  • It fits well with the standard library.

  • It reduces hazardous points such as exceptions, resource release, and concurrency.

  • It works well with tools, linters, type checkers, and formatters.

  • It does not create unnecessary abstractions.

How to Learn Idioms

Idioms are difficult to learn from a grammar book alone. You need to read the standard code of the actual ecosystem and ask questions actively.

Code
1. ๊ณต์‹ ๋ฌธ์„œ์˜ ์˜ˆ์ œ์™€ ์ž๊ธฐ ์‚ฌ์šฉ ๋ฐฉ์‹ ๋ณด๊ธฐ
2. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ ํŒจํ„ด ๋ถ„์„
3. ์œ ๋ช… ์˜คํ”ˆ์†Œ์Šค์˜ ์ž‘์€ ๋ชจ๋“ˆ ์ฝ๊ธฐ
4. ๋ฆฐํ„ฐ์™€ ํฌ๋งคํ„ฐ๊ฐ€ ๊ถŒ์žฅํ•˜๋Š” ํ˜•ํƒœ ํ™•์ธ
5. Effective X, The * Book๋ฅ˜ ๊ถŒ์œ„ ์žˆ๋Š” ๊ฐ€์ด๋“œ ์ฝ๊ธฐ
6. "Why Do We Write It This Way in This Language?"๋ฅผ ํ•ญ์ƒ ์งˆ๋ฌธํ•˜๊ธฐ

Key questions when learning idioms:

Code
์ด ์–ธ์–ด์—์„œ๋Š” ์ž์› ์ˆ˜๋ช…์„ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•˜๋Š”๊ฐ€?
์˜ค๋ฅ˜๋ฅผ ์–ด๋–ป๊ฒŒ ํ‘œํ˜„ํ•˜๋Š”๊ฐ€? (์˜ˆ์™ธ, Result, errno, panic)
๋ฐ˜๋ณต๊ณผ ์ปฌ๋ ‰์…˜ ์ฒ˜๋ฆฌ๋Š” ์–ด๋–ป๊ฒŒ ์“ฐ๋Š”๊ฐ€?
์ถ”์ƒํ™” ๋‹จ์œ„๋Š” ํ•จ์ˆ˜์ธ๊ฐ€, ๊ฐ์ฒด์ธ๊ฐ€, trait์ธ๊ฐ€, interface์ธ๊ฐ€?
๋™์‹œ์„ฑ๊ณผ ๋น„๋™๊ธฐ๋Š” ์–ด๋–ค ๋ฐฉ์‹์ด ์ž์—ฐ์Šค๋Ÿฌ์šด๊ฐ€?
๋ชจ๋“ˆ ๊ฒฝ๊ณ„๋Š” ์–ด๋””์— ๊ทธ์–ด์ง€๋Š”๊ฐ€?

Consistently applying these questions lets you absorb the idioms of a new language quickly.

Idioms are a qualitative concept, but recent efforts have attempted to extract them quantitatively through source code mining. Allamanis and Sutton (2014) published research on automatically extracting repeatedly occurring pattern fragments from large GitHub codebases using statistical methods, naming the approach "mining idioms from source code."[1]

Such automated extraction can be used to quickly identify idiomatic expressions in a language being newly learned, or as the basis for code review tools that detect anti-idioms. However, statistically frequent expressions cannot be assumed to be idiomatic without cross-validation against authoritative sources.

Cognitive research has also been conducted on how barriers to idiom learning operate in crowdsourced development environments.[2]

Summary

A Programming Idiom is a small code expression convention considered natural in a specific language.

Code
ํŒจ๋Ÿฌ๋‹ค์ž„์€ ์‚ฌ๊ณ ๋ฐฉ์‹์„ ์ •ํ•œ๋‹ค.
์›์น™์€ ํŒ๋‹จ ๊ธฐ์ค€์„ ์ •ํ•œ๋‹ค.
ํŒจํ„ด์€ ๋ฐ˜๋ณต ๋ฌธ์ œ์˜ ํ•ด๋ฒ•์„ ์ •ํ•œ๋‹ค.
์ด๋””์—„์€ ์ž์—ฐ์Šค๋Ÿฌ์šด ํ‘œํ˜„์„ ์ •ํ•œ๋‹ค.
๋ฌธ๋ฒ•์€ ๊ฐ€๋Šฅํ•œ ํ‘œํ˜„ ๊ทœ์น™์„ ์ •ํ•œ๋‹ค.

A good developer is not simply someone who knows the syntax, but someone who can naturally express problems through the idioms of the language. Idioms change over time, their sources are distributed, and they are paired with explicit negative examples (anti-idioms). Being conscious of all three dimensions significantly accelerates adaptation when encountering a new language.

See Also

  • Design Pattern

  • Software Design Patterns

  • Object-oriented programming

  • Programming Paradigm

  • Functional Programming

  • RAII

  • Standard Idioms

  • Idiomatic Code

  • Pythonic

  • Modern C++

  • Idiomatic Rust

  • Composition over Inheritance

  • Linguistic Idioms

  • Cognitive Load

  • Algorithm Skeleton

  • Embedded SQL


Categories: Programming | Programming Languages | Software Engineering | WIKI

Footnotes

  1. Allamanis, Miltiadis; Sutton, Charles (2014). "Mining idioms from source code". Proceedings of the 22nd ACM SIGSOFT International Symposium on Foundations of Software Engineering. pp. 472โ€“483. arXiv:1404.0417. doi:10.1145/2635868.2635901.Allamanis, Miltiadis; Sutton, Charles (2014). "Mining idioms from source code". Proceedings of the 22nd ACM SIGSOFT International Symposium on Foundations of Software Engineering. pp. 472โ€“483. arXiv:1404.0417. doi:10.1145/2635868.2635901. โ†ฉ
  2. Samudio, David I.; Latoza, Thomas D. (2022). "Barriers in Front-End Web Development". 2022 IEEE Symposium on Visual Languages and Human-Centric Computing (VL/HCC). pp. 1โ€“11. doi:10.1109/VL/HCC53370.2022.9833127. โ†ฉ
Revision history โ€” Programming Idioms