Напів унікальні особливості мови програмування [закрито]


25

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

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

Прикладом цього є генератори в Python або C #. Інші приклади можуть включати розуміння списку в Python, шаблон у C ++ або LINQ в .NET або ледачу оцінку в Haskell.

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

Відповіді:


25

Практично все, що в Хаскелл

  • Монади. Так - велике страшне слово, яке робить надзвичайно легкими парсери, IO, операції зі списками та інші речі настільки легкими (як тільки ви помітите загальну модель)
  • Стрілки. Те саме для просунутих користувачів;)
  • Стандартні речі, такі як лямбда і т.д.
  • Функції каррінгу
  • Алгебраїчні типи даних
  • Узгодження шаблону

І багато іншого.

PS. Так. Я фанат Haskell, якщо хтось запитав.


12
Для справедливості, ви повинні надати ML кредиту для більшості з цього списку.
чудовий

1
Ну - крім монадів і стріл IIRC. Але вони все ще пів Унікально
Маца Piechotka

Якась конкретна причина для голосування?
Maciej Piechotka

2
+1 для відповідності шаблону. Я показую це іншим людям, а вони не розуміють. Я думаю, що це геній.
Баррі Браун

Обов’язковий ( steve-yegge.blogspot.com/2010/12/… ). До речі, я навряд чи вважаю лямбда унікальними, python, C #, javascript тощо. Монади? Більшість інших мов називають це ланцюжком; Ядро jquery - це по суті один масивний набір HTML / DOM та AJAX монад (Google: jQuery.fn). Каррінг також відносно поширений в наш час.
Еван Плейс

21

Lisp макроси

Мова макросу Lisp - це Lisp, має кілька заздалегідь визначених синтаксичних функцій заради зручності. Використовуючи їх, можна додати основні функції до мови, такі як вибір стилів орієнтації об'єкта або делогічне детерміноване узгодження, подібне до Prolog, не дивлячись поза місцем. Це робить setfмакрос можливим, що є концептуально дуже потужним макросом: (setf A B)означає, що, коли ви оціните, Aви отримаєте B, і це може бути розширено до будь-якої межі, яка вам подобається.

Метапрограмування шаблонів C ++ здатне до подібних речей, але набагато іншою мовою, ніж звичайна C ++.


+1 Я сподіваюся, що одного разу мені вдасться програмувати на діалекті Лісп
Олівер Вайлер

@Helper ... через шаблони C ++ [страшний сміх]
mlvljr

@mlvjr: Вам страшно.
Девід Торнлі

Насправді, це єдина функція, яка вам зараз не потрібна, на мові. За допомогою макросів Lisp ви зможете пізніше додати всі інші можливі функції.
SK-логіка

18

Декоратор Пітона.

Вкрай просто здійснити запам'ятовування або час функціонування за допомогою декоратора.

Приклад таймера функцій.

class FuncTimer(object):
    """ Time how much time a function takes """
    def __init__(self, fn):
        self.fn = fn
        self.memo = {}
        self.start_time = time.time()
    def __call__(self, *args):
        self.memo['return'] = self.fn(*args)
        print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
        return self.memo['return']

Тепер, якщо у вас є функція, яку ви хочете вчасно, ви можете просто зробити це,

@FuncTimer
def foo():
    # foo's implememtation goes here

Ви побачите щось подібне,

Функція "foo" зайняла 3 секунди.


У Java є анотації, які мають подібне призначення та синтаксис, але працюють зовсім інакше
Casebash

1
+1: декоратори Python мене вразили більше, ніж майже будь-яка інша особливість мови. Вони дуже красиві і прості!
Адам Пейнтер

Може, ви могли поділитися простим прикладом з нами? Я не знаю Пітона чесним.
ShdNx

@ShdNx, я просто додав приклад.
grokus

1
Чи не слід обчислювати час початку як частина дзвінка?
detly

14

Передача void*в C. Ви можете передати все на необроблені байти і робити все, що завгодно, за допомогою цих даних.

(Так, сьогодні це унікально ...)


1
Об'єкт у .Net мовах дуже схожий. Тільки більше безпечного типу тощо
Maciej Piechotka,

Ви можете подавати об'єкти на багатьох мовах. Основна проблема полягає в тому, що багато мов розділяють примітиви та об'єкти
Casebash

5
@Maciej: навіть у .NET ви не можете реально кинути примітиви на Object. Ви боксуєте їх, і це зовсім інший звір. До того ж, це все ще зовсім відрізняється від кастингу на void*...
Дін Гардінг

1
Кастинг Pointerу Паскаль та Об'єкт Паскаль робить те саме.
Френк Ширар

1
@DeanHarding: Ну - у вас є C, до int64_tякого не завжди можна сміливо подавати void *(Вибачте за пізнє - 2 роки - відповідь).
Maciej Piechotka

12

Вихід у Python

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


1
Вихід вже вказаний у питанні.
Тринідад

Це іде аж до BCPL.
Пітер Тейлор

8

Лямбда-вирази (закриття, вкладені функції, анонімні методи, як би ви їх не називали).

Я вперше зіткнувся з ними в Перлі, миттєво полюбив їх і задумався, чому інших мов їх немає. Сьогодні я здогадуюсь, це вже не так унікально; навіть PHP вдалося якось їх зламати. Але на той час вони були напів унікальними.


5
Унікальний, якщо ви рахуєтеся повернутися до Lisp, який є другою найстарішою мовою програмування навколо. ;-)
Майкл Х.



7

Набори в Delphi дуже корисні, майже просто названий булевий масив. Вони дуже корисні для збереження форми налаштувань із 32 прапорцями. Але у них є однакові функції теорії множин (тобто різниця, перетин, з'єднання).

Я не впевнений, чи випали вони з моди, але я постійно їх використовую.


Приємно, але чи не просто це реалізувати на Java, наприклад: boolean []?
Марк C

Так, ви можете, але я не думаю, що це так просто, як: TForm = (FF_1500 = 1, FF_CA251 = 5, FF_UB04 = 6, FF_MA10 = 7); TFormSet = набір TForm;
Пітер Тернер

7

Надіслати

Від Ерланга. Надсилає повідомлення асинхронним іншому потоку.

Expr1 ! Expr2

Отримати

Від Ерланга. Отримує повідомлення з іншого потоку.

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

5

C # Властивості

/// <summary>
/// Get ID
/// </summary>
public int ID
{
    get; set;
}

проти

(Java)

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

2
Так, вони кращі, але це поганий приклад. Різниця була б набагато меншою, якби геттер / сетер насправді зробив би щось особливе, а версія C # задокументована менше.
Барт ван Хекелом

1
Мій начальник рішуче проти автоматичних властивостей C # і кожного разу, коли ми маємо аргументи з цього приводу, ніхто з нас не може зрозуміти, чому інший правильний чи неправильний. Я просто люблю їх, тому що вони роблять код набагато чистішим і економить мені багато часу в довгостроковій перспективі.
mbillard

2
Просто не дозволяйте, щоб це спонукало людей мати гетерів та сетерів у всьому. Слід використовувати лише ті геттери та сетери, які мають сенс як дії на об'єкт.
Девід Торнлі

3
Вони не називаються властивостями C #, вони називаються Авто-властивостями
Jaco Pretorius

1
Авто-властивості дуже поширені в наші дні. Python, Objective-C ...
Casebash

5

Союзи в С

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

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

Відмова від відповідальності:

Хоча Союзи вкрай корисні в деяких випадках, їх не можна знайти в більшості мов вищого рівня, оскільки вони не є безпечними для введення. IE, ви можете робити кровотоку даних через межі змінних, використовуючи союзи (великий ні ні в безпечному світі типу). З великою силою настає велика відповідальність.


2
ІМХО з поважної причини. Повторне тлумачення даних - це гарний спосіб стріляти по собі пішки ( en.wikipedia.org/wiki/Aliasing_(computing) ). Краще використовувати явні конверсії IMHO. Профспілки, які працюють правильно, - це алгебраїчні типи даних ІМХО.
Maciej Piechotka

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

Проблема полягає в тому, що C - це "мова більш високого рівня" (просто мова більш високого рівня). Оскільки K&R C отримує масу правил, що дозволяє використовувати швидший портативний код. Ціна полягає в тому, що компілятор може припускати різні речі, а деякі плутати. У більшості випадків unionвикористання є безпечним, деякі добре підтримуються ідіоми (хоча технічно не правильно) - див cellperformance.beyond3d.com/articles/2006/06 / ... (хоча це більше poblem з покажчиками спілок можуть добре підробити).
Мацей П'єхотка

Delphi розширив свій recordсинтаксис, щоб підтримати спілки:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Frank Shearar

5

Мені дуже подобається, якщо не модифікатор в Ruby . Це здається таким природним і замінює безліч сценаріїв, коли ваш код просто здається безладним без нього.

puts "All good" unless input.nil?

Як ти можеш цього не любити? : D


6
Перл мав це до Рубі. Я теж це люблю.
Баррі Браун

1
Nemerle має схожі ключові слова для unlessі whenякі замінюють найбільш поширене розгалуження сценаріїв , які традиційно використовували б if/else.
MattDavey

5

синтаксиси аргументів python

Я не впевнений, наскільки це унікально, але в python ви можете робити цікаві речі, такі як, щоб пари ключових слів автоматично перетворювалися в словник і назад. Те саме зі списками:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print "-- This parrot wouldn't", action,
    print "if you put", voltage, "volts through it."
    print "-- Lovely plumage, the", type
    print "-- It's", state, "!"


parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')

Документи python (прокрутіть униз, щоб отримати більше аргументів)


1
+1 за можливість передавати параметр углиб списку, не маючи передавати значення для всіх необов'язкових параметрів перед ним.
eswald

4

Препроцесор С. Ви навіть можете писати загальний код на різні платформи за допомогою - менше чи більше - ifdefs.


2
Є легші доступні препроцесори, які роблять додатковий крок та працюють з усіма мовами.
Девід Торнлі

Я дуже задоволений ifdef, ifndef та іншим.
ern0

3

Цілі-C категорії

Категорії пропонують простий спосіб розширити функціональність об'єкта під час виконання (мислити склад проти успадкування). Класичний приклад - додати перевірку орфографії до класу NSString.

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

Також корисно для виправлень помилок з низьким впливом, оскільки реалізація методу категорією буде переважати впровадження батьків.


1
Дуже схожий на методи розширення в C #
Casebash

2

Метод введення Ruby в поєднанні з функцією Symbol # to_proc Ruby 1.9 дозволяє написати неймовірно стислий (але все ще читабельний) код:

напр (1..10).inject(:+)

що підсумовує цілі числа від 1 до 10 => 55

Бачачи подібні приклади, змусило мене навчитися Рубі, що я тільки почав робити.


9
Справедливо кажучи, введіть версію Рубі fold / foldl / foldr з таких мов, як Lisp, Haskell тощо.
mipadi

Я б справді не назвав це унікальним.
Daenyth

1
У заголовку питання сказано "напів унікальний", а не унікальний. Безумовно, стислість коду, що забезпечується поєднанням ін'єкції (або карти тощо) та Symbol # to_proc, значно виходить за межі основних мов, таких як C, Java та C ++.
tcrosley

Дуже лаконічно (і мені це подобається), але я не дуже впевнений, що він відрізняється від чогось типу: Перелічувальний.Ранг (1, 10). з C # або інших мов
FinnNk

1

Механізм зв’язування в JavaFX (RIP). Ключове слово " прив'язка" дозволяє прив'язувати значення змінної до значення виразу і позбавляти від усіх цих некрасивих коду слухача будь-якого котла.

Хоча JavaFX багато в чому виявився невдалим, я знайшов багато особливостей мови сценаріїв досить приємною.


1

String mixins плюс оцінка часу функції компіляції в D - це дуже унікальна функція вбивці. Так, технічно це дві особливості, але реальна сила приходить від їх поєднання. За допомогою цієї комбінації ви можете записувати звичайні функції D, які генерують код у вигляді рядка під час компіляції, а потім змішувати цей код у будь-яку сферу дії та оцінювати його як звичайний код D. Код повністю статично складений і виконується точно так, як би він був написаний від руки. Ця функція використовується навіть для вирішення декількох клейких ситуацій у стандартній бібліотеці.


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