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


25

При изучении нового языка программирования вы иногда сталкиваетесь с особенностью языка, которая заставляет вас желать иметь его на других ваших языках программирования, которые вы знаете.

Какие языковые особенности были во время изучения очень нового для вас и того, что вы хотели бы иметь на других языках программирования.

Примером этого являются генераторы в Python или C #. Другие примеры могут включать в себя списки в Python, шаблоны в C ++ или LINQ в .NET или ленивые вычисления в Haskell.

Какие еще полууникальные языковые особенности вы встретили, которые были для вас совершенно новыми и поучительными? Существуют ли другие особенности старых языков программирования, которые были уникальными и вышли из моды?

Ответы:


25

Практически все в Хаскеле

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

И многое другое

PS. Да. Я фанат Хаскелла, если кто-нибудь спросит.


12
Чтобы быть справедливым, вы должны дать ML кредит для большей части этого списка.
Великолепно

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

Любая конкретная причина для понижения?
Мацей Пехотка

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

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

21

Лисп макросы.

Язык макросов Lisp - это Lisp, с несколькими предопределенными синтаксическими функциями для удобства. Используя их, можно добавлять основные функции в язык, такие как выбор стилей ориентации объекта или детерминистическое сопоставление, подобное Прологу, не отвлекаясь от места. Это делает setfвозможным макрос, который является концептуально очень мощным макросом: (setf A B)означает, что при оценке Aвы получите B, и это может быть расширено до любого предела, который вам нравится.

Шаблонное метапрограммирование C ++ способно на подобные вещи, но на языке, который сильно отличается от обычного C ++.


+1 Я надеюсь, что однажды я смогу программировать на диалекте Лисп.
Оливер Вейлер

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

@mlvjr: ты страшный.
Дэвид Торнли

Фактически, это единственная готовая функция, которая вам когда-либо понадобится в языке. С помощью макросов Lisp вы можете добавить все другие возможные функции позже.
SK-logic

18

Декоратор Python.

С помощью декоратора очень легко реализовать запоминание или синхронизацию функций.

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

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 произвели на меня впечатление больше, чем любая другая особенность языка. Они очень красивые и простые!
Адам Пейнтер

Может быть, вы могли бы поделиться простым примером с нами? Я не знаю Python, если честно.
ShdNx

@ShdNx, я только что добавил пример.
Грокус

1
Разве время начала не должно быть вычислено как часть вызова?
детально

14

Приведение к типу void*C. Вы можете преобразовать все в необработанные байты и делать с этими данными все, что хотите .

(Да, в наше время это уникально ...)


1
Объект на .Net языках очень похож. Только более безопасный тип и т. Д.
Мацей Пехотка

Вы можете привести к объекту на многих языках. Основная проблема заключается в том, что многие языки разделяют примитивы и объекты
Casebash

5
@Maciej: даже в .NET вы не можете использовать примитивы для Object. Вы их кладете , а это совсем другой зверь. Кроме того, это все равно совершенно не похоже на приведение к void*...
Дин Хардинг

1
Приведение к PointerPascal и Object Pascal делает то же самое.
Фрэнк Шиарар

1
@DeanHarding: Хорошо - в C у вас есть то, int64_tчто вы не всегда можете безопасно использовать void *(Извините за опоздание - 2 года - ответ).
Мацей Пехотка

12

Урожай в питоне

В Python (и я верю в C #) вы можете определить так называемый генератор, который приостанавливает выполнение функции в yieldоператоре, возвращает значение и при последующих вызовах, перезапускает функцию, где она остановилась (с сохранением состояния между вызовами). Это отлично подходит для генерации длинных списков значений, когда вас интересует только текущее значение функции (что очень часто встречается). Это позволяет вам создавать потенциально бесконечно длинные последовательности, занимая при этом только очень ограниченное пространство в памяти.


1
Доходность уже указана в вопросе.
Тринидад

Это все вплоть до BCPL.
Питер Тейлор

8

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

Я впервые столкнулся с ними в Perl, сразу же полюбил их и удивился, почему на других языках их нет. В настоящее время я думаю, что это уже не так уникально; даже PHP удалось как-то их взломать. Но в то время они были уникальны.


5
Уникальный, если вы рассчитываете вернуться в Lisp, который является вторым старейшим языком программирования. ;-)
Майкл Х.



7

Наборы в Delphi очень полезны, в основном это просто именованный логический массив. Они очень полезны для сохранения формы настроек с 32 флажками. Но у них есть все те же функции теории множеств (т.е. разность, пересечение, объединение).

Я не уверен, что они вышли из моды, но я использую их все время.


Хорошо, но разве это не легко реализовать на Java, например: boolean []?
Марк С

Да, вы можете, но я не думаю, что это так кратко, как: 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;
}

против

(Джава)

/**
 * 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

Я не могу честно сказать, что я не написал достаточно C, чтобы сделать что-то из этого сам, но я работал с другим кодом, который делает.

Когда дело доходит до упаковки смеси различных данных в приложениях, которые манипулируют необработанными битами / байтами, такими как сетевое или двоичное хранилище данных. В строго типизированных языках нет простого способа сделать эквивалент.

Отказ от ответственности:

Хотя в некоторых случаях союзы чрезвычайно полезны, они не встречаются в большинстве языков более высокого уровня, потому что они не безопасны для типов. То есть, вы можете сделать так, чтобы данные отбирались через границы переменных, используя объединения (большое нет, нет в мире безопасных типов). С большой властью приходит большая ответственность.


2
ИМХО по уважительной причине. Переинтерпретация данных - это прекрасный способ выстрелить себе в ногу ( en.wikipedia.org/wiki/Aliasing_(computing) ). Лучше использовать явные преобразования ИМХО. Профсоюзы поступают правильно ИМХО - это алгебраические типы данных.
Мацей Пехотка

@Maciej Я добавил необходимый отказ от ответственности. Хотя я не уверен, точно ли это объясняет опасность использования союзов, так как у меня нет глубоких знаний об их использовании. Я просто знаю, что там, где я видел их использование, код был намного более кратким и с ним легче работать, чем с языковым эквивалентом более высокого уровня.
Эван Плейс

Проблема в том, что C - это «язык более высокого уровня» (просто язык более низкого уровня). Начиная с K & R C он получает множество правил, позволяющих быстрее использовать переносимый код. Цена заключается в том, что компилятор может предполагать разные вещи, а некоторые путать. БОЛЬШАЯ часть unionиспользования безопасна, некоторые хорошо поддерживаются идиомами (хотя технически это не правильно) - см. Cellperformance.beyond3d.com/articles/2006/06/…… (хотя это больше проблем с указателями, союзы могут подделать это).
Мацей Пехотка

Delphi расширил свой recordсинтаксис для поддержки профсоюзов:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
Фрэнк Шиарар

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 за возможность передачи параметра глубоко в списке без необходимости передавать значения для всех необязательных параметров перед ним.
Эсвальд

4

Препроцессор C Вы даже можете написать общий код для разных платформ с - меньше или больше - ifdefs.


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

Я очень доволен ifdef, ifndef и другими.
ern0

3

Objective-C Категории

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

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

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


1
Очень похоже на методы расширения в C #
Casebash

2

Рубин «s инъекционный метод в сочетании с Symbol # to_proc особенностью Ruby 1.9 позволяет одной записи некоторый невероятно краткий (но читаемый) код:

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

который суммирует целые числа от 1 до 10 => 55

Увидев подобные примеры, я захотел изучить Ruby, что я только начал делать.


9
Чтобы быть справедливым, inject - это версия Ruby для fold / foldl / foldr из таких языков, как Lisp, Haskell и т. Д.
mipadi

Я бы не назвал это уникальным.
Дейнит

1
Заголовок вопроса гласит «полууникальный», а не уникальный. Конечно, лаконичность кода, обеспечиваемая комбинацией inject (или map и т. Д.) И Symbol # to_proc, выходит далеко за рамки основных языков, таких как C, Java и C ++.
Тросли

Очень лаконично (и мне это нравится), но я не уверен, что это отличается от чего-то вроде: Enumerable.Range (1, 10) .Aggregate ((s, x) => s + x); из C # или других языков
FinnNk

1

Механизм связывания в JavaFX (RIP). Связывают ключевое слово позволяет связать значение переменной со значением выражения и получать вы избавиться от всех тех , некрасиво Слушатель вообще шаблонного кода.

Хотя JavaFX во многом был неудачным, я нашел много возможностей языка сценариев довольно приятным.


1

Строковые миксины плюс оценка функции времени компиляции в D - довольно уникальная особенность убийцы. Да, технически это две особенности, но настоящая сила заключается в их объединении. С помощью этой комбинации вы можете написать обычные D-функции, которые генерируют код в виде строки во время компиляции, а затем смешать этот код с любой областью видимости, и он будет оцениваться как обычный D-код. Код полностью статически скомпилирован и выполняется точно так же, как если бы он был написан от руки. Эта функция даже используется для обхода нескольких неприятных ситуаций в стандартной библиотеке.


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