Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
var MyClass = function () {
if (condition) {
BaseClass1.call(this);
} else {
BaseClass2.call(this);
}
}
myClass this
| condition this = baseClass1_call this
| otherwise = baseClass2_call this
class Multi a b where
foo :: a -> b -> IO ()
using System;
public enum Color { R, G, B }
public class Program
{
public static string Puzzle(Color color)
{
switch (color)
{
case Color.R: return "Red";
case Color.G: return "Green";
case Color.B: return "Blue";
default: throw new Exception("impossible"); // Is it really impossible to get here?
// Ask Pex to find out!
}
}
}
static void Main(string[] args)
{
// Неа, компилятор не пустит
Puzzle(10);
// И так компилятор не обмануть
int myColor = 10;
Puzzle(myColor);
// Crazy!
Color color = Color.R + 10;
Puzzle(color);
// Бинарные операции очень удобны для enum. Но, только если там не завелся бинарный баг :D
// Компилятор пропустит и это.
// R = 0 dec; G = 1 dec; B = 2 dec;
// 00b | 01b | 10b == 11b (3 dec)
Color color2 = Color.R | Color.G | Color.B;
Puzzle(color2);
}
дизайн enum'ов в C# — это, пожалуй, самая слабая сторона языка
Далее я выбрал четыре случайных проекта, которые предстояло транслировать с Python на Haskell
В статических C# и F# эта задача решается через dynamic или аналоги, например. И не будет никакого рантаймового оверхеда или рефлекшена
Можно представить, что когда программист пытается создать программу, то он определяет множества, интервалы для переменных, в которых может находиться программа в не ошибочном состоянии. Статическая типизация — это мощный инструмент повышения надежности.
public function do($param) {
assert(is_array($param) || is_string($param));
if (is_string($param) {
$param = [$param];
}
// ...
}
public do(char[] param) {
this->param([a]);
}
public do(char[][] param) {
//...
}
public abstract class JabberPacket : XMapper
{
[XMapTo ("type")]
public abstract string Type { get; set; }
[XMapTo("to")]
public abstract Jid To { get; set; }
[XMapTo ("from")]
public abstract Jid From { get; set; }
[XMapTo ("id")]
public abstract string Id { get; set; }
}
Потом на XElement натравливается метод AsMapper, который генерирует (или берёт уже готовый) класс, реализующий мясо геттеров/сеттеров. Т. е. что-то вроде XDocument.Load(...).Root.AsMapper().Foo. В итоге получается разделение информации о структуре и бизнес-логики, а так же полное отсутствие оверхеда. В принципе, могу этим поделиться и выложить на гитхабе.xml.Picture[0].Country[1].getAttribute(«имярек»)
На PHP $xml->Picture[0]->Country[1]['имярек']
В языках с GC и изоляцией программы от указателей на память динамическая типизация мне кажется странной.
query(Model).filter(Model.name == 'foo').limit(20)count(), достроили с offset().limit() и получили страницу данных.sqlalchemy.func. Для простоты примера, предположим у него нет «своих» функций. Любая попытка получения аттрибута по имени из этого модуля, например sqlalchemy.func.max(Model.name) генерирует вызов функции SQL с переданными параметрами. Для примера выше 'MAX(model.name)'. Очень сильно экономит на кодо-генераторах и размере кода. Сделано оно вменяемо и не влияет на производительность.(в любом случае, она не является такой уж большой — 60 страниц для исследовательской статьи, равно как в ней особо нет и «птичьего языка»
Модульного тестирования недостаточно. Нужна статическая типизация!