Рубрика «generics»

PHP Generics. Right here. Right now - 1

Многие PHP разработчики хотели бы видеть в PHP поддержку дженериков, и я в том числе. RFC по их добавлению был создан ещё в 2016 году, но до сих пор не принял окончательный вид. Я рассмотрел несколько вариантов решений поддержки дженериков в синтаксисе PHP, но не нашёл рабочей версии, которой мог бы воспользоваться обычный разработчик.

В итоге я решил, что могу сам попробовать реализовать такое решение на PHP. Скриншот выше — реальный пример того, что у меня получилось.

Если хочется сразу попробовать, то вот библиотека mrsuh/php-generics и репо, в котором можно поиграться.

Читать полностью »

func Map[F, T any](s []F, f func(F) T) []T {
    r := make([]T, len(s))
    for i, v := range s {
        r[i] = f(v)
    }
    return r
}

Как вы уже наверняка знаете, proposal по дженерикам в Golang принят (официально это называется type parameters) и будет имплементирован в go 1.18. Бета будет доступна уже в конце этого года. А это значит, что пора разобраться, на чём в итоге остановились разработчики языка — ведь черновик type parameters постоянно менялся в течение последних лет.

Технология новая, на практике толком никто не использовал. Поэтому если увидите какую-то неточность в статье, не стесняйтесь указать это в комментариях.

Самостоятельно поиграться с дженериками можно здесь

Итак, поехали.

Читать полностью »

Unsafe generic math in C# - 1

К сожалению, адекватно перевести название затеянного мной безобразия на русский язык оказалось не просто. С удивлением я обнаружил, что официальная документация MSDN называет "дженерики" "шаблонами" (по аналогии с C++ templates, я полагаю). В попавшемся мне на глаза 4-м издании "CLR via C#" Джеффри Рихтера, переведенном издательством "Питер", дженерики именуются "обобщениями", что гораздо лучше отражает суть понятия. В этой статье речь пойдет о небезопасных обобщенных математических операциях в C#. Учитывая, что C# не предназначен для высокопроизводительных вычислений (хотя, безусловно, на это способен, но не в состоянии тягаться с тем же C/C++), математическим операциям в BCL уделено не так много внимания. Давайте попробуем упростить работу с базовыми арифметическими типами силами C# и CLR.

Читать полностью »

Недавно я столкнулся с ситуацией, что замена Object на var в программе на Java 10 приводит к исключению в процессе выполнения. Мне стало интересно, много ли разных способов добиться такого эффекта, и я обратился с этим вопросом к сообществу:

Оказалось, что добиться эффекта можно разными способами. Хотя все они несильно сложные, но на примере такой задачки интересно вспомнить о разных тонкостях языка. Давайте посмотрим, какие удалось найти способы.

Читать полностью »

Модели дженериков и метапрограммирования: Go, Rust, Swift, D и другие - 1

В некоторых сферах программирования нормально хотеть написать такую структуру данных или алгоритм, которые могут работать с элементами разных типов. Например, список дженериков или алгоритм сортировки, которому нужна только функция сравнения. В разных языках предложены всевозможные способы решения этой задачи: от простого указания программистам на подходящие общие функции (С, Go) до таких мощных систем дженериков, что они стали полными по Тьюрингу (Rust, C++). В этой статье я расскажу о системах дженериков из разных языков и их реализации. Начну с решения задачи в языках без подобной системы (вроде С), а затем покажу, как постепенное добавление расширений приводит к системам из других языков.
Читать полностью »

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

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

Данная статья покажет, как, используя существующие инструменты, в некоторых случаях с минимальными модификациями, мы можем получить мощь дженериков в PHP уже сейчас.

Читать полностью »

Замыкание обобщенного типа в Rust - 1

В этой короткой статье я расскажу о паттерне в Rust, который позволяет "сохранять" для последующего использования тип, переданный через обобщенный метод. Этот паттерн встречается в исходниках Rust-библиотек и я тоже иногда его использую в своих проектах. Мне не удалось найти в сети публикаций о нем, поэтому я дал ему свое название: "Замыкание обобщенного типа", и в этой статье хочу рассказать, что он из себя представляет, зачем и как его можно использовать.

Читать полностью »

Для чего в Rust есть ассоциированные типы (associated types), и в чём их отличие от аргументов типов (type arguments aka generics), ведь они так похожи? Разве недостаточно только последних, как во всех нормальных языках? У тех, кто только начинает изучать Rust, а особенно у людей, пришедших из других языков ("Это же дженерики!" — скажет умудрённый годами джавист), такой вопрос возникает регулярно. Давайте разбираться.

TL;DR Первые контролирует вызываемый код, вторые — вызывающий.

Читать полностью »

Несколько подводных камней статической типизации в Python - 1

Думаю, мы все потихоньку уже привыкаем, что у Python есть аннотации типов: их завезли два релиза назад (3.5) в аннотации функций и методов (PEP 484), и в прошлом релизе (3.6) к переменным (PEP 526).

Так как оба этих PEP были вдохновлены MyPy, расскажу, какие житейские радости и когнитивные диссонансы подстерегали меня при использовании этого статического анализатора, равно как и системы типизации в целом.

Disclamer: я не поднимаю вопрос о необходимости или вредности статической типизациии в Python. Просто рассказываю о подводных камнях, на которые натолкнулся в процессе работы в статически-типизированном контексте.

Читать полностью »

Да-да, вам не привиделось и вы не ослышались — именно высокого рода. Род (kind) — это термин теории категорий, означающий по сути тип типа [данных].

Но вначале немного лирики.

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

Эта статься — мои пять копеек в этот хайп. Мы рассмотрим валидацию данных в Хаскеле.

Валидация типом

Ранее было рассмотрен пример методики валидации при помощи валидации типом:

type EmailContactInfo  = String
type PostalContactInfo = String

data ContactInfo = EmailOnly EmailContactInfo | 
                   PostOnly PostalContactInfo | 
                   EmailAndPost (EmailContactInfo, PostalContactInfo)

data Person = Person 
  { pName :: String,
  , pContactInfo :: ContactInfo,
  }

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

Валидация данными высокого рода

Данные высокого рода - 1

В этой статье мы посмотрим иной метод валидации — при помощи данных высокого рода.

Пусть у нас есть тип данных:

data Person = Person
  { pName :: String
  , pAge  :: Int
  }

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

Тут можно и поэтому данный метод широко используется среди авторов библиотек на Хаскеле.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js