Pull to refresh
222
0
Павло @TheShock

Senior JS Developer

Send message
Замена только «свой-чужой» сколько стоила! Это всё на народ легло. Вот такая цена за плюшки для себя.

С другой стороны, ещё один гвоздь в гроб экономики советского союза, так что и тут лучше гражданам сделал.

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

Я вас не понимаю. И что? Вы предлагаете не писать код, который должен исполнятся при переходе в статус CANCELLED?


"Если юзер использует наше приложение не так, как задумал программист — он сам дурак", правильно?

По фактам там отель, а не дворец Путина

Я правильно помню, что это элитный отель, в котором нету туалетов в номерах?

Я бы тогда поднял руку и спросил: "тогда мне ещё непонятно, зачем вы сказали спрашивать тем, кому непонятно?"

Есть ещё одна — "я нифига не понял, потому на всякий случай минус"

Почему из order->cancel() хоть как-то следует копипаста?

Но мне почему-то кажется, что, к примеру, для свопа элементов в linked list и array код свопа тоже разный будет

И это тоже нормально. Вот только на примере СиШарпа для Гоу нужно было бы переопределять своп не LinkedList и ArrayList.


А List<Cat>, List<Dog>, List<Animal> и всех остальных листов. Для каждого возможного Т в листе, который мы хотим сортировать нужно определить три метода.


А если мы хотим сортировать ArrayList<Cat> и LinkedList<Cat>, то для каждого из них — тоже заново написать функцию сравнения котов. Понимаете в чём разница?

Это например касается MobX'a, что с ним якобы большие проблемы, пишете что мутирование объекта это bad practice(что вообще просто нелепо) и бла бла бла.

И подписки обзервбла на обзервбл, на что ответ так и не был дан.

когда один observable может быть подписан на изменения другого

А это как? Ну физически как? В MobX есть @observable — свойства на которые там где-то внутри происходит подписка и @computed — свойства, которые подписываются. Вы не подписываете никакие observable на другие observable.

Зачем тогда вы приводите нормальный код на другом языке как контраргумент к существованию пустых интерфейсов, если этот нормальный код в Go будет использоваться точно так же?

Этот код я привожу как объяснение того, что такое полиморфизм. А пустой интерфейс — это аналог типа object. Вы читайте, пожалуйста, внимательнее.

Сравнение типа писать — нормально. Ведь разные типы вполне могут сравниваться одинаково. Да даже в рамках одного типа сравнение может идти по разному. Строки можно сортировать по алфавиту, по длине, по сумме кодов цифр. Обратите внимание, к сравнивателю я не имел претензий.


А вот свап двух элементов массива писать — глупо. Ведь как два элемента массива между собой поменять — совершенно не зависит от наполнения массива. Это глупый, ненужный копипаст. Разницу улавливаете?


Более того, сам по себе сравниватель должен лежать в клиентском коде, возле самих типов. Ведь типов, которые могут лежать в массиве и по которым может происходить сортировка — бесконечное множество и крайне глупо их все описывать в файлике рядом с сортом.

И конкретно это — абсолютно нормальный код. И конкретно это — полиморфизм. Вот только вы говорите сейчас про совершенно другую механику.
Мы обсуждаем необходимость использования пустого интерфейса в Гоу. В обычном коде на других языках вы врядли встретите постоянное использование object или any, а в Гоу — это в порядке вещей.

Я приведу один пример — модуль sort, который написан авторами гоу и который должен сортировать массивы. Он позволяет отсортировать только массивы из нескольких встроенных массивов — тех, что авторы сами лично определили в библиотеке:


type IntSlice []int
type Float64Slice []float64
type StringSlice []string

То есть да, у вас есть три типа, которые вам можно использовать, а остальные — нет.


Более того, код функции Swap в этих трёх типах был просто продублирован три раза. Да, я совершенно серъёзно, они закопипастили один и тот же код три раза. Более того, чтобы расширить возможности этой библиотеки ещё на другие типы — этот код снова надо копипастить для КАЖДОГО типа, который вы хотите поддержать.


func (x     IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x  StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

В СиШарпе, к примеру, ты можешь сортировать массив из любых элементов, которые реализуют IComparable, ну или передать отдельный IComparer<T> — сравниватель двех элементов.


И, представьте, ничего не копипаститься для каждого нового типа.

Если бы []SomeType удовлетворяло []SomeInterface (при том что SomeType удовлетворяет SomeInterface),

Э нет, всё не так просто. Вы говорите о ковариантности и контравариантности. Нельзя просто так сделать, чтобы оно отвечало, ведь если пойти по одной тропинке — другая будет закрыта.

Чтобы что-то с ним сделать, его нужно принудительно привести к статическому типу.

Вот именно!


И при ошибке типа будет что?
Правильно, ошибка в рантайме.


А ошибка в рантайме при неправильном типе у нас в каких языках?
Правильно, динамических!


А нафига такую хрень вообще использовать?
Правильно, потому что нету дженериков.


Я рад, что мы с вами сошлись.

Ещё раз: вы путаете динамику и полиморфизм

Ничего я не путаю. Способ указать "тут может быть что угодно" ещё не называется полиморфизмом, как и то, что я могу спрыгнуть с горы ещё не означает, что я умею летать, хотя в воздухе какое-то время я, конечно пробуду. То, что оно в гоу называется красивым словом "interface" ещё не означает, что это сразу стало полиморфизмом, а то, что в TypeScript называется словом any — не стало. Более того, сам по себе полиформизм ещё не означает отсутствие динамики. Полиформизм есть точно так же в полностью динамических языках.


Суть полиформизма в том, что вам не нужно уточнять тип, чтобы с ним работать. Ну, к примеру:


interface IFoo {
    void DoSmth();
}

void Method (IFoo foo) {
    foo.DoSmth();
}

class Bar : IFoo {};
class Qux : IFoo {};

Method(new Bar());
Method(new Qux());

Вы видите, что я передаю в метод разные типы, но продолжаю с ними работать как с одним. Это — полиморфизм. А вот использовать мета-тип "any" и потом кастить его к нужному типу и получать исключение — это динамика, а не полиморфизм. Ведь проверка и уточнение типа происходит в рантайме, а не в компайл-тайме.

class Foo {
    public void Test() {}
}

/**
 * Классический строго-типизированный код
 */
public class Static
{

    public void Main()
    {
        Method(new Foo());
    }

    private void Method (Foo foo) {
        foo.Test();
    }

}

Далее — динамический код, при передаче в метод непривального аргумента, например Method(new Bar()); ошибка будет не в компайл тайме, как в статически типизированных языках, а в рантайме, как в динамически типизированных языках и да, это динамически типизированный код на C#


public class Dynamic
{
    public void Main()
    {
        Method(new Foo());
        Method(new Bar()); // we still can
    }

    private void Method (object foo) {
        ((Foo) foo).Test();
    }
}

Information

Rating
Does not participate
Location
Киев, Киевская обл., Украина
Date of birth
Registered
Activity