Re: Файл
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.09.06 01:53
Оценка: 28 (2) -3
Здравствуйте, <Аноним>, Вы писали:

А>Как такое реализовать на Lisp? Может кто поделится бинарником и какой рантайм и откуда скачать для Windows?


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

А тут можно с места, и как говорится, в карьер.

Код может выглядить, например, так:
using System.Console;
using Nemerle.Utility;
using System.IO;

def strToFind = "partition";
def strs = File.ReadAllLines(@"C:\boot.ini");
WriteLine($"Lines in file: $(strs.Length)");
WriteLine();
WriteLine($"Lines contained '$strToFind':");
WriteLine(strs.ToList().Filter(_.Contains(strToFind)));
ReadLine();

Рельное обеяснение тут пожалуй требует только строка:
WriteLine(strs.ToList().Filter(_.Contains("partition")));

strs.ToList() превращает массив возвращенный стандартной .net-ной фукнцией File.ReadAllLines() в список (односвязанный). Метод Filter() в соотвествии со своим именем отфильтровывает элементы списка удовлетворяющие условию. Условие передается в виде фукнции через параметр. Собственно то что можно передавать фукнции в качестве параметра — это и есть функциональный стиль. Но это можно сделать и в C# 2.0.

А вот '_.Contains(strToFind)' это пожалу самое интересное.
Это так называемое частичное применение функций, да еще и с замыканием. Этот код заменяется на создание невидимой (анонимной) функции. Эта функция захватывает переменную strToFind из контекста где она определена. Знак "_" заменяется параметром этой анонимной функции. Таким образом написав '_.Contains(strToFind)' мы получаем функцию принимающую один аргумент типа "строка" и возращающую булево выражение. То что тип аргумента строка компилятор вычисляет из контекста куда должна передаваться фукнция, а то чт возвращаемое значение должно быть булевым выясняется из возвращаемого значения функции Contains().

Это код можно переписать более явно (и естественно более громоздко):
WriteLine(strs.ToList().Filter(elem => elem.Contains(strToFind)));

данный вариант соотвествует тому что будет доступно в C# 3.0.

А чтобы код уж совсем стал похож на традиционные императивные языки можно переписать его так:
using System.Console;
using Nemerle.Utility;
using System.IO;

def strToFind = "partition";
def strs = File.ReadAllLines(@"C:\boot.ini");
WriteLine($"Lines in file: $(strs.Length)");
WriteLine();
WriteLine($"Lines contained '$strToFind':");
foreach (str in strs)
    when (str.Contains(strToFind))
        WriteLine(str);
ReadLine();
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.