Re[3]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 01.04.10 20:42
Оценка: 1 (1) +6
Здравствуйте, Ikemefula, Вы писали:

I>смотрится покрасивше, но это плохой способ.


Это хороший способ. Два плохих я не стал квотить.

I>Потому что например есть кое какиех хелперы и их пристроить сюда никак нельзя.


I>Один из хелперов ты скипнул почему то и заменил на цикл.


Их пристраивать просто не нужно. Не надо в одну кучу валить получение данных и обработку, потом вам за это спасибо скажут.
Re: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 01.04.10 20:02
Оценка: 11 (2) +3
Здравствуйте, Ikemefula, Вы писали:

I>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


Вот такой лучше:

var segments = sr.WorkingSegments.Cast<ServiceSegment>().Concat(sr.ProtectionSegments.Cast<ServiceSegment>());
var connections = from s in segments
                  from p in s.SegmentParcels.Cast<SegmentParcel>
                  let nc = p.NetworkConnection
                  where nc != null
                  select nc;
foreach(var connection in connections)
    Collect(connection, protection);
Re[7]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 12:10
Оценка: -3 :)
Здравствуйте, Ikemefula, Вы писали:

L>>А мне нравится. Имхо, гораздо читабельнее, чем нагромождение extension-методов.


I>Зато к нему надо привыкать, т.к. он менее прозрачный


Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.

L>>А тут как раз этот случай и есть.


I>Нет. Этому коду три года и до сих пор никому это разделение не понадобилось.


Этот код ни разу за 3 года не понадобилось отлаживать?! Не верю.
Re[12]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:35
Оценка: +1 -3
Здравствуйте, dorofeevilya, Вы писали:


I>>Вот если бы это читалось на раз безо всяких спецификацй, тогда было бы прозрачно.

D>Так не получится, поскольку язык программирования — это формальная знаковая система, предназначенная для записи компьютерных программ. Язык программирования определяет набор лексических, синтаксических и семантических правил, задающих внешний вид программы и действия, которые выполнит исполнитель (компьютер) под ее управлением. (википедия)

В данном форуме википедия не сильно приветствуется

D>Не хочешь же ты сказать, что на C# стал писать сразу, как только услышал о нем, не читая не единой книги, статьи и т. д.


Я именно это и хочу сказать. Если надо читать спецификацию, книгу и тд то язык однозначно плох.
Re: Какой код проще, лучше и почему
От: sashar2  
Дата: 04.04.10 06:16
Оценка: -3
Здравствуйте, Ikemefula.

С extensions и/или LINQ синтаксисом вариант в плане читаемости проигрывает. В данном случае можно обойтись foreach. Возможно, стоит части кода вынести в отдельные методы, которые стоит назвать по их смыслу. Ниже приведу пример (только пример ) :

    private void Collect(IService sr, ObjectCategories protection)
    {
      foreach (NetworkConnection networkConnection in GetServiceConnections(sr))
        Collect(networkConnection, protection);
    }

    private IEnumerable<NetworkConnection> GetServiceConnections(IService service)
    {
      List<NetworkConnection> networkConnections = new List<NetworkConnection>();

      foreach (ServiceSegment segment in GetServiceSegments(service))
        foreach (NetworkConnection networkConnection in GetSegmentConnections(segment))
          networkConnections.Add(networkConnection);

      return networkConnections;
    }

    private IEnumerable<ServiceSegment> GetServiceSegments(IService service)
    {
      List<ServiceSegment> segments = new List<ServiceSegment>();

      foreach (ServiceSegment item in service.WorkingSegments)
        segments.Add(item);
      foreach (ServiceSegment item in service.ProtectionSegments)
        segments.Add(item);

      return segments;
    }

    private IEnumerable<NetworkConnection> GetSegmentConnections(ServiceSegment segment)
    {
      List<NetworkConnection> networkConnections = new List<NetworkConnection>();

      foreach (SegmentParcel parcel in segment.SegmentParcels)
        if (parcel.NetworkConnection != null)
          networkConnections.Add(parcel.NetworkConnection);

      return networkConnections;
    }


Можно частично перенести на linq extensions:

    private void Collect(IService sr, ObjectCategories protection)
    {
      foreach (NetworkConnection networkConnection in GetServiceConnections(sr))
        Collect(networkConnection, protection);
    }

    private IEnumerable<ServiceSegment> GetServiceSegments(IService service)
    {
      return Enumerable.Concat(service.WorkingSegments, service.ProtectionSegments);
    }

    private IEnumerable<NetworkConnection> GetServiceConnections(IService service)
    {
      return GetServiceSegments(service).SelectMany(s => GetSegmentConnections(s));
    }

    private IEnumerable<NetworkConnection> GetSegmentConnections(ServiceSegment segment)
    {
      return segment.SegmentParcels.Select(s => s.NetworkConnection).Where(s => s != null);
    }
Re[6]: Какой код проще, лучше и почему
От: Ziaw Россия  
Дата: 05.04.10 17:10
Оценка: 5 (1) +1
Здравствуйте, Ikemefula, Вы писали:

I>почему тогда не так ?


тогда уж

return items.FirstOrDefault(item => criteria.All(spec => spec.IsMetBy(item)));
Re[5]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 11:54
Оценка: 1 (1) +1
Здравствуйте, gandjustas, Вы писали:

G>1)Количеством строк.

G>2)FirstOrDefault гораздо понятнее, чем использование break. FirstOrDefault лучше отражает суть того что происходит.
G>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.

почему тогда не так ?

return items.Where(item => criteria.All(spec => spec.IsMetBy(item))).FirstOrDefault();
Re[5]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 10:01
Оценка: +1 -1
Здравствуйте, Nose, Вы писали:

N>intention лучше выражен.


Е-мое, сколько новых модных слов появилось, у тебя intention, у gandjustas'а composition. А разъяснить что эти слова значат можете?
Re[10]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 12:45
Оценка: +1 -1
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:


G>>Это ты как раз написал способ превращения императивного кода в функциональный ленивый список.


I>Просто ленивый список, никакой он не фунциональный.



G>>Далеко не в каждом языке такое есть.

I>да, придется попотеть и реализовать автомат.
Сильно попотеть...
Re[4]: Какой код проще, лучше и почему
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.04.10 20:24
Оценка: 11 (1)
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, samius, Вы писали:


S>>let здесь по-моему лишний. Не тот случай, чтобы запоминать промежуточные значения нужно было.


L>Это уже вопрос личных предпочтений. Я в свою очередь не вижу причин, почему бы не вставить тут let.


Это лишний анонимный тип с лишними экземплярами. Они оправданы, когда за let-ом нужны наборы значений s, p и nc, либо когда вычисленное значение нужно закэшировать. А т.к. нужно лишь значение nc, притом что p.NetworkConnection вряд ли нужно кэшировать, то на мой взгяд let не оправдан.
Re[8]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 08.04.10 05:31
Оценка: 4 (1)
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Undying, Вы писали:


U>>>Я не требую реализовывать функционально конкретно этот алгоритм (это просто пример задачи со сложным промежуточным состоянием), но мне было бы интересно увидеть решение любой вашей задачи со сложным промежуточным состоянием в чисто функциональном стиле.


G>>на haskell.


U>Haskell я к сожалению не понимаю, поэтому мне сложно что-то сказать по этому коду. А на шарп это легко переписывается?


Если забить на ленивость, то в 2 раза по объему больше будет.


public class Pos
{
    public double X { get; set; }
    public double Y { get; set; }
}

public class TrackItem
{
    public Pos Pos { get; set; }
    public DateTime Time { get; set; }
}

public enum StationPassStatus
{
    InTime, Late, Early, NotPassed
}

public static class EnumeraleExtensions
{
    public static Tuple<IEnumerable<T>, IEnumerable<T>> Span<T>(this IEnumerable<T> seq, Func<T, bool> pred)
    {
        return Tuple.Create(seq.TakeWhile(pred), seq.SkipWhile(pred));
    }

    public static IEnumerable<S> Scan<T, S>(this IEnumerable<T> seq, S seed, Func<T, S, S> f)
    {
        var state = seed; //Вот тут происходит передача состояния
        foreach (var e in seq)
        {
            yield return state;
            state = f(e, state);
        }
    }
}

public static class TrackExtensions
{
    public static double Dist(Pos p1, Pos p2)
    {
        var x = p1.X - p2.X;
        var y = p1.Y - p2.Y;
        return Math.Sqrt(x * x - y * y);
    }

    public static Tuple<IEnumerable<TrackItem>, IEnumerable<TrackItem>> 
            GetTrackSegmentWithinRadius(this IEnumerable<TrackItem> track, Pos pos, double radius)
    {
        return track.SkipWhile(t => Dist(t.Pos, pos) > radius)
                    .Span(t => Dist(t.Pos, pos) <= radius);
    }

    public static StationPassStatus GetStationPassStatus
        (this IEnumerable<TrackItem> track, DateTime stationTime)
    {
        if (!track.Any())
        {
            return StationPassStatus.NotPassed;
        }
        else
        {
            var times = track.Select(t => t.Time);
            var min = times.Min();
            var max = times.Max();

            //Супер-логика
            return StationPassStatus.InTime; 
        }

    }
}

class Program
{
    static Pos[] stations = new Pos[] { ... };

    static IEnumerable<Tuple<int, StationPassStatus>> GetScheduleDiff
        (IEnumerable<Tuple<int,DateTime>> schedule, 
         IEnumerable<TrackItem> track,
         double radius)
    {
        return schedule.Scan(new { Track = track, StationId = 0,  Status = StationPassStatus.NotPassed}, 
                            (st, s) =>
                            {
                                var r = s.Track.GetTrackSegmentWithinRadius(stations[st.Item1], radius);
                                var status = r.Item1.GetStationPassStatus(st.Item2);
                                return new { Track = r.Item2, StationId = st.Item1, Status = status };
                            })
                        .Select(t => Tuple.Create(t.StationId, t.Status))
                        .Skip(1);
    }
}
Re[2]: Какой код проще, лучше и почему
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.04.10 20:07
Оценка: 1 (1)
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, Ikemefula, Вы писали:


I>>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


L>Вот такой лучше:


L>
L>var connections = from s in segments
L>                  from p in s.SegmentParcels.Cast<SegmentParcel>
L>                  let nc = p.NetworkConnection
L>                  where nc != null
L>                  select nc;
L>

let здесь по-моему лишний. Не тот случай, чтобы запоминать промежуточные значения нужно было.
var connections = from s in segments
                  from p in s.SegmentParcels.Cast<SegmentParcel>
                  where p.NetworkConnection != null
                  select p.NetworkConnection;
Re: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 05:10
Оценка: 1 (1)
Здравствуйте, Ikemefula, Вы писали:

I>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


Лучше всего так:

    private void Collect(IService sr, ObjectCategories protection)
    {
      IEnumerable<ServiceSegment> segments = _.Combine(sr.WorkingSegments, sr.ProtectionSegments);

      foreach (ServiceSegment segment in segments)
      {
        foreach (SegmentParcel parcel in segment.SegmentParcels)
        {
          if (parcel.NetworkConnection != null)
            Collect(parcel.NetworkConnection, protection);
        }
      }
    }


В этом варианте и лишних сущностей не появляется (в отличие от первого варианта) и по лаконичности он первому варианту не уступает.
Re[6]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 12:02
Оценка: 1 (1)
Здравствуйте, Ikemefula, Вы писали:

I>почему тогда не так ?

I>return items.Where(item => criteria.All(spec => spec.IsMetBy(item))).FirstOrDefault();

Кстати да, в таком виде очень неплохо смотрится. Непонятно зачем вместо этого кучу from, in, select и where городить.
Re[6]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 09:50
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>1)Количеством строк.


U>И с каких это пор скобочки стали учитываться при подсчете строк?


С тех пор как текст программ начали читать

G>>2)FirstOrDefault гораздо понятнее, чем использование break. FirstOrDefault лучше отражает суть того что происходит.


U>Издеваешься? FirstOrDefault это вообще крайне опасная операция, т.к. если match у нас, к примеру, int, то в случае пустого массива получим 0, который можно очень долго по коду отлавливать.

А с break что получишь? Тот же самый 0 при наивной реализации или придется более сложные конструкции городить.

G>>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.

U>С каких это пор создание лишних сущностей стало достоинством кода?
Это называется страшным словом composition. Чем выше возможности композиции тем лучше, это всегда так было.
Re[10]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 10:37
Оценка: +1
Здравствуйте, Silver_s, Вы писали:

S_>
S_>public static T? FirstOrNull<T>(this IEnumerable<T> en) where T: struct
S_>{
S_>    return en.Count() > 0 ? (T?)en.First() : null;
S_>}
S_>


Плохо, т.к. надо постоянно помнить с коллекцией структур или с коллекцией классов происходит работа. Вот если бы к этой функции можно было добавить функцию для классов с тем же именем:

public static T FirstOrNull<T>(this IEnumerable<T> en) where T: class
{
}


то было бы нормально. Однако фиг, компилятор этого сделать не даст.
Re[8]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 10:59
Оценка: :)
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>А с break что получишь? Тот же самый 0 при наивной реализации или придется более сложные конструкции городить.


U>Каким это таким образом этот код запишет в match 0 при отсутствии item'ов удовлетворяющих критерию?


U>
U>      int? match = null;
U>      foreach (var item in items)
U>      {
U>        if (criteria.All(criterion => criterion.IsMetBy(item)))
U>        {
U>          match = item;
U>          break;
U>        }
U>      }
U>


Думаешь сложно сделать преобразование к int? в коде с Linq?
Re[4]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 11:45
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

I>>смотрится покрасивше, но это плохой способ.


L>Это хороший способ. Два плохих я не стал квотить.


Еще мне не нравится sql-подобный синтаксис Сильно неясно, зачем его воткнули в язык.

I>>Один из хелперов ты скипнул почему то и заменил на цикл.


L>Их пристраивать просто не нужно. Не надо в одну кучу валить получение данных и обработку, потом вам за это спасибо скажут.


Я разделяю только кода это действитльно нужно. Т.е. когда мне на момент написания кода это необходимо.
Re[5]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 11:50
Оценка: +1
Здравствуйте, Ikemefula, Вы писали:

L>>Это хороший способ. Два плохих я не стал квотить.


I>Еще мне не нравится sql-подобный синтаксис Сильно неясно, зачем его воткнули в язык.


А мне нравится. Имхо, гораздо читабельнее, чем нагромождение extension-методов.

I>>>Один из хелперов ты скипнул почему то и заменил на цикл.


L>>Их пристраивать просто не нужно. Не надо в одну кучу валить получение данных и обработку, потом вам за это спасибо скажут.


I>Я разделяю только кода это действитльно нужно. Т.е. когда мне на момент написания кода это необходимо.


А тут как раз этот случай и есть.
Re[6]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:06
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

I>>Еще мне не нравится sql-подобный синтаксис Сильно неясно, зачем его воткнули в язык.


L>А мне нравится. Имхо, гораздо читабельнее, чем нагромождение extension-методов.


Зато к нему надо привыкать, т.к. он менее прозрачный

I>>Я разделяю только кода это действитльно нужно. Т.е. когда мне на момент написания кода это необходимо.


L>А тут как раз этот случай и есть.


Нет. Этому коду три года и до сих пор никому это разделение не понадобилось.
Re[8]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 12:15
Оценка: :)
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:


G>>>>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.

U>>>С каких это пор создание лишних сущностей стало достоинством кода?
G>>Это называется страшным словом composition. Чем выше возможности композиции тем лучше, это всегда так было.

I>Вообще говоря и в императивном можно что хошь передать куда хошь.


I>
I>IEnumerable<T> GetBlah(IEnumerable<T> items)
I>{
I>   foreach (T item in items)
I>    if (criteria.All(c => c.IsMetBy(item)))
I>      yield return item;
I>   yield break;
I>}
I>


I>пожалуйста, передавай куда хошь и что хошь.

Это ты как раз написал способ превращения императивного кода в функциональный ленивый список.
Далеко не в каждом языке такое есть.

I>
I>if(!GetBlah(items).MoveNext)
I>   throw new Exception(Res.BlahTargetNotFound);
I>

Это скомпилируется?
Re[10]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:49
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

I>>Читается как текст, а девелоперу надо понимать, что, как будет работать.


L>А что непонятного для девелопера в query-синтаксисе?


Это еще один язык. Для его освоения нужно время.

I>>Не понял, на 20 строчек примитивного кода уже отладчик нужен ? ну и дела.


L>Да иной раз и для одной отладчик крайне желателен.


Это не тот случай. В других случаях будет вот так (сейчас чуть больше кода)

GetRouting(selection).DisposeAll();
...
if (GetRouting(selection).AtLeastOne())
            {
                context.CommandEnabled = true;
                return;
            }


GetRouting — ленивая коллекция, обработка отдельно от сбора была сделана в тот момент, когда понадобилась проверка.
Re: Какой код проще, лучше и почему
От: Silver_s Ниоткуда  
Дата: 02.04.10 12:53
Оценка: +1
Здравствуйте, Ikemefula, Вы писали:

Кстати у Concat не совсем хороший синтаксис получается.
sr.WorkingSegments.Cast<ServiceSegment>()
            .Concat(sr.ProtectionSegments.Cast<ServiceSegment>())
.SelectMany....


Возможно даже так лучше, несмотря на лишние слова. Симметрично.
Enumerable.Concat(
   sr.WorkingSegments.Cast<ServiceSegment>(),
   sr.ProtectionSegments.Cast<ServiceSegment>()
)
.SelectMany...
Re[10]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 19:32
Оценка: +1
Здравствуйте, Silver_s, Вы писали:

S_>>Ну там тоже можно сделать:

S_>> matches.Select(_=>(int?)_).FirstOrDefault()
S_>А если часто такое писать, то лучше аналог такой функции реализовать:
S_>
S_>public static T? FirstOrNull<T>(this IEnumerable<T> en) where T: struct
S_>{
S_>    return en.Count() > 0 ? (T?)en.First() : null;
S_>}
S_>


Во-первых, коллекция может не вернуть Count(), например если это бесконечная коллекция.
Во-вторых, коллекция не обязана всегда возвращать согласованный результат при разных запросах, например если это L2S-запрос, то при определенном уровне изоляции транзакций, первый Count() может вернуть число отличное от 0, но последующий First — ничего не вернуть.

Если уж нужно что-то подобное, то используйте подход как у Dictionary:
public static bool TryFirst<T>(this IEnumerable<T> src, out T value) {
    try {
        value = src.First();
        return true;
    } catch (InvalidOperationException) {
        value = default(T);
        return false;
    }
}


Хотя этот код тоже далек от идеала: InvalidOperationException вполне может быть выброшен не непосредственно First-ом, а коллекцией src.

Вариант с ручным перебором наверное будет-таки "честнее":
foreach (T elem in src){
    value = elem;
    return true;
}
value = default(T);
return false;
Re[15]: Какой код проще, лучше и почему
От: Sinix  
Дата: 03.04.10 02:52
Оценка: +1
Здравствуйте, AndrewVK, Вы писали:

AVK>В нем, скорее всего, проще будет применить FirstOrValue. Ну либо конвертировать в int? matches.

Давно сделал bool TryGetFirst<T>(this IEnumerable<T> source, out T value) и не мучаюсь с семантикой. Для извращённых сценариев (пока не понадобилось) можно изобрести Option<T> или использовать Lazy<T> в 4-м фреймворке (кстати, может там и Option<T> уже есть?).


А развели-то...
Слово К.О.: С null засада в том, что не всегда очевидно что получили: null как допустимое значение или null как "не найдено".
Re[10]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 05.04.10 06:57
Оценка: +1
Здравствуйте, Undying, Вы писали:

L>>С FirstOrNull проблемы никуда не ушли бы, т.к. null — вполне себе допустимое зачение для ссылочного типа, а значит может встретиться в коллекции.


U>И сколько раз в жизни ты писал код, в котором при получении первого элемента требовалось разделять ситуации 1) коллекция пуста 2) в коллекции первый элемент null?


Тогда тем более непонятно зачем вводить FirstOrNull, если он не решает тех проблем, которые есть у FirstOrDefault.
Re: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 07:45
Оценка: :)
Здравствуйте, Ikemefula, Вы писали:

I>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


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

Вот к примеру алгоритм определения прохождения расписания:


      int certifiedStationIndex = -1;
      StationIntervalWithIndex unexpectedInterval = null;

      Dictionary<Tuple2<int, DateTime>, bool> undoneArrivalIntervals = new Dictionary<Tuple2<int, DateTime>, bool>();
      while (!isFinished)
      {
        while (rawArrivals.Count > 0 || rawDepartures.Count > 0)
        {
          JointIntervalData currentInterval = null;
          int currentStationIndex = -1;
          bool isArrivalInterval = CurrentPassingIsArrival(rawArrivals, rawDepartures);
          if (isArrivalInterval)
          {
            currentInterval = rawArrivals.Dequeue();
            currentStationIndex = FindStationIndex(result.StationPassings, certifiedStationIndex,
              currentInterval.Joint.Id, true, currentInterval.BeginTime, limitDelay);
            if (currentStationIndex == -1)
              continue;
            undoneArrivalIntervals[_.Tuple(currentInterval.Joint.Id, currentInterval.BeginTime)] = true;
          }
          else
          {
            currentInterval = rawDepartures.Dequeue();
            if (undoneArrivalIntervals.Remove(_.Tuple(currentInterval.Joint.Id, currentInterval.BeginTime)))
              continue;
            currentStationIndex = FindStationIndex(result.StationPassings, certifiedStationIndex,
              currentInterval.Joint.Id, false, currentInterval.ConclusionTime.Value, limitDelay);
            if (currentStationIndex == -1)
              continue;
          }

          StationPassing currentStation = result.StationPassings[currentStationIndex];
          // транспорт движется запланировано
          {
            if (currentStationIndex == certifiedStationIndex + 1)
            {
              currentStation.Interval = currentInterval;
              certifiedStationIndex++;
              unexpectedInterval = null;
              if (certifiedStationIndex == result.StationPassings.Length - 1)
              {
                isFinished = true;
                break;
              }
              continue;
            }
          }
          ...
        }

        yield return status;
      }


Объясните как такие задачи решать в чисто функциональном стиле?

Соответственно получается, что даже если виртуозно владеешь функциональным стилем, все равно для записи сложных алгоритмов нужно не хуже владеть стилем императивным.
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 08:28
Оценка: -1
Здравствуйте, Ikemefula, Вы писали:

U>>Объясните как такие задачи решать в чисто функциональном стиле?


I>Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.


Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние. Если задача по своему условию требует сложного промежуточного состояния, то рефакторинг здесь помочь ничем не может. Вот мне и хотелось бы увидеть, как в чисто функциональном стиле решаются задачи со сложным промежуточным состоянием.
Re[2]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.04.10 12:23
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Ikemefula, Вы писали:


I>>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


U>Главная проблема чисто функционального подхода, что на нем непонятно как писать сложные алгоритмы.

U>Вот к примеру алгоритм определения прохождения расписания:
По человечески объясни что код делает, уверен что моментально напишут функциональное решение.
Re[11]: Какой код проще, лучше и почему
От: Ziaw Россия  
Дата: 05.04.10 17:03
Оценка: +1
Здравствуйте, Ikemefula, Вы писали:

I>
I>GetRouting(selection).DisposeAll();
I>


Все методы во фреймворке для IEnumerable сделаны как:
1. по возможности ленивы
2. не меняющие состояние перечисления или объектов в нем (хотя это сложно запретить полностью и при большом желании поменять таки можно)

Создавая свои экстеншены которые выглядят и используются также как и библиотечные, но имеющие логику противоположную ленивости и иммутабельности вы рискуете быть непонятыми и люди пользующиеся вашими экстеншенами будут создавать больше ошибок. Lloyd правильно заметил, что не стоит смешивать получение данных и операции над ними. По этому поводу писал Липперт(емнип) и была бурная дискуссия в .NET.

I>
I>if (GetRouting(selection).AtLeastOne())
I>


I>GetRouting — ленивая коллекция, обработка отдельно от сбора была сделана в тот момент, когда понадобилась проверка.

Это Any() изобретено чтоли?
Re[8]: Какой код проще, лучше и почему
От: Silver_s Ниоткуда  
Дата: 07.04.10 13:30
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Объясни каким образом измельчение позволит из императивного кода сделать функциональный?

U>И в чем после этого код станет менее императивным?

Ну так чтобы на низком уровне остались лямбды и цепочки функций из Enumerable, то сомнительно что любой алгоритм можно было так реализовать не ухудшив читабельность.
Но все же когда одна функция заменяется на несколько более маленьких(каждая проще и понятнее исходной), которые последовательно вызываются и передают результат на вход следующей. Это декомпозиция в стиле функциональной.
При этом для функций/алгоритмов плохо поддающихся такой декомпозиции может возникнуть оверхед — некоторые излишества, которые могут только ухудшить ситуацию.
Вот была тема "Закон сохранения сложности", один из моментов там был примерно такой(очень грубо): Когда сложность не превышает какой-то критический уровень, лишние абстракции и какие-то трюки разделения обязанностей,декомпозиции могут только его усложнить и увеличить объем кода. А когда сложность непосильная, на такие трюки,декомпозиции можно пойти, оверхед тоже будет, но общий выигрыш уже положительный. Нелинейные эффекты. Так что для каждого случая индивидуально, в зависимости от конкретных метрик.
Тут кстати приводили небольшие излишества(черезмерное дробление), вроде каждая функция упрощается а общая сложность скорее увеличивается: http://www.rsdn.ru/forum/philosophy/3761260.1.aspx
Автор: sashar2
Дата: 04.04.10


А так чтобы большой и сложный императивный код (который нельзя уже упростить императивно) превращался в маленький и понятный чисто функциональный, таких примеров не так много(по крайней мере не большинство). Мне бы тоже было интересно посмотреть на их список.
Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.04.10 18:58
Оценка:
Просьба вникнуть в код и найти потенциальные ошибки в каждом случае

3.5
    private void Collect(IService sr, ObjectCategories protection)
    {
            sr.WorkingSegments.Cast<ServiceSegment>()
            .Concat(sr.ProtectionSegments.Cast<ServiceSegment>())
            .SelectMany(s => s.SegmentParcels.Cast<SegmentParcel>())
            .Select(p => p.NetworkConnection)
            .Where(nc => (nc != null))
            .Execute(nc => Collect(nc, protection));
     }


2.0
    private void Collect(IService sr, ObjectCategories protection)
    {
      List<ServiceSegment> segments = new List<ServiceSegment>();

      foreach (ServiceSegment item in sr.WorkingSegments)
        segments.Add(item);
      foreach (ServiceSegment item in sr.ProtectionSegments)
        segments.Add(item);

      foreach (ServiceSegment segment in segments)
      {
        foreach (SegmentParcel parcel in segment.SegmentParcels)
        {
          if (parcel.NetworkConnection == null)
            continue;

          Collect(parcel.NetworkConnection, protection);
        }
      }
    }
Re[3]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 01.04.10 20:17
Оценка:
Здравствуйте, samius, Вы писали:

S>let здесь по-моему лишний. Не тот случай, чтобы запоминать промежуточные значения нужно было.


Это уже вопрос личных предпочтений. Я в свою очередь не вижу причин, почему бы не вставить тут let.
Re[5]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 01.04.10 20:28
Оценка:
Здравствуйте, samius, Вы писали:

L>>Это уже вопрос личных предпочтений. Я в свою очередь не вижу причин, почему бы не вставить тут let.


S>Это лишний анонимный тип с лишними экземплярами.


Честно говоря, меня вся эта кухня мало волнует.

S>Они оправданы, когда за let-ом нужны наборы значений s, p и nc, либо когда вычисленное значение нужно закэшировать. А т.к. нужно лишь значение nc, притом что p.NetworkConnection вряд ли нужно кэшировать, то на мой взгяд let не оправдан.


На мой вкус вариант с let читабельнее, но я не настаиваю.
Re[2]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 01.04.10 20:34
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Вот такой лучше:


L>
L>var segments = sr.WorkingSegments.Cast<ServiceSegment>().Concat(sr.ProtectionSegments.Cast<ServiceSegment>());
L>var connections = from s in segments
L>                  from p in s.SegmentParcels.Cast<SegmentParcel>
L>                  let nc = p.NetworkConnection
L>                  where nc != null
L>                  select nc;
L>foreach(var connection in connections)
L>    Collect(connection, protection);
L>


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

Один из хелперов ты скипнул почему то и заменил на цикл.
Re: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 05:54
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


I>3.5

I>
I>    private void Collect(IService sr, ObjectCategories protection)
I>    {
I>            sr.WorkingSegments.Cast<ServiceSegment>()
I>            .Concat(sr.ProtectionSegments.Cast<ServiceSegment>())
I>            .SelectMany(s => s.SegmentParcels.Cast<SegmentParcel>())
I>            .Select(p => p.NetworkConnection)
I>            .Where(nc => (nc != null))
I>            .Execute(nc => Collect(nc, protection));
I>     }
I>


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

      foreach (var ss in new[] { sr.WorkingSegments, sr.ProtectionSegments })
        foreach (ServiceSegment s in ss)
          foreach (SegmentParcel p in s.SegmentParcels)
          {
            if (p.NetworkConnection != null)
              Collect(p.NetworkConnection, protection);
          }


В функциональном варианте 250 символов, в императивном 220, т.е. даже меньше.
Re[2]: Какой код проще, лучше и почему
От: samius Япония http://sams-tricks.blogspot.com
Дата: 02.04.10 05:58
Оценка:
Здравствуйте, Undying, Вы писали:

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


U>
U>      foreach (var ss in new[] { sr.WorkingSegments, sr.ProtectionSegments })
U>        foreach (ServiceSegment s in ss)
U>          foreach (SegmentParcel p in s.SegmentParcels)
U>          {
U>            if (p.NetworkConnection != null)
U>              Collect(p.NetworkConnection, protection);
U>          }
U>


U>В функциональном варианте 250 символов, в императивном 220, т.е. даже меньше.


Твой вариант падает в рантайме на втором foreach-е
Re[2]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 06:22
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Ikemefula, Вы писали:


I>>Просьба вникнуть в код и найти потенциальные ошибки в каждом случае


I>>3.5

I>>
I>>    private void Collect(IService sr, ObjectCategories protection)
I>>    {
I>>            sr.WorkingSegments.Cast<ServiceSegment>()
I>>            .Concat(sr.ProtectionSegments.Cast<ServiceSegment>())
I>>            .SelectMany(s => s.SegmentParcels.Cast<SegmentParcel>())
I>>            .Select(p => p.NetworkConnection)
I>>            .Where(nc => (nc != null))
I>>            .Execute(nc => Collect(nc, protection));
I>>     }
I>>


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


U>
U>      foreach (var ss in new[] { sr.WorkingSegments, sr.ProtectionSegments })
U>        foreach (ServiceSegment s in ss)
U>          foreach (SegmentParcel p in s.SegmentParcels)
U>          {
U>            if (p.NetworkConnection != null)
U>              Collect(p.NetworkConnection, protection);
U>          }
U>


U>В функциональном варианте 250 символов, в императивном 220, т.е. даже меньше.


Тебе повезло с примером. Вот получше пример.
Re[2]: Какой код проще, лучше и почему
От: Muxa  
Дата: 02.04.10 06:48
Оценка:
      IEnumerable<ServiceSegment> segments = _.Combine(sr.WorkingSegments, sr.ProtectionSegments);

а что это за конструкция такая?
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 07:44
Оценка:
Здравствуйте, Muxa, Вы писали:

M>
M>      IEnumerable<ServiceSegment> segments = _.Combine(sr.WorkingSegments, sr.ProtectionSegments);
M>

M>а что это за конструкция такая?

Объединение произвольного количества коллекций.
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 07:47
Оценка:
Здравствуйте, samius, Вы писали:

S>Твой вариант падает в рантайме на втором foreach-е


Да, new[] лучше не использовать, надо так:

      foreach (var ss in new IEnumerable[] { sr.WorkingSegments, sr.ProtectionSegments })
        foreach (ServiceSegment s in ss)
          foreach (SegmentParcel p in s.SegmentParcels)
          {
            if (p.NetworkConnection != null)
              Collect(p.NetworkConnection, protection);
          }
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 08:24
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Тебе повезло с примером. Вот получше пример.


И чем это:

var matches = from item in items 
              where criteria.All(
                criterion=>criterion.IsMetBy(item)) 
              select item;
match = matches.FirstOrDefault();


лучше чем?

      foreach (var item in items)
      {
        if (criteria.All(criterion => criterion.IsMetBy(item)))
        {
          match = item;
          break;
        }
      }
Re[4]: Какой код проще, лучше и почему
От: Nose Россия  
Дата: 02.04.10 08:35
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>Тебе повезло с примером. Вот получше пример.


U>И чем это:


U>
U>var matches = from item in items 
U>              where criteria.All(
U>                criterion=>criterion.IsMetBy(item)) 
U>              select item;
U>match = matches.FirstOrDefault();
U>


U>лучше чем?


U>
U>      foreach (var item in items)
U>      {
U>        if (criteria.All(criterion => criterion.IsMetBy(item)))
U>        {
U>          match = item;
U>          break;
U>        }
U>      }
U>


intention лучше выражен.
Re[4]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 08:46
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>Тебе повезло с примером. Вот получше пример.


U>И чем это:


U>
U>var matches = from item in items 
U>              where criteria.All(
U>                criterion=>criterion.IsMetBy(item)) 
U>              select item;
U>match = matches.FirstOrDefault();
U>


U>лучше чем?


U>
U>      foreach (var item in items)
U>      {
U>        if (criteria.All(criterion => criterion.IsMetBy(item)))
U>        {
U>          match = item;
U>          break;
U>        }
U>      }
U>


1)Количеством строк.
2)FirstOrDefault гораздо понятнее, чем использование break. FirstOrDefault лучше отражает суть того что происходит.
3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.
Re[5]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 09:00
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>1)Количеством строк.


И с каких это пор скобочки стали учитываться при подсчете строк?

G>2)FirstOrDefault гораздо понятнее, чем использование break. FirstOrDefault лучше отражает суть того что происходит.


Издеваешься? FirstOrDefault это вообще крайне опасная операция, т.к. если match у нас, к примеру, int, то в случае пустого массива получим 0, который можно очень долго по коду отлавливать.

G>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.


С каких это пор создание лишних сущностей стало достоинством кода?
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 09:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>А с break что получишь? Тот же самый 0 при наивной реализации или придется более сложные конструкции городить.


Каким это таким образом этот код запишет в match 0 при отсутствии item'ов удовлетворяющих критерию?

      int? match = null;
      foreach (var item in items)
      {
        if (criteria.All(criterion => criterion.IsMetBy(item)))
        {
          match = item;
          break;
        }
      }
Re[4]: Какой код проще, лучше и почему
От: Muxa  
Дата: 02.04.10 10:05
Оценка:
U>Объединение произвольного количества коллекций.
не понял. вы про ф-цию Combine говорите?
я спрашивал что означает конструкция _. (подчерк-точка) с точки зрения языка.
Re[5]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 10:14
Оценка:
Здравствуйте, Muxa, Вы писали:

M>не понял. вы про ф-цию Combine говорите?

M>я спрашивал что означает конструкция _. (подчерк-точка) с точки зрения языка.

class _
{
}
Re[8]: Какой код проще, лучше и почему
От: Silver_s Ниоткуда  
Дата: 02.04.10 10:15
Оценка:
Здравствуйте, Undying, Вы писали:
G>>А с break что получишь? Тот же самый 0 при наивной реализации или придется более сложные конструкции городить.
U>Каким это таким образом этот код запишет в match 0 при отсутствии item'ов удовлетворяющих критерию?

U>
U>      int? match = null;
U>      foreach (var item in items)
U>


Ну там тоже можно сделать:
matches.Select(_=>(int?)_).FirstOrDefault()

Короче бы получилось: from .... (int?)select
Но это гораздо хуже.
Re[9]: Какой код проще, лучше и почему
От: Silver_s Ниоткуда  
Дата: 02.04.10 10:24
Оценка:
S_>Ну там тоже можно сделать:
S_> matches.Select(_=>(int?)_).FirstOrDefault()
А если часто такое писать, то лучше аналог такой функции реализовать:
public static T? FirstOrNull<T>(this IEnumerable<T> en) where T: struct
{
    return en.Count() > 0 ? (T?)en.First() : null;
}
Re[6]: Какой код проще, лучше и почему
От: Muxa  
Дата: 02.04.10 10:30
Оценка:
M>>не понял. вы про ф-цию Combine говорите?
M>>я спрашивал что означает конструкция _. (подчерк-точка) с точки зрения языка.

U>
U>class _
U>{
U>}
U>

а почему не
Some _ = new Some();
?
откуда этот класс изначально взялся. чота я вообще запутался?
Re[9]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 10:32
Оценка:
Здравствуйте, Silver_s, Вы писали:

S_>Ну там тоже можно сделать:

S_> matches.Select(_=>(int?)_).FirstOrDefault()

И еще одну сущность создать? А зачем? Уж лучше как-то так:

if (matches.CountMore(0))
match = matches.First();
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 10:42
Оценка:
Здравствуйте, Muxa, Вы писали:

M>откуда этот класс изначально взялся. чота я вообще запутался?


Кто-то написал, в стандартной библиотеке такого класса нет:

class _
{
  public IEnumerable<T> Combine<T>(params IEnumerable<T>[] collections)
  {
  }
}
Re[6]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 11:06
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Nose, Вы писали:


N>>intention лучше выражен.


U>Е-мое, сколько новых модных слов появилось, у тебя intention, у gandjustas'а composition. А разъяснить что эти слова значат можете?


intention — намерение, суть того что делает код.
composition — композиция, имеется ввиду функциональная, применение одной функции (в общем куска кода) к результату работы другой.
Это наилучший вид композиции, другие виды композиции, например через изменяемое состояние, гораздо хуже.
Re[8]: Какой код проще, лучше и почему
От: Muxa  
Дата: 02.04.10 11:30
Оценка:
U>Кто-то написал, в стандартной библиотеке такого класса нет:

а в первом вашем сообщении _ (подчерк) это имя класса? (тогда метод должен быть статическим)
или экземпляр? (тогда должно присутствовать объявление переменной)
Re[2]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 11:37
Оценка:
Здравствуйте, Undying, Вы писали:

U>
U>      foreach (var ss in new[] { sr.WorkingSegments, sr.ProtectionSegments })
U>        foreach (ServiceSegment s in ss)
U>          foreach (SegmentParcel p in s.SegmentParcels)
U>          {
U>            if (p.NetworkConnection != null)
U>              Collect(p.NetworkConnection, protection);
U>          }
U>


U>В функциональном варианте 250 символов, в императивном 220, т.е. даже меньше.


Твой код не работает потому что ss имеет тип ServiceSegmentCollection [] те. нужен еще один foreach
Re[9]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 11:52
Оценка:
Здравствуйте, Muxa, Вы писали:

M>а в первом вашем сообщении _ (подчерк) это имя класса? (тогда метод должен быть статическим)

M>или экземпляр? (тогда должно присутствовать объявление переменной)

Подчеркивание это тип класса, метод Combine разумеется статический.
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 11:55
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Твой код не работает потому что ss имеет тип ServiceSegmentCollection [] те. нужен еще один foreach


А так работает?

      foreach (var ss in new IEnumerable[] { sr.WorkingSegments, sr.ProtectionSegments })
        foreach (ServiceSegment s in ss)
          foreach (SegmentParcel p in s.SegmentParcels)
          {
            if (p.NetworkConnection != null)
              Collect(p.NetworkConnection, protection);
          }
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 02.04.10 11:58
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>composition — композиция, имеется ввиду функциональная, применение одной функции (в общем куска кода) к результату работы другой.

G>Это наилучший вид композиции, другие виды композиции, например через изменяемое состояние, гораздо хуже.

Это потому что все остальные виды композиции хуже, до недавнего времени среди мэйнстримовских языков не было ни одного функционального?
Re[7]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:01
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>>>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.

U>>С каких это пор создание лишних сущностей стало достоинством кода?
G>Это называется страшным словом composition. Чем выше возможности композиции тем лучше, это всегда так было.

Вообще говоря и в императивном можно что хошь передать куда хошь.

IEnumerable<T> GetBlah(IEnumerable<T> items)
{
   foreach (T item in items)
    if (criteria.All(c => c.IsMetBy(item)))
      yield return item;
   yield break;
}


пожалуйста, передавай куда хошь и что хошь.

if(!GetBlah(items).MoveNext)
   throw new Exception(Res.BlahTargetNotFound);



Более того, если выставляешь API наружу, этот GetBlah придется писать и в императивном и в функциональном стиле.

и здесь в любом случае надо указывать, что GetBlah ленивый и надо кругом это учитывать.
Re[6]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:02
Оценка:
Здравствуйте, Undying, Вы писали:

U>
U>class _
U>{
U>}
U>


Лучше все таки человеческое имя, т.к. _ многие используют для приватных филдов и _. читается похуже
Re[3]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:10
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Тебе повезло с примером. Вот получше пример.


Я взял самый простой пример из имеющихся.
Re[4]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:10
Оценка:
Здравствуйте, Undying, Вы писали:


U>А так работает?


U>
U>      foreach (var ss in new IEnumerable[] { sr.WorkingSegments, sr.ProtectionSegments })
U>        foreach (ServiceSegment s in ss)
U>          foreach (SegmentParcel p in s.SegmentParcels)
U>          {
U>            if (p.NetworkConnection != null)
U>              Collect(p.NetworkConnection, protection);
U>          }
U>


Это я туплю, предыдущий тоже рабочий.
Re[6]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 12:11
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, gandjustas, Вы писали:


G>>1)Количеством строк.

G>>2)FirstOrDefault гораздо понятнее, чем использование break. FirstOrDefault лучше отражает суть того что происходит.
G>>3)В случае Linq matches это объект, который можно куда-то передать или как-то обработать, в случае с циклом такого не выйдет.

I>почему тогда не так ?


I>return items.Where(item => criteria.All(spec => spec.IsMetBy(item))).FirstOrDefault();


В этом случае лучше именно так.
Re: Какой код проще, лучше и почему
От: Константин Л. Франция  
Дата: 02.04.10 12:15
Оценка:
Здравствуйте, Ikemefula, Вы писали:

[]

из этих двух — первый. а так Lloyd правильно заметил про разделение.
Re[8]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.


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

I>>Нет. Этому коду три года и до сих пор никому это разделение не понадобилось.


L>Этот код ни разу за 3 года не понадобилось отлаживать?! Не верю.


Не понял, на 20 строчек примитивного кода уже отладчик нужен ? ну и дела.
Re[9]: Какой код проще, лучше и почему
От: dorofeevilya Россия  
Дата: 02.04.10 12:18
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, Lloyd, Вы писали:


L>>Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.


I>Читается как текст, а девелоперу надо понимать, что, как будет работать.

Существует четкая спецификация, как это работает.
Re[8]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.04.10 12:18
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


G>>composition — композиция, имеется ввиду функциональная, применение одной функции (в общем куска кода) к результату работы другой.

G>>Это наилучший вид композиции, другие виды композиции, например через изменяемое состояние, гораздо хуже.

U>Это потому что все остальные виды композиции хуже, до недавнего времени среди мэйнстримовских языков не было ни одного функционального?


Не прикидывайся, ты прекрасно знаешь что и почему было.
Re[9]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:20
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Это ты как раз написал способ превращения императивного кода в функциональный ленивый список.


Просто ленивый список, никакой он не фунциональный.

G>Далеко не в каждом языке такое есть.


да, придется попотеть и реализовать автомат.

I>>
I>>if(!GetBlah(items).MoveNext)
I>>   throw new Exception(Res.BlahTargetNotFound);
I>>

G>Это скомпилируется?

Нет конечно, я слегка погорячился Нужен энумератор и круглые скобки.
Re[10]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 02.04.10 12:26
Оценка:
Здравствуйте, dorofeevilya, Вы писали:

L>>>Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.


I>>Читается как текст, а девелоперу надо понимать, что, как будет работать.

D>Существует четкая спецификация, как это работает.

Вот если бы это читалось на раз безо всяких спецификацй, тогда было бы прозрачно.

Прозрачность и легкость чтения — это немного разные вещи.
Re[11]: Какой код проще, лучше и почему
От: dorofeevilya Россия  
Дата: 02.04.10 12:31
Оценка:
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, dorofeevilya, Вы писали:


L>>>>Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.


I>>>Читается как текст, а девелоперу надо понимать, что, как будет работать.

D>>Существует четкая спецификация, как это работает.

I>Вот если бы это читалось на раз безо всяких спецификацй, тогда было бы прозрачно.

Так не получится, поскольку язык программирования — это формальная знаковая система, предназначенная для записи компьютерных программ. Язык программирования определяет набор лексических, синтаксических и семантических правил, задающих внешний вид программы и действия, которые выполнит исполнитель (компьютер) под ее управлением. (википедия)

Не хочешь же ты сказать, что на C# стал писать сразу, как только услышал о нем, не читая не единой книги, статьи и т. д.

I>Прозрачность и легкость чтения — это немного разные вещи.
Re[9]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 12:37
Оценка:
Здравствуйте, Ikemefula, Вы писали:

L>>Ты шутишь? query-синтаксис как раз гораздо прозрачнее нагромождения extension-ов. Читается как текст на человеческом английском.


I>Читается как текст, а девелоперу надо понимать, что, как будет работать.


А что непонятного для девелопера в query-синтаксисе?

L>>Этот код ни разу за 3 года не понадобилось отлаживать?! Не верю.


I>Не понял, на 20 строчек примитивного кода уже отладчик нужен ? ну и дела.


Да иной раз и для одной отладчик крайне желателен.
Re[6]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.04.10 15:13
Оценка:
Здравствуйте, Undying, Вы писали:

U>Издеваешься? FirstOrDefault это вообще крайне опасная операция, т.к. если match у нас, к примеру, int


В таких случаях int просто заменяется на int?
... << RSDN@Home 1.2.0 alpha 4 rev. 1466 on Windows 7 6.1.7600.0>>
AVK Blog
Re[7]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 15:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

U>>Издеваешься? FirstOrDefault это вообще крайне опасная операция, т.к. если match у нас, к примеру, int


AVK>В таких случаях int просто заменяется на int?


Где именно? В типе match или в коллекции items?
Re[8]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.04.10 15:40
Оценка:
Здравствуйте, Lloyd, Вы писали:

AVK>>В таких случаях int просто заменяется на int?


L>Где именно? В типе match или в коллекции items?


Где удобнее.
... << RSDN@Home 1.2.0 alpha 4 rev. 1466 on Windows 7 6.1.7600.0>>
AVK Blog
Re[9]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 19:14
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>>>В таких случаях int просто заменяется на int?


L>>Где именно? В типе match или в коллекции items?


AVK>Где удобнее.


И где удобнее в приведенном примере?
Re[10]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.04.10 19:45
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>И где удобнее в приведенном примере?


Каком именно? Здесь массу вариантов приводили.
... << RSDN@Home 1.2.0 alpha 4 rev. 1466 on Windows 7 6.1.7600.0>>
AVK Blog
Re[11]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 20:38
Оценка:
Здравствуйте, AndrewVK, Вы писали:

L>>И где удобнее в приведенном примере?


AVK>Каком именно? Здесь массу вариантов приводили.


В том, который выше по этой ветке.
Re[12]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.04.10 21:49
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>В том, который выше по этой ветке.


Их там тоже не один. Ты можешь конкретный вариант привести?
... << RSDN@Home 1.2.0 alpha 4 rev. 1466 on Windows 7 6.1.7600.0>>
AVK Blog
Re[13]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 02.04.10 22:10
Оценка:
Здравствуйте, AndrewVK, Вы писали:

L>>В том, который выше по этой ветке.


AVK>Их там тоже не один. Ты можешь конкретный вариант привести?


Тот, в котором фигурирует FirstOrDefault.
Re[14]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 02.04.10 22:22
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Тот, в котором фигурирует FirstOrDefault.


В нем, скорее всего, проще будет применить FirstOrValue. Ну либо конвертировать в int? matches.
... << RSDN@Home 1.2.0 alpha 4 rev. 1466 on Windows 7 6.1.7600.0>>
AVK Blog
Re[2]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 04.04.10 06:35
Оценка:
Здравствуйте, sashar2, Вы писали:

S>С extensions и/или LINQ синтаксисом вариант в плане читаемости проигрывает. В данном случае можно обойтись foreach. Возможно, стоит части кода вынести в отдельные методы, которые стоит назвать по их смыслу. Ниже приведу пример (только пример ) :


Это очень тяжелый код. Undying показал самое лучше из императивщины.
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 03:56
Оценка:
Здравствуйте, AndrewVK, Вы писали:

U>>Издеваешься? FirstOrDefault это вообще крайне опасная операция, т.к. если match у нас, к примеру, int


AVK>В таких случаях int просто заменяется на int?


Т.е. если у нас есть коллекция int'ов, то ее надо явно преобразовывать в коллекцию Nullable<int>? Это очень удобно?

Функция FirstOrDefault в фрамеворке это ошибка дизайна, если бы вместо нее были бы функции FirstOrNull для коллекций классов и FirstOrNullable для коллекций структур, то проблем не было бы в принципе.
Re[8]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 05.04.10 06:08
Оценка:
Здравствуйте, Undying, Вы писали:

AVK>>В таких случаях int просто заменяется на int?


U>Т.е. если у нас есть коллекция int'ов, то ее надо явно преобразовывать в коллекцию Nullable<int>? Это очень удобно?


U>Функция FirstOrDefault в фрамеворке это ошибка дизайна, если бы вместо нее были бы функции FirstOrNull для коллекций классов и FirstOrNullable для коллекций структур, то проблем не было бы в принципе.


С FirstOrNull проблемы никуда не ушли бы, т.к. null — вполне себе допустимое зачение для ссылочного типа, а значит может встретиться в коллекции.
Да и с FirstOrNullable — непонятно тогда, как работать с коллекцией nullable-ов, ведь Nullable<T> — сама по себе структура.
Re[9]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 06:25
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>С FirstOrNull проблемы никуда не ушли бы, т.к. null — вполне себе допустимое зачение для ссылочного типа, а значит может встретиться в коллекции.


И сколько раз в жизни ты писал код, в котором при получении первого элемента требовалось разделять ситуации 1) коллекция пуста 2) в коллекции первый элемент null?

Я вот ни разу, и даже задачу где бы это требовалось придумать не могу.
Re[11]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 07:49
Оценка:
Здравствуйте, Lloyd, Вы писали:

U>>И сколько раз в жизни ты писал код, в котором при получении первого элемента требовалось разделять ситуации 1) коллекция пуста 2) в коллекции первый элемент null?


L>Тогда тем более непонятно зачем вводить FirstOrNull, если он не решает тех проблем, которые есть у FirstOrDefault.


Не понял ответа. Если разделять ситуации коллекция пуста и первый элемент коллекции null не требуется, то использовать функции FirstOrNull и FirstOrNullable безопасно, в отличии от функции FirstOrDefault.
Re[2]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.04.10 07:57
Оценка:
Здравствуйте, Undying, Вы писали:

U>Вот к примеру алгоритм определения прохождения расписания:



U>
U>


U>Объясните как такие задачи решать в чисто функциональном стиле?


Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.
Re[12]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 05.04.10 08:21
Оценка:
Здравствуйте, Undying, Вы писали:

L>>Тогда тем более непонятно зачем вводить FirstOrNull, если он не решает тех проблем, которые есть у FirstOrDefault.


U>Не понял ответа. Если разделять ситуации коллекция пуста и первый элемент коллекции null не требуется, то использовать функции FirstOrNull и FirstOrNullable безопасно, в отличии от функции FirstOrDefault.


А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
Re[13]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 09:20
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?


В том что если FirstOrNull подсунуть коллекцию структур компилятор выдаст ошибку, а FirstOrDefault это не просто проглотит, но и в рантайме ошибку мы получим не по месту внесения, а хрен знает где и когда.
Re[8]: Какой код проще, лучше и почему
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.04.10 09:25
Оценка:
Здравствуйте, Undying, Вы писали:

U>Т.е. если у нас есть коллекция int'ов, то ее надо явно преобразовывать в коллекцию Nullable<int>? Это очень удобно?


Обычно в запросе все равно есть проекция, в которой и можно к int? преобразовать заодно.

U>Функция FirstOrDefault в фрамеворке это ошибка дизайна, если бы вместо нее были бы функции FirstOrNull для коллекций классов и FirstOrNullable для коллекций структур, то проблем не было бы в принципе.


Ну так добавь, делов то.
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
AVK Blog
Re[14]: Какой код проще, лучше и почему
От: Lloyd Россия  
Дата: 05.04.10 09:25
Оценка:
Здравствуйте, Undying, Вы писали:

L>>А в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?


U>В том что если FirstOrNull подсунуть коллекцию структур компилятор выдаст ошибку, а FirstOrDefault это не просто проглотит, но и в рантайме ошибку мы получим не по месту внесения, а хрен знает где и когда.


в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?
Re[15]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 09:30
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>в чем отличие поведения FirstOrNull для reference-типов от FirstOrDefault?


Ни в чем. Для коллекций классов FirstOrDefault использовать можно.
Re[4]: 2AVK: С чем несогласен?
От: Undying Россия  
Дата: 05.04.10 10:20
Оценка:
Здравствуйте, Undying, Вы писали:

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


Ты считаешь, что задач со сложным промежуточным состоянием в природе не существует? Или что в функциональном стиле такие задачи решаются легко?

Если второе, то хотелось бы увидеть пример решения задачи со сложным промежуточным состоянием в функциональном стиле.
Re[4]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.04.10 10:26
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, Ikemefula, Вы писали:


U>>>Объясните как такие задачи решать в чисто функциональном стиле?


I>>Сходу сказать сложно. Я с такими алгОритмами начинаю с рефакторинга. После трех-четырех фаз рефакторинга код приобретает декларативный вид. Но опять же, должна быть мотивация этм заняться, ради эстетического удовлетворения я на такое не пойду.


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


Не понял идею.
Re[5]: 2AVK: С чем несогласен?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.04.10 11:00
Оценка:
Здравствуйте, Undying, Вы писали:

U>Ты считаешь, что задач со сложным промежуточным состоянием в природе не существует? Или что в функциональном стиле такие задачи решаются легко?


Я считаю, что в очень многих случаях сложное состояние удается отделить.
А не согласен я со следующим:

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

... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
AVK Blog
Re[5]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 05.04.10 11:05
Оценка:
Здравствуйте, Ikemefula, Вы писали:

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


I>Не понял идею.


Например, по условию задачи нужно хранить следующие промежуточные состояния:

      int certifiedStationIndex = -1; //последняя остановка пройденная по расписанию
      StationIntervalWithIndex unexpectedInterval = null; //остановка пройденная вне очереди (если есть)
      Dictionary<Tuple2<int, DateTime>, bool> undoneArrivalIntervals = new Dictionary<Tuple2<int, DateTime>, bool>(); //остановки, на которые мы в текущий момент уже въехали, но еще из них не выехали


Объясни каким образом рефакторинг поможет избавиться от этих промежуточных состояний?
Re[6]: 2AVK: С чем несогласен?
От: Undying Россия  
Дата: 05.04.10 11:11
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Я считаю, что в очень многих случаях сложное состояние удается отделить.


А что делать в тех случаях (пусть немногих), в которых сложное состояние отделить не удается?

Пример функционального алгоритма работающего со сложным промежуточным состоянием ты привести можешь?

AVK>А не согласен я со следующим:

AVK>

AVK>Проблема сложных алгоритмов, что они имеют сложное промежуточное состояние.


Можно пример сложного алгоритма без сложного промежуточного состояния?
Re[6]: Какой код проще, лучше и почему
От: Silver_s Ниоткуда  
Дата: 05.04.10 11:59
Оценка:
Здравствуйте, Undying, Вы писали:
U>Объясни каким образом рефакторинг поможет избавиться от этих промежуточных состояний?

Всю задачу я не понимаю. Но есть опасения что приведенный кусок кода выдернут из функции которая раз в 5 больше этого куска.
Если для написавшего ее, она легко читается и ее не прийдется менять, то никаких проблем. Если нет то ее лучше было бы как-то измельчить, порубать на более мелкие. Неважно в функциональном стиле или нет. Для алгоритмов как правило всегда существует много вариантов реализации.

Например:Тут вот похоже два потока данных rawArrivals, rawDepartures, каждый оборот внутреннего цикла выдергивает и обрабатывает один элемент либо из первого либо из второго потока. Это уже можно вынести, в отдельную функцию возвращающую перечисление currentInterval, и если надо информацию откуда выдернуто.Небольшая но все-таки декомпозиция. Не факт что это сильно улучшит, остального кода я не видел (да и не стал бы разбираться с пол-тысячей строк).
Интересно было бы только время жизни этих данных. И есть ли какая-то топ-функция у который вполне конкретный вход и выход, которая вызывает остальные функции, и которая скрывает какие-то промежуточные данные(время жизни которых не выходит за пределы этой функции).
Re[7]: 2AVK: С чем несогласен?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 05.04.10 15:11
Оценка:
Здравствуйте, Undying, Вы писали:

U>А что делать в тех случаях (пусть немногих), в которых сложное состояние отделить не удается?


Ах, уже немногих. Это неколько контрастирует с исходным заявлением. Что делать? Думать. Серебрянной пули нет.

U>Можно пример сложного алгоритма без сложного промежуточного состояния?


В каком виде пример? Форматтер исходников в ешарпере сгодится?
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
AVK Blog
Re[12]: Какой код проще, лучше и почему
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 05.04.10 18:21
Оценка:
Здравствуйте, Ziaw, Вы писали:

I>>
I>>if (GetRouting(selection).AtLeastOne())
I>>


I>>GetRouting — ленивая коллекция, обработка отдельно от сбора была сделана в тот момент, когда понадобилась проверка.

Z>Это Any() изобретено чтоли?

Примерно так да, я указал, что этого кода как бы нет, есть немного другой.
Re[12]: Какой код проще, лучше и почему
От: _FRED_ Черногория
Дата: 06.04.10 07:08
Оценка:
Здравствуйте, Ziaw, Вы писали:

I>>GetRouting(selection).DisposeAll();


Z>Все методы во фреймворке для IEnumerable сделаны как:

Z>1. по возможности ленивы
Z>2. не меняющие состояние перечисления или объектов в нем (хотя это сложно запретить полностью и при большом желании поменять таки можно)
Z>Создавая свои экстеншены которые выглядят и используются также как и библиотечные, но имеющие логику противоположную ленивости и иммутабельности вы рискуете быть непонятыми и люди пользующиеся вашими экстеншенами будут создавать больше ошибок. Lloyd правильно заметил, что не стоит смешивать получение данных и операции над ними. По этому поводу писал Липперт(емнип) и была бурная дискуссия в .NET.

ОК, а если тот же DisposeAll не является методом-расширением, то всё ОК?

DisposableHelper.DisposeAll(GetRouting(selection));


Help will always be given at Hogwarts to those who ask for it.
Re[9]: Какой код проще, лучше и почему
От: vdimas Россия  
Дата: 06.04.10 07:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Не прикидывайся, ты прекрасно знаешь что и почему было.


Пока что все знают, что не хуже до сих пор в очень многих разделах современного ПО. И смысл рекламировать тот или иной подход вообще, когда рассматриваются частности?
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 06.04.10 10:34
Оценка:
Здравствуйте, Silver_s, Вы писали:

U>>Объясни каким образом рефакторинг поможет избавиться от этих промежуточных состояний?


S_>Если для написавшего ее, она легко читается и ее не прийдется менять, то никаких проблем. Если нет то ее лучше было бы как-то измельчить, порубать на более мелкие. Неважно в функциональном стиле или нет. Для алгоритмов как правило всегда существует много вариантов реализации.


Объясни каким образом измельчение позволит из императивного кода сделать функциональный?

S_>Например:Тут вот похоже два потока данных rawArrivals, rawDepartures, каждый оборот внутреннего цикла выдергивает и обрабатывает один элемент либо из первого либо из второго потока. Это уже можно вынести, в отдельную функцию возвращающую перечисление currentInterval, и если надо информацию откуда выдернуто.Небольшая но все-таки декомпозиция. Не факт что это сильно улучшит, остального кода я не видел (да и не стал бы разбираться с пол-тысячей строк).


И в чем после этого код станет менее императивным?

S_> Всю задачу я не понимаю. Но есть опасения что приведенный кусок кода выдернут из функции которая раз в 5 больше этого куска.


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

S_> Интересно было бы только время жизни этих данных.


Время жизни от нуля (если на момент вызова функции у нас были данные на конец расписания) до бесконечности (если данные на конец расписания нам еще не пришли).

S_> И есть ли какая-то топ-функция у который вполне конкретный вход и выход, которая вызывает остальные функции, и которая скрывает какие-то промежуточные данные(время жизни которых не выходит за пределы этой функции).


Это и есть топ-функция. На вход она принимает въезды и выъезды на остановки, на выходе возвращает остановки с временем их прохождения.
Re[8]: 2AVK: С чем несогласен?
От: Undying Россия  
Дата: 06.04.10 10:34
Оценка:
Здравствуйте, AndrewVK, Вы писали:

U>>Можно пример сложного алгоритма без сложного промежуточного состояния?


AVK>В каком виде пример? Форматтер исходников в ешарпере сгодится?


Ссылку можно?
Re[9]: 2AVK: С чем несогласен?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 06.04.10 11:04
Оценка:
Здравствуйте, Undying, Вы писали:

U>Ссылку можно?


Ссылку на что? На решарпер?
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
AVK Blog
Re[10]: 2AVK: С чем несогласен?
От: Undying Россия  
Дата: 06.04.10 11:06
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Ссылку на что? На решарпер?


На код, который не имеет промежуточных состояний, но является алгоритмически сложным.
Re[11]: 2AVK: С чем несогласен?
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 06.04.10 11:08
Оценка:
Здравствуйте, Undying, Вы писали:

U>На код, который не имеет промежуточных состояний, но является алгоритмически сложным.


Код ты можешь поглядеть только в декомпиляторе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1469 on Windows 7 6.1.7600.0>>
AVK Blog
Re[3]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 06.04.10 11:16
Оценка:
Здравствуйте, gandjustas, Вы писали:

U>>Главная проблема чисто функционального подхода, что на нем непонятно как писать сложные алгоритмы.

U>>Вот к примеру алгоритм определения прохождения расписания:
G>По человечески объясни что код делает, уверен что моментально напишут функциональное решение.

Контроль расписания транспорта(например, автобуса). Т.е. есть набор остановок с временами когда автобус должен на них находиться (например, остановка А-выезд 7:45, остановка B-прибытие 8:34, остановка B-выезд 8:40, остановка А-прибытие 9:05, остановка А-выезд 9:12 и т.д.). Остановки могут накладываться друг друга. Нужно получить отклонения автобуса от расписания.
Re[4]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.04.10 11:24
Оценка:
Здравствуйте, Undying, Вы писали:

U>Здравствуйте, gandjustas, Вы писали:


U>>>Главная проблема чисто функционального подхода, что на нем непонятно как писать сложные алгоритмы.

U>>>Вот к примеру алгоритм определения прохождения расписания:
G>>По человечески объясни что код делает, уверен что моментально напишут функциональное решение.

U>Контроль расписания транспорта(например, автобуса). Т.е. есть набор остановок с временами когда автобус должен на них находиться (например, остановка А-выезд 7:45, остановка B-прибытие 8:34, остановка B-выезд 8:40, остановка А-прибытие 9:05, остановка А-выезд 9:12 и т.д.).

Так уже лучше.
Какие входные данные? Как определять нахождение автобуса на остановке? В случае непопадания во время прибытия автобус должен простоять положенное время или должен уехать вовремя?

U>Остановки могут накладываться друг друга.

Это как

U>Нужно получить отклонения автобуса от расписания.

В каком виде?
Re[5]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 07.04.10 10:45
Оценка:
Здравствуйте, gandjustas, Вы писали:

U>>Контроль расписания транспорта(например, автобуса). Т.е. есть набор остановок с временами когда автобус должен на них находиться (например, остановка А-прямая 7:45, остановка B-прямая 8:34, остановка B-обратная 8:40, остановка А-обратная 9:05, остановка А-прямая 9:12 и т.д.).


G>Какие входные данные?


Исходные, то что выше + геокоординаты автобуса во времени. В том алгоритме который я приводил, вместо геокоординат автобуса во времени, алгоритм работает с интервалами времен нахождения в пределах остановки (подготавливаемых из геокоординат автобуса во времени другой функцией).

G>Как определять нахождение автобуса на остановке?


Остановка это геокоордината + радиус. Попадание в этот радиус есть признак нахождения автобуса в пределах остановки. Соответственно алгоритм должен отбрасывать ложные проезды остановок (например, двигаясь по прямому маршруту автобус зацепил остановку обратного маршрута), а также определять к какому времени расписания проезд остановки относился.

G>В случае непопадания во время прибытия автобус должен простоять положенное время или должен уехать вовремя?


Это водителю решать. Задача алгоритма честно показать все отклонения автобуса от расписания.

U>>Остановки могут накладываться друг друга.

G>Это как

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

U>>Нужно получить отклонения автобуса от расписания.

G>В каком виде?

В приведенном алгоритме, у нас есть коллекция остановок расписания с планируемыми временами (описанная вверху), итогом работы алгоритма является выставление для каждой остановки реального времени прибытия и отправления.

ps
Я не требую реализовывать функционально конкретно этот алгоритм (это просто пример задачи со сложным промежуточным состоянием), но мне было бы интересно увидеть решение любой вашей задачи со сложным промежуточным состоянием в чисто функциональном стиле.
Re[6]: Какой код проще, лучше и почему
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 07.04.10 13:58
Оценка:
Здравствуйте, Undying, Вы писали:

U>Я не требую реализовывать функционально конкретно этот алгоритм (это просто пример задачи со сложным промежуточным состоянием), но мне было бы интересно увидеть решение любой вашей задачи со сложным промежуточным состоянием в чисто функциональном стиле.


на haskell.
import Data.Time

type Pos = (Double,Double)

dist :: Pos -> Pos -> Double
dist (x1,y1) (x2,y2) = sqrt (x' * x' + y' * y')
                       where x' = x1 - x2
                             y' = y1 - y2

type ScheduleItem = (Int, DiffTime)
type Schedule =  [ScheduleItem]
type Track =     [(Pos, DiffTime)]
type Stations =  [Pos]

stations = [...]::Stations

getTrackSegmentWithinRadius :: Double -> Pos -> Track -> (Track, Track)
getTrackSegmentWithinRadius radius pos track =
    span (\(p,_) ->  dist pos p < radius) $ dropWhile (\(p,_) ->  dist pos p > radius) track


data StationPassStatus = InTime | Late | Early | NotPassed
                         deriving(Eq,Show)

getStationPassStatus :: DiffTime -> Track -> StationPassStatus
getStationPassStatus stationTime segment = 
    if null segment
        then NotPassed
        else
            --Super complex logic
            InTime 
            where times = map snd segment
                  min = minimum times
                  max = maximum times

getScheduleDiff :: Double -> Schedule -> Track -> [(Int, StationPassStatus)]
getScheduleDiff radius s track =
    drop 1 $
    map (\(_,a,b) -> (a,b)) $
    scanr (\(stationId, t) -> \(track,_,_) -> 
        let (seg, track') = getTrackSegmentWithinRadius radius (stations!!stationId) track
            status = getStationPassStatus t seg
        in (track', stationId, status)) (track, 0, NotPassed) s


не очень сложное состояние.

Вся передача состояния делается явно через параметры или неявно с помощью монад.
Re[7]: Какой код проще, лучше и почему
От: Undying Россия  
Дата: 08.04.10 04:37
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Undying, Вы писали:


U>>Я не требую реализовывать функционально конкретно этот алгоритм (это просто пример задачи со сложным промежуточным состоянием), но мне было бы интересно увидеть решение любой вашей задачи со сложным промежуточным состоянием в чисто функциональном стиле.


G>на haskell.


Haskell я к сожалению не понимаю, поэтому мне сложно что-то сказать по этому коду. А на шарп это легко переписывается?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.