Здравствуйте, Аноним, Вы писали:
А>Но сапоги — они тоже разные. Скажем так, появились новые, весьма полезные сегодня сапоги — вдобавок к старым сапогам, несколько иносившимся. НГо это вовсе не первые сапоги
Это стало чрезвычайно актуальным в связи с переходом от количества гигагерц к количеству ядрышек. Армстронг мерял на ультраспарке с 8 процессорами и получил АВТОМАТИЧЕСКОЕ ускорение в 7 с лишним раз.
А>Где-то пробегала ссылка на описание создания сервера карточных игр на Хаскеле и на Эрланге. А>И как раз говорилось что на Эрланге пропали проблемы со взаимодействием потоков. Врут ?
Это про покер-сервер ? Да, мужик так и не смог надежно развязать разные игры на Хаскеле, да и коду много получилось по обьему.
Да, вчера на форуме D еще запостили ( (с) BCS ) забавный способ вычислить есть ли значение в массиве:
import std.stdio;
void main()
{
int[] a = new int[10]; // естественнно, можно вместо int[] писать autoint j=1; // аналогично
// populate aforeach(i, inout k; a) k=i+1;
if({foreach(i;a) if(i==j) return true; return false;}())
writef("true\n");
else
writef("false\n");
}
Попробовал сделать подобное на Nemerle, не получилось (хотя честно сказать, не знаток):
using System;
def a = array(10);
def j = 1;
for(mutable i = 0; i < a.Length; ++i) a[i] = i+1;
//if( { foreach( i in a ) when( i == j ) true false } )if( { foreach( i in a ) when( i == j ) true; false } )
Console.WriteLine("true");
else
Console.WriteLine("false");
Закомментаренное не компилирует, а то что есть возвращает естественно false как последнее выражение.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, Андрей Хропов, Вы писали:
АХ>>Да, вчера на форуме D еще запостили ( (с) BCS ) забавный способ вычислить есть ли значение в массиве:
FR>Похоже я что-то пропустил, разъясни с каких пор D начал подерживать блоки кода? FR>(у меня v0.154 не компилирует)
С 0.161 (см. здесь).
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Попробовал сделать подобное на Nemerle, не получилось (хотя честно сказать, не знаток):
и не должно
в коде
foreach (...)
{
expression
}
expression должен возвращать void
и выходить наобум из блока нельзя
и это хорошо, потому что когда я вызываю foreach, он должен выполниться обазательно для всех элементов контейнера
семантика у него такая
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Попробовал сделать подобное на Nemerle, не получилось (хотя честно сказать, не знаток):
Вот:
// для макроса returnusing Nemerle.Imperative;
using System.Console;
def a = $[0..9]; // или $[0..9].ToArray(), чтобы был именно массив, но здесь не принципиально
def j = 1;
// так называемые блоки кода, aka недофункции :))if (r: { foreach(i in a) when (i==j) r(true); false })
WriteLine("true");
else
WriteLine("false");
// неспортивный вариант, стандартная функция + partial applicationif (a.Exists(_ == j))
WriteLine("true");
else
WriteLine("false");
// полный аналог кода на Dif (() => { foreach(i in a) when (i == j) return true; false })
WriteLine("true");
else
WriteLine("false");
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Попробовал сделать подобное на Nemerle, не получилось (хотя честно сказать, не знаток):
АХ>
АХ>using System;
АХ>def a = array(10);
АХ>def j = 1;
АХ>for(mutable i = 0; i < a.Length; ++i) a[i] = i+1;
АХ>//if( { foreach( i in a ) when( i == j ) true false } )
АХ>if( { foreach( i in a ) when( i == j ) true; false } )
АХ> Console.WriteLine("true");
АХ>else
АХ> Console.WriteLine("false");
АХ>
АХ>Закомментаренное не компилирует, а то что есть возвращает естественно false как последнее выражение.
Что закоментированное, что не закоментированное все одно большое недоразумение. Первый код неверен синтаксически. Воторй семантически. О чем и говорит варнинг при копмпиляции.
Точ то ты хотел изобразить пишется так:
using System.Console;
def a = array(10);
def j = 1;
for(mutable i = 0; i < a.Length; ++i) a[i] = i+1;
if(block: { foreach( i in a ) when ( i == j ) block(true); false } )
WriteLine("true");
else
WriteLine("false");
но это совершенно использование микроскопа (Nemerle) для забивания гвоздей.
На Nemerle подобный код пишется так:
using System.Console;
using Nemerle.Utility;
def ary = array[0,1,2,3,4,5,6,7,8,9];
def j = 3;
WriteLine(NArray.Exists(ary, elem => elem == j));
А по идее вообще так:
using System.Console;
using Nemerle.Utility;
def ary = array[0,1,2,3,4,5,6,7,8,9];
def j = 3;
WriteLine(ary.Exists(elem => elem == j));
Но вот что-то глюкают методы расширения пока что.
Твоя же ошибка заключается в том, что ты думашь, что конструкция:
when (i == j)
true;
это аналог сишного:
if (i == j)
return true;
а это не так. В Немерле ты имешь дело с выражениями. И код:
when (i == j)
true;
просто бесмысленнен. Значние true; просто будет проигнорировано.
Если ты хочешь именно возвратить значение, то нужно:
* Или воспользоваться императивным return, предварительно импортировав его из пространства имен Nemerle.Imperative.
* Или воспользоваться блоками (как показал я).
* Или не волять дурака и пользоваться сильными сторонами языка как, например, фукнциями высшего порядка (как в послдендем примере). При этом код будет на порядок более понятным и безопасным.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, PhantomIvan, Вы писали:
PI>и не должно PI>в коде PI>
PI>foreach (...)
PI>{
PI> expression
PI>}
PI>
PI>expression должен возвращать void PI>и выходить наобум из блока нельзя PI>и это хорошо, потому что когда я вызываю foreach, он должен выполниться обазательно для всех элементов контейнера PI>семантика у него такая
VK>// полный аналог кода на D
VK>if (() => { foreach(i in a) when (i == j) return true; false })
VK> WriteLine("true");
VK>else
VK> WriteLine("false");
VK>
причем у меня самые свежие исходники.
Да, и еще:
if (...)
WriteLine("true");
else
WriteLine("false");
совершенно лишние конструкции. Можно проще жить:
WriteLine(...)
ведь мы в любом случае имеем булеву фукнцию.
Кстати, надо признать, что лично я снова не допер до идеи частичного применения фукнций, хотя это вроде как само собой нарашивалось.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VK>// для макроса return
VK>using Nemerle.Imperative;
А почему Nemerle.Imperative нет ни [url=http://nemerle.org/doc/]здесь[/url] ни [url=http://nemerle.org/Class_library]здесь[/url] ?
Я только обнаружил в Quick guide.
VK>// так называемые блоки кода, aka недофункции :))
VK>if (r: { foreach(i in a) when (i==j) r(true); false })
VK> WriteLine("true");
VK>else
VK> WriteLine("false");
Ага, нашел в Quick guide и [url=http://wiki.nemerle.org/Block]здесь[/url].
Хотя ИМХО, немного извратно. Напоминает Pascal в котором return был в виде присваивания переменной с именем функции.
К тому же true и false возвращаются через разные конструкции здесь.
Лучше наверное r(false) для единообразия?
VK>// неспортивный вариант, стандартная функция + partial application
VK>if (a.Exists(_ == j))
VK> WriteLine("true");
VK>else
VK> WriteLine("false");
Да, это круто :up:.
VK>// полный аналог кода на D
VK>if (() => { foreach(i in a) when (i == j) return true; false })
VK> WriteLine("true");
VK>else
VK> WriteLine("false");
VK>
А где в документации упоминание о таком синтаксисе (=>)?
К тому же здесь как то странно, получается что если в if передать лямбду без параметров она вызовется автоматом?
(к сожалению проверить на самой свежей версии компилятора не могу, у меня че-то svn сегодня заглючил).
Здравствуйте, VladD2, Вы писали:
VD>Твоя же ошибка заключается в том, что ты думашь, что конструкция: VD>
VD>when (i == j)
VD> true;
VD>
VD>это аналог сишного: VD>
VD>if (i == j)
VD> return true;
VD>
VD>а это не так. В Немерле ты имешь дело с выражениями. И код: VD>
VD>when (i == j)
VD> true;
VD>
VD>просто бесмысленнен. Значние true; просто будет проигнорировано.
Да, подумав, я здесь не будет возвращения значения выражения как я думал.
VD>Если ты хочешь именно возвратить значение, то нужно: VD>* Или воспользоваться императивным return, предварительно импортировав его из пространства имен Nemerle.Imperative. VD>* Или воспользоваться блоками (как показал я).
Уже показали, спасибо.
VD>* Или не волять дурака и пользоваться сильными сторонами языка как, например, фукнциями высшего порядка (как в послдендем примере).
Это немного другое.
Если бы в D была функция Exists, то это выглядело бы как
a.Exists( (int i) { return i == j; } );
более многословно, чем вариант на Nemerle, предложенный Vermicious Knid
Кстати я в качестве "документации" и справочника по синтаксису Nemerle очень часто использовал тесты, на которых тестируется компилятор. Очень рекомендую, там используется практически весь набор языковых конструкций.
Здравствуйте, Андрей Хропов, Вы писали:
АХ>А почему Nemerle.Imperative нет ни здесь ни здесь ? АХ>Я только обнаружил в Quick guide.
Наверное потому, что авторы его недолюбливают и не используют.
АХ>Ага, нашел в Quick guide и здесь. АХ>Хотя ИМХО, немного извратно. Напоминает Pascal в котором return был в виде присваивания переменной с именем функции.
В принципе чуть-чуть извратно, да. Но зато очень гибко, так как они могут быть вложенными и встречаться в любом подвыражении. Вот например взятый с потолка образец почти нечеловески сложной логики(в синтаксисе с отступами, чтобы избежать нагромождения фигурных скобок):
def z = fst:
foreach((i, x) in arr0)
def j = snd:
foreach((j, y) in arr1)
if (j == y)
snd(j)
else when(j == x)
fst(y)
snd(42)
if (j == i)
fst(x)
else when (j == x)
fst(i)
fst(42)
Это на самом деле неплохая и гораздо более функциональная замена для break в циклах и позволяет обойтись без лишних функций.
АХ>А где в документации упоминание о таком синтаксисе (=>)?
Честно говоря не знаю. Точно должно быть в new features и других сообщениях о новых релизе. Вообще это синтаксис позаимствован из C# 3.0. Появился он в Nemerle не так давно, а документацию обновить видимо еще не успели.
АХ>К тому же здесь как то странно, получается что если в if передать лямбду без параметров она вызовется автоматом?
Да, признаю, это был неверный код.
Правильно будет либо так:
(() => { foreach(i in a) when (i == j) return true; false })()
Либо так:
fun(){ foreach(i in a) when (i == j) return true; false }()
Здравствуйте, Андрей Хропов, Вы писали:
VD>>* Или не волять дурака и пользоваться сильными сторонами языка как, например, фукнциями высшего порядка (как в послдендем примере). АХ>Это немного другое.
Не — это как раз правильный подход.
Как раз ногромождения кода — это не хорошо. Код должен быть максимально простым.
АХ>Если бы в D была функция Exists, то это выглядело бы как
АХ>
АХ>a.Exists( (int i) { return i == j; } );
АХ>
АХ>более многословно, чем вариант на Nemerle, предложенный Vermicious Knid АХ>
АХ>a.Exists( _ == j )
АХ>
АХ>не спорю.
У D есть кое-какие идеологические проблемы. Например, в нем анонимные функции осуществляют статическое замыкание (термин D-ишный), в то время как все языки полноценно поддерживающие фукнции высшего порядка позволяют делать лексическое замыкание. Это означет, что более сложный код не будет работать.
К тому же Nemerle по примеру C# 3.0 поддерживает методы расширения. Это означает, что методы вроде Exists можно написать самостоятельно.
Ну, а наличие методов подобных Exists в стандарной библиотеке демонстрирует, насколько принятыми для языка являются функции высшего порядка. Разница между D и Nemerlom не в синтаксисе. Разница в идеологической базе. Nemerlom проектировался в рассчете на фунциональный подход (как в прочем и на объектно-ориентированный и компонентный). D же это попытка улучшить С++. Приятно, что D движется в нужном направлении. Но не приятно, что движение хаотично и спонтанно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.