Що ідіоматичне?


19

Я розумію, що "ідіома" є звичайною операцією або шаблоном, який у певній мові не спрощений синтаксисом основної мови, наприклад, збільшенням цілого числа:

i = i + 1;

У C ++ ця ідіома спрощена оператором:

++i;

Однак, коли хтось використовує термін "ідіоматичний", я не знаю, як це зрозуміти. Що робить фрагмент коду "ідіоматичним"?


Це належить стільки ж на english.stackexchange.com, скільки тут.
S.Lott

@ perl.j: Проникливий. Ви дійсно уточнили, чому визначення "idiomatic" не належить до english.stackexchange.com. Дуже корисний.
S.Lott

Відповіді:


24

Ідіоматичний спосіб написання якогось коду - це коли ви пишете його дуже специфічно через мовні особливості, які не мають інших мов.

Наприклад, у C ++ використання ідіоми RAII призводить до способів написання коду C ++, керування ресурсами, які є ідіоматичними.

Іншим прикладом може бути використання розуміння списку в Python для створення списків. Це ідіоматично, тому що ви б використали розуміння списку в ідіоматичному Python, але ви могли зробити те ж саме, використовуючи функцію генератора на будь-якій іншій мові або навіть на Python.

Часто хтось, хто пробує нову мову, не використовуючи ідіоми, характерні для цієї мови, не напише ідіоматичний код.


Відмінний опис. Так що в C #, якщо я створять метод розширення, який закликається TryAdd()в Dictionaryкласі Generic, щоб спочатку перевірити, !Contains()а потім зателефонувати Add(), це було б ідіоматично? Я використовую функцію, характерну для методів розширення C #.
void.pointer

1
Я не впевнений, як саме досвідчений кодер C ++ скаже вам написати безкоштовні функції для розширення класів, а не додавати членів, де це можливо. Це не те саме, що методи розширення C #, але він досить близький і доступний для будь-якої мови, що дозволяє безкоштовні функції. Я впевнений, що написання "set / getters" в C # за допомогою властивостей є ідіоматичним.
Клайм

Але це не C ++, тому використання "способу C ++" може бути недостатньо "ідіоматичним". Використання тут методу розширення є розумним і дуже схожим на C #. У будь-якому випадку це був приклад, але методи розширення дуже ідіоматичні для C #.
void.pointer

Так, тому я сказав "я не впевнений", це відчувається ідіоматично, але це настільки близько до інших основних особливостей інших мов, що я не впевнений (тому що я не C # dev). У мене є ще один приклад: циклічне завершення відбувається за допомогою рекурсії на всіх функціональних мовах. Ви можете це робити іншими мовами, але очевидно, що це ідіоматично для функціональних мов. Не впевнений, чи допомагає це.
Клайм

1
Звичайно, пітон іде на крок далі, маючи ідіоматичний спосіб посилання на ідіоматичний код, тобто на пітонічний. * 8 ')
Марк Бут

12

Нормальне визначення

Використання, що містить або позначає вирази, які є природними для носія мови

Визначення програмування

Використання, що містить або позначає вирази, природні програмісту [Вставити мову]


1
Якби я вважав, що визначення "google" для цього терміна є корисним, я б не розміщував тут. Я хотів кращого опису (подібного до навчального посібника) із прикладами.
void.pointer

3
@Robert - Я думаю, я не розумію, чому ти не розумієш.
ChaosPandion

2
Спочатку я прочитав вашу відповідь, це було не зовсім зрозуміло. Прочитавши відповідь, яка зараз позначена як моя відповідь, стало дуже зрозуміло, що означає "ідіоматичний", і я зараз це розумію. Тепер, коли я прочитав вашу відповідь, це має сенс. Однак ти не переглянув мене прикладами та різними сценаріями, тому я вважаю, що ваша відповідь не була такою корисною. Ви дали відповідь "вебстеру", що технічно правильно, але не корисно, наскільки мені допомагає зрозуміти. Я вдячний за вашу допомогу.
void.pointer

7

Ідіоматичне в контексті програмування зазвичай можна визначити як "найбільш природний спосіб виразити щось мовою"

Я бачу, що слово ідіоматичне особливо часто зустрічається в Рубі. У Ruby є величезні можливості метапрограмування, і для написання ідіоматичного коду Ruby зазвичай потрібно використовувати ці.

Зауважте, що те, що фрагмент коду є ідіоматичним, не означає, що він чистий або навіть стислий. Багато разів ви повинні йти на компроміси.

Так, в основному, ідіоматичний найчастіше відноситься до найпоширенішого способу написати щось мовою, часто це стосується "сленгу" (ідіоми). Якщо фрагмент коду не є ідіоматичним, він може бути ідеально читабельним, стислим, чистим і правильним, але він може почуватися / виглядати незручно у використаній мові. Перевага смаку щодо того, чи було б переписання такого фрагмента коду ідіоматичним, насправді було б хорошою справою, і про це треба судити залежно від конкретного випадку.

Наприклад, ідіоматична англійська може залежати від регіону. Використання цього слова bum, ймовірно, потрібно для ідіоматичної англійської англійської мови, тоді як buttвона більше підходить для англійської США. (Я сумно не знаю англійської англійської мови Великобританії: /)


Дякую (прихильно), я думаю, що ваше визначення потрапило прямо на місце для мене!
Ашаман Кінгпін

3

Найкращий приклад, який я можу придумати, зверху голови, для того, що є ідіоматичним, походить від Рубі.

Для багатьох мов ви можете повторити:

for( start; end; increment){
    code;
}

Або щось дуже схоже. Багато мов також мають foreach(x in SetOfXes)конструкцію. Але ідіоматична для Рубі ітерація включає в себе такі речі, як:

collection.each do |current|
  current.do_stuff
end

і навіть

10.times do |x|
  puts x
end

Я вважаю це ідіоматичним, оскільки вони представляють спосіб робити щось менш поширене, і це щось є в основі філософії його області. У Рубі є філософія взаємодії з об'єктами, яка, хоча і не є унікальною, не є всюдисущою.

На смисловій ноті, коли я чую слово ідіоматичний, мій мозок автоматично завершує думку як "ідіоматичну до ..." - я просто рефлекторно розбираю її як стосується конкретного предмета.


Чим collection.each do |current|відрізняється від foreach(current in collection)? Обидва - це контурні конструкції, встановлені currentдля кожного елемента collection.
MSalters

2

Ідіоми, як правило, є найкращим можливим способом вираження спільної, відносно складної ситуації в мові. Збільшення - це не ідіома чи щось подібне. Використовуючи приріст префікса замість постфікса, ви можете стверджувати, що це ідіома C ++.

Ідіоми - це найкращий спосіб використання мови, визначений експертними користувачами. Справжньою ідіомою C ++ були б об’єкти функцій. Ще одна ідіома - RAII. Ніщо не говорить про те, що ви повинні звільнити ресурси в деструкторі. Але це ідіоматично робити це. Інший приклад - шаблони - ідіоматично використовувати шаблони для, ну, всього, що можна, але ніщо не заважає вам надмірно використовувати спадщину.


Вікіпедія використовувала приріст як приклад, тому саме це я згадував у своєму питанні. Чому ідіоми повинні бути складними? Це не здається частиною визначення, заснованого на інших відповідях.
void.pointer

4
@Robert Dailey: Як збільшення може бути ідіомою? Це частина мови . Ідіоми складають користувачі мови, вони змінюються з часом. Збільшення не є ідіомою, це основна функціональність мови. Беручи до уваги цю логіку, я можу сказати, що будь-яка інша основна мовна функція є ідіомою, і тому кожна програма є ідіоматичною, чого вона не є.
DeadMG

2

Ваше визначення мене не вважає правильним. Ідіома - це спосіб написання чогось, що може бути, а може і не бути можливим в інших мовах, але це звично для цієї мови. Зазвичай це коротше, ніж альтернатива, але це насправді не є вимогою.

Це може бути простіше пояснити, якщо говорити про те, що не є ідіоматичним. На мові C ++ досить ідіоматично писати:

Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p)
{
 // whatever
}

Ще ідіоматичніше писати:

Foo* p; 
if(p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
{
 // whatever
}

Цей код робить саме те саме - деякі люди, які не знайомі з C ++, можуть прочитати його як тестування, щоб побачити, чи p дорівнює тому, що функція повертає, але це не те, що робить.

Порівняйте те, що хтось може написати, дуже неідіоматично, хто прийшов з іншої мови:

Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y);
if(p !=NULL)
{
 // whatever
}

Ви також побачите, що цей матеріал вибивається як недіотичний:

if (x>0)
  return true;
else
 return false;

Тому що ідіоматичний підхід є

return (x>0);

Неідіоматичні способи не є помилковими, але вони зазвичай займають більше часу, а для читання завжди потрібно більше часу для тих, хто знає ідіоми. Якщо я називаю вас "хлопчиком, який плакав вовка", і ви знаєте історію, це швидше, ніж якщо б я пояснив, як помилкові тривоги змушують людей ігнорувати вас. Проблема, звичайно, полягає в тому, якщо ви не знаєте історії і не знаєте, що вовки мають спільне з тим, про що ми говоримо. Так само це може бути проблемою, якщо ви ніколи раніше не бачились return x<y;і справді не знаєте, що це робить.


1
Ідіоматичним підходом, безумовно, було б оголосити покажчик у умови if, так що до нього ніколи не можна отримати доступ, якщо це не NULL. if(Foo* p = SomeThingThatReturnsAFooPointer(arg, param, x, y))
DeadMG

мм, мабуть. Або на тисячу рядків раніше, оскільки він використовується у всьому цьому блоці. Або у файлі заголовка, оскільки це змінна команда. Я лише декларував це, щоб читачі знали, що це Foo *, ви маєте рацію, що в реальному житті його там не декларували.
Кейт Григорій

1

Коли існує кілька способів виразити щось, найпоширеніший або загальноприйнятий спосіб. Наприклад, використання структурованого оператора в C замість точного еквівалента з використанням операторів goto.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.