Здравствуйте, kochetkov.vladimir, Вы писали:
J>>>>Боже... Дай, думаю, посмотрю, что пишут в "Дельфи против СИ++"... I>>Минусы за немерле, а примеры — хорошие.
KV>Минусы за немерле — это как? Я же не виноват, что именно на примере этого языка статика рвет динамику, с чем не согласен-то?
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, kochetkov.vladimir, Вы писали:
I>>>P.S. Щас вот подпись обновится и всё станет ясно
KV>>Ааааа. Я нахожу эту подпись несколько утопичной
I>Опасно ходишь !
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Запрограммируй на С#/С++ конечный автомат какой. Сравни с его реализацией скажем на Питоне или Руби. Сделай выводы. G>>А в чем проблема на C# сделать функцию из IEnumerable<T> в IEnumerable<V> на yield return?
I>Покажи пример автомата.
G>>>>Если уж на то пошло, то большая часть того что пишется в динамике может быть выражена и в статике. Ну конечно зависит от языка. I>>>Может и что ? G>>То что утверждение про "писать в разы больше кода" несостоятельно. I>В разы. Относительно С++ с его указателями так и вовсе в десятки раз.
Ну ты еще с ассемблером сравни.
G>>>>А в случае динамического языка у тебя будет в рантайме выпадать ошибка. Причем выпадать она может не всегда. G>>>>Чтобы получить надежность кода на уровне статического варианта тебе нужно написать для этого дела тест. I>>>Зато в с#, C++ придется городить всякие визиторы. G>>И часто тебе приходится их городить? Я визиторы писал пару раз в жизни всего. Еще несколько раз пользовался готовыми. I>мне вот обходы всякие приходится писать чуть не постоянно
Обходы и визиторы — не одно и то же.
Я тоже часто пишу обходы, мне хватает IEnumerable<T> и Linq.
I>>>В итоге и там и там придется тесты писать G>>В динамических языках придется писать больше тестов для получения того уже уровня надежности кода. I>теоретически
Также как и увеличение кода, про которое ты рассказываешь.
I>>>а основная логика в динамическом языке будет гораздо проще читаться. G>>Опять-таки большая часть логики будет практически одинаково выражаться что в статике, что в динамике. I>теоретически
Также как и увеличение кода, про которое ты рассказываешь.
Можно, но твой код даже не скомпилится, т.к. надо пообъявлять State.A и тд.
Т.е. пока что ты сел в лужу
I>>>>Зато в с#, C++ придется городить всякие визиторы. G>>>И часто тебе приходится их городить? Я визиторы писал пару раз в жизни всего. Еще несколько раз пользовался готовыми. I>>мне вот обходы всякие приходится писать чуть не постоянно G>Обходы и визиторы — не одно и то же. G>Я тоже часто пишу обходы, мне хватает IEnumerable<T> и Linq.
Вот,сильно упрощенный пример. Покажи, как тут Linq поможет
IEnumerable<Vertex> Verteces(Vertex root)
{
var hash = new HashSet<Vertex>();
ListVisitor<Vertex> visitList = null;
Visitor<Vertex> visit = (v) => { hash.Add(v); visitList(v.Childs); };
visitList = (l) => { foreach(var v in l ?? new Vertex[0] ) visit(v); }
visit(root);
return hash;
}
I>>теоретически G>Также как и увеличение кода, про которое ты рассказываешь.
см выше.
I>>>>а основная логика в динамическом языке будет гораздо проще читаться. G>>>Опять-таки большая часть логики будет практически одинаково выражаться что в статике, что в динамике. I>>теоретически G>Также как и увеличение кода, про которое ты рассказываешь.
в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя.
G>>В принципе и на C++ можно такое же сделать.
I>Можно, но твой код даже не скомпилится, т.к. надо пообъявлять State.A и тд. I>Т.е. пока что ты сел в лужу
не включай дурачка, типа сам не догадаешься:
public enum State {A,B,C,D}
public enum Event {W,X,Y,Z}
По объему кода 1-в-1 соответствует тому что ты написан на Ruby.
В принципе и на C++ можно написать с тем же объемом.
I>>>>>Зато в с#, C++ придется городить всякие визиторы. G>>>>И часто тебе приходится их городить? Я визиторы писал пару раз в жизни всего. Еще несколько раз пользовался готовыми. I>>>мне вот обходы всякие приходится писать чуть не постоянно G>>Обходы и визиторы — не одно и то же. G>>Я тоже часто пишу обходы, мне хватает IEnumerable<T> и Linq.
I>Вот,сильно упрощенный пример. Покажи, как тут Linq поможет I>
I>IEnumerable<Vertex> Verteces(Vertex root)
I>{
I> var hash = new HashSet<Vertex>();
I> ListVisitor<Vertex> visitList = null;
I> Visitor<Vertex> visit = (v) => { hash.Add(v); visitList(v.Childs); };
I> visitList = (l) => { foreach(var v in l ?? new Vertex[0] ) visit(v); }
I> visit(root);
I> return hash;
I>}
I>
TreeNumerable.Traverse(root, v => v.Childs ?? new Vertex[0]).Distinct()
Вообще визитор оправдан когда у тебя:
1)очень развесистая иерархия классов
2)она со временем не меняется
3)классы образуют дерево
4)алгоритмы обхода дерева часто меняются
В других случаях есть более простые способы.
Вообще странно что я тебе такое рассказываю.
I>в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя.
Используй комбинаторы.
Здравствуйте, kochetkov.vladimir, Вы писали:
KV>Минусы за немерле — это как? Я же не виноват, что именно на примере этого языка статика рвет динамику, с чем не согласен-то?
Linq здесь ровно один вызов А кода уже больше, чем у меня Вот уж помощь так помощь
G>И твой код сокращается до G>
G>TreeNumerable.Traverse(root, v => v.Childs ?? new Vertex[0]).Distinct()
G>
А код выше куда деть ? Для частного случая у тебя получилось даже больше кода чем у меня А если вдруг окажется, что обход не только сверху вниз и классов в обходе будет больше одного, внезапно окажется, что твой код вообще не нужен
G>Вообще визитор оправдан когда у тебя:
Спасибо за информацию, КО. Только если бы ты не торопился, то не стал бы пороть очевидную чушь.
I>>в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя. G>Используй комбинаторы.
Шо ж ты сам их не показл преимущества этих комбинаторов ? Увлёкся, вероятно
P.S. Похоже, у меня в коде фатальный недостаток — мой код пиcан не тобой
I>Linq здесь ровно один вызов А кода уже больше, чем у меня Вот уж помощь так помощь
1)Это универсальный код, в отличие от твоего, написан один раз и используется всегда
2)Этот код работает лениво, в отличие от твоего
G>>И твой код сокращается до G>>
G>>TreeNumerable.Traverse(root, v => v.Childs ?? new Vertex[0]).Distinct()
G>>
I>А код выше куда деть? Для частного случая у тебя получилось даже больше кода чем у меня А если вдруг окажется, что обход не только сверху вниз и классов в обходе будет больше одного, внезапно окажется, что твой код вообще не нужен
Приведи пример, тогда посмотрим.
G>>Вообще визитор оправдан когда у тебя: I>Спасибо за информацию, КО. Только если бы ты не торопился, то не стал бы пороть очевидную чушь.
Так ты спрашиваешь очевидные вещи и совершаешь банальные ошибки.
I>>>в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя. G>>Используй комбинаторы. I>Шо ж ты сам их не показл преимущества этих комбинаторов ? Увлёкся, вероятно
А Traverse это что по твоему?
I>P.S. Похоже, у меня в коде фатальный недостаток — мой код пиcан не тобой
Нет, фатальный недостаток у тебя в том что ты начинаешь выкручиваться вместо того чтобы понять где ты неправ.
PS. Пойди еще скажи тем кто Rx написал, что они неправы, потому что они написали очень много кода, который позволит сократить твой код на 2 строчки.
Здравствуйте, gandjustas, Вы писали:
I>>Linq здесь ровно один вызов А кода уже больше, чем у меня Вот уж помощь так помощь G>1)Это универсальный код, в отличие от твоего, написан один раз и используется всегда
Твой код для частного случая, когда нужно только по вертексам и только сверху вниз бегать.
G>2)Этот код работает лениво, в отличие от твоего
И ты уверен, что всегда нужна эта ленивость ?
G>>>И твой код сокращается до G>>>
G>>>TreeNumerable.Traverse(root, v => v.Childs ?? new Vertex[0]).Distinct()
G>>>
I>>А код выше куда деть? Для частного случая у тебя получилось даже больше кода чем у меня А если вдруг окажется, что обход не только сверху вниз и классов в обходе будет больше одного, внезапно окажется, что твой код вообще не нужен
G>Приведи пример, тогда посмотрим.
Слишком большой пример получается а ты постоянно спрыгиваешь на свои задачи. В общих чертах примерно так — иерархическая структура, которую нужно обойти при чем некоторые объекты нужно обходить по нескольку раз. Как выделить более менее адекватный пример — пока не знаю и времени на это нет.
I>>>>в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя. G>>>Используй комбинаторы. I>>Шо ж ты сам их не показл преимущества этих комбинаторов ? Увлёкся, вероятно G>А Traverse это что по твоему?
Это частный случай который больше никуде не приспособить
G>PS. Пойди еще скажи тем кто Rx написал, что они неправы, потому что они написали очень много кода, который позволит сократить твой код на 2 строчки.
Здравствуйте, Ikemefula, Вы писали:
I>Здравствуйте, gandjustas, Вы писали:
I>>>Linq здесь ровно один вызов А кода уже больше, чем у меня Вот уж помощь так помощь G>>1)Это универсальный код, в отличие от твоего, написан один раз и используется всегда
I>Твой код для частного случая, когда нужно только по вертексам и только сверху вниз бегать.
Ок, приведи код с визитором, в котором надо как-то по-другому бегать.
G>>2)Этот код работает лениво, в отличие от твоего I>И ты уверен, что всегда нужна эта ленивость ?
Там где не нужна будет я напишу ToList, а ты что сделаешь чтобы получить ленивость в своем коде?
G>>>>И твой код сокращается до G>>>>
G>>>>TreeNumerable.Traverse(root, v => v.Childs ?? new Vertex[0]).Distinct()
G>>>>
I>>>А код выше куда деть? Для частного случая у тебя получилось даже больше кода чем у меня А если вдруг окажется, что обход не только сверху вниз и классов в обходе будет больше одного, внезапно окажется, что твой код вообще не нужен
G>>Приведи пример, тогда посмотрим.
I>Слишком большой пример получается а ты постоянно спрыгиваешь на свои задачи.
Да ну?
Ты привел код, а когда я привел свой вариант, делающий ровно тоже самое, но с большим потенциалом повторного использования и композиции ты сказал:
I>Твой код для частного случая, когда нужно только по вертексам и только сверху вниз бегать.
А до этого пытался оправдать непонятно зачем написанный недовизитор тем что у тебя "еще куча всего".
I>в полном варианте кроме Vertex еще куча всяких классов.
Более того, ты завел разговор о визиторах, хотя зачем там визиторы — так и не смог показать.
I>Зато в с#, C++ придется городить всякие визиторы.
I>В общих чертах примерно так — иерархическая структура которую нужно обойти при чем некоторые объекты нужно обходить по нескольку раз. Как выделить более менее адекватный пример — пока не знаю и времени на это нет.
Ну значит считаем что с визиторами ты сел в лужу, пока не доказано обратного.
I>>>>>в полном варианте кроме Vertex еще куча всяких классов. Как с ними быть — не ясно. А вот в динамие — одна рекурсивная фунцыя. G>>>>Используй комбинаторы. I>>>Шо ж ты сам их не показл преимущества этих комбинаторов ? Увлёкся, вероятно G>>А Traverse это что по твоему? I>Это частный случай который больше никуде не приспособить
1)Не уходи от вопроса. Ты не считаешь Visitor комбинатором?
2)Он позволяет обойти любое дерево, где узел хранит ссылки на потомков
3)Так как обход делается лениво, то это позволяет без проблем комбинировать его с другими
Здравствуйте, gandjustas, Вы писали:
G>>>2)Этот код работает лениво, в отличие от твоего I>>И ты уверен, что всегда нужна эта ленивость ? G>Там где не нужна будет я напишу ToList, а ты что сделаешь чтобы получить ленивость в своем коде ?
Ты свой код сам писал ? foreach что у тебя делает ? Опаньки, ленивость вышла кастрированая Но вообще ленивость в моем случае всегда замедление, что недопустимо в принципе.
G>>>Приведи пример, тогда посмотрим.
I>>Слишком большой пример получается а ты постоянно спрыгиваешь на свои задачи. G>Да ну?
Ну да.
G>Ты привел код, а когда я привел свой вариант, делающий ровно тоже самое, но с большим потенциалом повторного использования и композиции ты сказал:
А для чего в частном случае целая куча кода как у тебя да еще с сайд-эффектами в виде недоленивости и проседания перформанса ?
G>А до этого пытался оправдать непонятно зачем написанный недовизитор тем что у тебя "еще куча всего".
И что тебя смущает ? Код завязан на определенную специфику и нет времени адаптировать его персонально для тебя.
G>Более того, ты завел разговор о визиторах, хотя зачем там визиторы — так и не смог показать.
Выполнять операции над конкретной структурой, это ж очевидно. В операциях оных всегда нужен обход какой нибудь.
I>>Это частный случай который больше никуде не приспособить G>2)Он позволяет обойти любое дерево, где узел хранит ссылки на потомков
Твой вариант удобен только для однородной структуры, т.е. частный случай.
G>3)Так как обход делается лениво, то это позволяет без проблем комбинировать его с другими
Во первых, ленивость у тебя кастрированая. Во вторых, у тебя частный случай. В третьих проблемы в виде проседания перформанса в несколько раз. В четвертых, гнусная отладка получается с твоими "комбинаторами".