G>>Ок.. Однако у Скалы/Немерле по сравнению с Лиспом/Окамлом я вижу еще 2 преимущества: G>>1. Порог вхождения для программистов на традиционных языках (С++/#/Java) ниже Т>А зато для бывших дельфистов OCaml будет ближе
работал на делфи, работал на с++, на c#
втыкал в одну прогу на окамле
АХ>>у нас есть набор инструментов
а какие это инструменты?
L>Ну и в довесок, даже если бы мощность языка (всё таки абстрактное и субъективное понятие) определяло бы его выбор (что совсем не так, судя по моему опыту), то я бы выбрал не Немерле.
а что?
PI>>но то, что в ней нет макросов для меня на Скале ставит крест
FR>Почему?
потому что я начал проект, где активно использую макросы
постепенно буду его делать, и постепенно буду разбираться в лиспе
очень удобно будет постоянно думать в этом контексте "а как бы я это сделал в лиспе"
FR>Судя по Re[22]: MIT переходи со схемы на...
scala и без макросов может неплохо прожить. Да и D похоже той же дорожкой идет
естественно
всем им уготована долгая плодовитая жизнь
просто, я как крутько (без ложной скромности), желаю быть "on the edge", и пользоваться всем самым лучшим, чего и вам всем желаю
а макросы нужны редко, как на данный момент
это потом, со временем, все сообразят, что кодогенераторы нужно заменить макросами
E>Но блин, их API Reference это сплошное издевательство. Такое впечатление, что комментариев при написании библиотек они вообще не делали. И примеров с гулькин нос. Только ScalaByExample и спасает местами.
FR>Ну и конечно агрессивная реклама как я уже говорил во многом оталкивает, я вот вчера scala скачал, будет свободное время лучше его поковыряю
дело молодое
PI>>а если толпа идёт куда-то не туда, то что ж придётся проявить некоторую индивидуальность и сообразительность
FR>А зачем тебе толпа?
мне как раз незачем, я как раз против ветра плюю
PI>>тут проскочил термин "настоящее"-программирование PI>>это не "ковыряться", не "изучать", не "лабать дома" PI>>это когда есть реальные задачи, которые нужно реализовать, обеспечив взаимодейтсвие с десятком технологий
FR>Пока для "настоящего" программирования немерле непригоден, выйдет релиз
поздравляю — ты в толпе, зачем тебе толпа?
ну жди, штампик поставят — "релиз", тогда ты так же бодро поменяешь мнение о немерле? или будешь пару лет разогреваться? типа посмотрим, че они там на нем сделают, а вдруг там баги еще есть...
FR>, будут хоть какие-то гарантии что проект не забросят тогда да.
гарантий нет
для себя — я вижу весь код сверху донизу, и знаю, если что нужно будет — поправлю
и вряд ли это будет больше, чем твик
хотя, может со временем, подумаю, каков следующий шаг
PI>>и неважно чего именно не хватает для фортрана (к примеру) — гуи, xml-либы, tcp-классов, тест-фреймворка PI>>если не хватает хотя бы одного пункта, то можно фортран вычеркивать из списка
FR>Из какого списка? Нет никакого такого Списка пригодного для всех и всего. У каждого разработчика, проекта свои списки и часто с очень разными критериями.
ага, но есть стандартизированные списки, типа "разработка веб-проектов"
или "разработка сетевого софта"
или "разработка софта для вычислений"
и сразу ясно, что для веба например, без нормальной xml-либы язык можно списывать со счетов
Здравствуйте, VladD2, Вы писали:
VD>>>Заблуждаетесь вы в одном. В том что плохое получается от макросов (вмест них можно вписать что угодно по вкусу). Полхой код получается от небрежности, глупости, надменности и большого опыта. Хороший же искючительно от желания сделать код хорошим. Так что получив плохой код, сделай его хоршим. Вот и все.
EC>>Опять какие-то домыслы — я здесь ниразу не озвучил своё отношение к макросам.
VD>Конечно, домыслы. Ты здесь вообще не разу ни одной разумной мысли до коднца не высказывал. Просто задаешь откровенно глупые, алогичные вопросы. На подобные вопросы можно отвечать только, то что они не корректны. Но даже из пдобной ахинеи можно понять к чему человек пытается клонить. Демагогия ведь давно стала наукой. Ее приемы изучены и сразу видно куда клонит демагог.
Ты меня упрекаешь в непоследовательности суждений, хотя сам совершенно непоследователен. Постоянно отвечаешь невпопад.
Ты утвержал, что я вижу в макросах вред (абзац 1), я тебе указал на некорректность этого утверждения (абзац 2), ты это незаметил и перешёл на обсуждение моей личности (абзац 3), причём даже если отталкиваться от того, что то что утверждается в абзаце 3 верно, то логической связи между абзацом 2 и 3 нет — т.е. ты непоследователен в своих рассуждениях.
Но ты даже, если и согласен со мной, то всё равно это не признаешь, но я на это и не рассчитываю.
VD>Вот зачем, к примеру, задавать вопрос: VD>
Т.е. тебе нет разницы какой код сопровождать: просто плохой или изощрённо плохой?
VD>?
Ты контекст поскипал. Там высказывалась довольно банальная мысль, что неоправданная сложность кода усложняет сопровождение, т.е. слишком сложный код — плохой код.
VD>Ты влез защищать черт знает, что и на первое замечание откровенно перешел на обсуждение личности оппонента. Причем умудрился разглядеть какие-то упоминания Немерла.
Не надо передёргивать, я провёл сравнение для пояснения мысли, личность оппонента никак не обсуждалась (причём мой собеседник меня прерасно понял, что подтверждается его адекватной реакцией).
VD>Так вот мой тебе совет. Если раздражает реклама, выключи ее. Перевожу для тех бестолковых, что пытаются трактовать слова дословно. Не нравится разговоры о Немерле или еще каких-то там технологиях которые? Кажется, что о чем-то говорят слишком часто и не к месту? Не открывай форумы и сайты где это происходит. У тебя есть выбор. В конце концов, создай свой сайт. Но не надо затыкать рот окружающим.
Я нормально справляюсь с рекламой. Здесь около 75% тем для меня не интересны — я их просто пропускаю мимо. Я пытался сказать, что реклама Nemerle безусловно важна, но на мой взгляд есть более эффективные способы её проведения, но как ты её будешь вести решать безусловно тебе.
VD>Бери пример с других. Тот же Руби обсуждается и никто не запрещает этого делать. Наоборот это интересно.
Глядя на твоё общение с eao197 очень трудно заметить твой интерес к руби, обычно всё сводится к тому, что он сильно сливает Nemerle, а то, что они позиционируются для совершенно различных применений ты почему-то не берёшь в расчёт.
Предлагаю сворачивать дискуссию (ну не получается у нас с тобой нормально общаться — и ладно), её ценность для остальных читателей форума ноль, да и для нас сомнительна.
Здравствуйте, eao197, Вы писали:
E>Пример с многопоточностью показал скорость передачи сообщений в Scala на 200000 сообщений больше, чем в C++ (800K против 600K).
Что за пример? Исходный код в студию. Ща сравним [злорадно потирая руки] .
E>Компилировалась до версии 1.4, если точнее. Scala2 уже не работает под .NET. Кстати, описание Scala на RSDN уже порядком устарела, Scala2 существенно отличается от Scala1.
Судя по "Scala Reference. Chapter B. Changes between Scala version 1.0 and 2.0." не слишком сильно. Так кое-где поправили.
Здравствуйте, PhantomIvan, Вы писали:
E>>Но блин, их API Reference это сплошное издевательство. Такое впечатление, что комментариев при написании библиотек они вообще не делали. И примеров с гулькин нос. Только ScalaByExample и спасает местами.
PI>а что, сорцы Скалы недоступны?
Доступны. Только:
— я уже избалован хорошими примерами. Например, MSDN для документации по STL и WinAPI, Ruby Doc, Java Doc, да и собственная документация меня устраивает А тут прям каменный век;
— реализация какого-то класса/метода без примеров его использования мало полезна. Ведь я же не переписывать его собираюсь, а использовать;
— мне вообще-то не шашечки, мне ехать нужно. Т.е. писать код, который пойдет в коммерческое использование, в перспективе для систем режима 24x7, которые не только я сопровождать буду. Там дай-то бог в собственных исходниках разобраться, а не в дебрях библиотек Scala.
Чтобы не быть глословным: SyncVar -- то еще описание
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Я понимаю почему мои сообщения вызывают у тебя такую негативную реакцию — я порой выхожу за рамки, общаяясь с тобой.
Поэтому прошу прощение за то хамство, что я себе позволял в сообщениях адресованных тебе.
Предлагаю завязать с выплёскиванием негатива в форум и
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Здравствуйте, eao197, Вы писали:
E>>Пример с многопоточностью показал скорость передачи сообщений в Scala на 200000 сообщений больше, чем в C++ (800K против 600K). АХ>Что за пример? Исходный код в студию. Ща сравним [злорадно потирая руки] .
См. ниже.
Только я не уверен, что в Scala использовались нативные нити. В случае же собственных нитей переключение между ними могло бы быть гораздо эффективнее, чем нативных. Но при реальной нагрузке и выполнении каких-либо блокирующих операций такие нити могут заблокировать выполнение всего приложения, в отличии от нативных.
E>>Компилировалась до версии 1.4, если точнее. Scala2 уже не работает под .NET. Кстати, описание Scala на RSDN уже порядком устарела, Scala2 существенно отличается от Scala1. АХ>Судя по "Scala Reference. Chapter B. Changes between Scala version 1.0 and 2.0." не слишком сильно. Так кое-где поправили.
У них есть отдельный документ с таким названием, там изменения на 17-ти страницах подробно расписаны. Хотя перечисленны те же, что и в Scala Reference.
Реализация на Scala.
abstract class MessageBase
case class Message( n: int ) extends MessageBase
case class Shutdown extends MessageBase
object QueueSpeed4 {
import scala.concurrent.Channel
import java.util.Calendar
val MESSAGES : int = 2000000
type Queue = Channel[ MessageBase ]
def producerThread( q: Queue, messages: int ): unit = {
for( val i <- Iterator.range( 0, messages ) )
q.write( Message( i ) )
q.write( Shutdown )
}
def consumerThread( q: Queue ): unit = {
def loop {
q.read match {
case Message( i ) => if( i + 1 < MESSAGES ) loop
case Shutdown() =>
}
}
loop
}
def spawn( body: => unit ) = new Thread {
start
override def run = body
}
def join( threads: Thread* ) {
for( val t <- threads ) t.join
}
def main( args: Array[ String ] ) {
var q : Queue = new Queue
val start = Calendar.getInstance.getTimeInMillis
join(
spawn { producerThread( q, MESSAGES ) },
spawn { consumerThread( q ) } )
val finish = Calendar.getInstance.getTimeInMillis
val workTime : double = (finish - start).toDouble / 1000.0
Console.println( "total: " + workTime +
", troughput: " + MESSAGES / workTime )
}
}
// vim:ts=2:sw=2:sts=2:expandtab
Реализация на C++. Используется ACE и собственная реализация очереди сообщений (не ACE_MessageQueue):
/*
* Замер максимальной скорости передачи сообщений между двумя
* нитями через очередь сообщений.
*/#include <iostream>
#include <memory>
#include <queue>
#include <ace/Condition_Thread_Mutex.h>
#include <ace/Guard_T.h>
#include <ace/Log_Msg.h>
#include <ace/OS.h>
#include <ace/OS_main.h>
#include <ace/Thread_Manager.h>
#include <ace/Thread_Mutex.h>
#include <ace/Time_Value.h>
// Количество сообщений, которое будет отосланно.const int MESSAGE_COUNT = 20000000;
// Тип сообщения, которое будет передаваться через очередь сообщений.class message_t
{
public :
message_t( int ordinal )
: m_ordinal( ordinal )
{}
int
ordinal() const { return m_ordinal; }
private :
int m_ordinal;
};
// Тип очереди сообщений.class demand_queue_t {
public :
demand_queue_t();
~demand_queue_t();
enum
{
//! Была извлечена заявка.
demand_extracted = 1,
//! Заявка не была извлечена, т.к.
//! выставлен признак завершения работы.
shutting_down = 2
};
// Поместить заявку в очередь.void
push(
std::auto_ptr< message_t > message );
// Взять первую заявку.int
pop(
std::auto_ptr< message_t > & message,
/* В случае отличия от нуля сюда помещается
текущее количество заявок в очереди.
Это значение может использоваться для
определения того, будет ли остановлена
текущая нить при следующем обращении
к pop */
size_t * remaining_demands_count = 0 );
// Сбросить признак необходимости завешения работы.void
start();
// Выставить признак необходимости завешения работы.void
shutdown();
// Принудительное удаление всех отавшихся в
// очереди заявок.void
destroy_all_demands();
private :
ACE_Thread_Mutex m_lock;
ACE_Condition_Thread_Mutex m_not_empty;
// Тип списка сообщений.typedef std::queue< message_t * > message_queue_t;
// Список всех сообщений.
message_queue_t m_messages;
bool m_shutdown;
// Удаление всего содержимого %m_messages.void
cleanup_demands();
};
demand_queue_t::demand_queue_t( )
: m_shutdown( false )
, m_not_empty( m_lock )
{}
demand_queue_t::~demand_queue_t()
{
cleanup_demands();
}
void
demand_queue_t::push(
std::auto_ptr< message_t > message )
{
ACE_Guard< ACE_Thread_Mutex > lock( m_lock );
// После shutdown-а ничего больше не обрабатываем.if( !m_shutdown )
{
m_messages.push( message.release() );
m_not_empty.signal();
}
}
int
demand_queue_t::pop(
std::auto_ptr< message_t > & message,
size_t * remaining_demands_count )
{
ACE_Guard< ACE_Thread_Mutex > lock( m_lock );
while( true )
{
if( m_messages.size() )
{
message = std::auto_ptr< message_t >(
m_messages.front() );
m_messages.pop();
if( remaining_demands_count )
*remaining_demands_count = m_messages.size();
break;
}
else if( m_shutdown )
// Нужно завершать работу.return shutting_down;
else// Нужно ждать наступления
// какого-нибудь события.
m_not_empty.wait();
}
return demand_extracted;
}
void
demand_queue_t::start()
{
m_shutdown = false;
}
void
demand_queue_t::shutdown()
{
ACE_Guard< ACE_Thread_Mutex > lock( m_lock );
m_shutdown = true;
m_not_empty.signal();
}
void
demand_queue_t::destroy_all_demands()
{
ACE_Guard< ACE_Thread_Mutex > lock( m_lock );
if( m_shutdown )
{
cleanup_demands();
}
else
{
ACE_ERROR(( LM_ERROR,
"demand_queue_t::destroy_all_demands without "
"preceding demand_queue_t::shutdown\n" ));
}
}
void
demand_queue_t::cleanup_demands()
{
while( m_messages.size() )
{
delete m_messages.front();
m_messages.pop();
}
}
// Параметры для тестовых нитей.struct thread_params_t
{
// Очередь, которой нужно пользоваться.
demand_queue_t & m_queue;
thread_params_t(
demand_queue_t & queue )
: m_queue( queue )
{}
};
// Нить генератора сообщений.
ACE_THR_FUNC_RETURN
producer_thread( void * raw_param )
{
const thread_params_t * params = ACE_reinterpret_cast(
const thread_params_t *, raw_param );
for( int i = 0; i != MESSAGE_COUNT; ++i )
{
std::auto_ptr< message_t > message( new message_t( i ) );
params->m_queue.push( message );
}
return 0;
}
// Нить потребителя сообщений.
ACE_THR_FUNC_RETURN
consumer_thread( void * raw_param )
{
const thread_params_t * params = ACE_reinterpret_cast(
const thread_params_t *, raw_param );
while( true )
{
std::auto_ptr< message_t > message;
int result = params->m_queue.pop( message, 0 );
if( demand_queue_t::demand_extracted == result )
{
if( MESSAGE_COUNT == message->ordinal() + 1 )
break;
}
else
break;
}
return 0;
}
int
main( int argc, char ** argv )
{
demand_queue_t queue;
thread_params_t params( queue );
ACE_Time_Value start_time = ACE_OS::gettimeofday();
ACE_Thread_Manager::instance()->spawn(
producer_thread,
¶ms );
ACE_Thread_Manager::instance()->spawn(
consumer_thread,
¶ms );
ACE_Thread_Manager::instance()->wait();
ACE_Time_Value finish_time = ACE_OS::gettimeofday();
double work_time = ( finish_time.msec() - start_time.msec() ) / 1000.0;
std::cout << "messages: " << MESSAGE_COUNT
<< ", total time: " << work_time << " sec"
<< ", throughput: " << MESSAGE_COUNT / work_time << " msgs/sec"
<< std::endl;
return 0;
}
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
E>Чтобы не быть глословным: SyncVar -- то еще описание
оно ж автоматом сгенерировано
а если ты в курсе java.concurrent, то не можешь ли ты предположить, что это за SyncVar такой?
потому что в немерле понятно всё, что связано с дотнетом (только макросы — специфичные для Немерле, вызывают недоумение)
E>>Компилировалась до версии 1.4, если точнее. Scala2 уже не работает под .NET. Кстати, описание Scala на RSDN уже порядком устарела, Scala2 существенно отличается от Scala1. АХ>Судя по "Scala Reference. Chapter B. Changes between Scala version 1.0 and 2.0." не слишком сильно. Так кое-где поправили.
а зачем же тогда убрали поддержку .NET?
Здравствуйте, PhantomIvan, Вы писали:
EC>>реклама Nemerle безусловно важна, но на мой взгляд есть более эффективные способы её проведения PI>какие?
Перечислю те моменты, которые меня не устраивают в текщей реализации рекламной кампании :
Упоминать Nemerle к месту.
Сравнивать его с инструментами позиционирующимися для решения задач более-менее того же класса для которых предназначен он сам.
Не надо строить из себя программистскую элиту — таким способом невозможно привлечь людей способных реально помочь проекту.
Не надо вводить людей в заблуждение, что это последние достижения в языкостроении, думаю что Haskell не менее интересен в этом плане (скорее даже более, но пока не могу адекватно оценить).
Не .NET'ом единым сыт мир, есть масса задач, где он неприменим — тут как-то утвержали, что нет никаких принципиальных трудностей реализовать back end компилятора для другого окружения, от этой возможности пока она не реализована никому не тепло не холодно.
Насколько я понимаю здесь большинство людей решают достаточно приземлённые задачи и надо привести реальные примеры где фичи Nemerle дадут преимущество (насколько я понял Влад над этим работает).
Здравствуйте, PhantomIvan, Вы писали:
E>>>Компилировалась до версии 1.4, если точнее. Scala2 уже не работает под .NET. Кстати, описание Scala на RSDN уже порядком устарела, Scala2 существенно отличается от Scala1. АХ>>Судя по "Scala Reference. Chapter B. Changes between Scala version 1.0 and 2.0." не слишком сильно. Так кое-где поправили. PI>а зачем же тогда убрали поддержку .NET?
Не убрали, а не доделали.
У них видимо руки не доходят, да это для них видимо и не приоритетно по сравнению с исследованием новых фич. Но в планах она есть.
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Не убрали, а не доделали. АХ>У них видимо руки не доходят, да это для них видимо и не приоритетно по сравнению с исследованием новых фич. Но в планах она есть.
Оппс, правильная ссылка — здесь.
Здравствуйте, PhantomIvan, Вы писали:
E>>Чтобы не быть глословным: SyncVar -- то еще описание
PI>оно ж автоматом сгенерировано
Вот это то же автоматом сгенерированно. Но, как говорится, почувствуйте разницу.
PI>а если ты в курсе java.concurrent, то не можешь ли ты предположить, что это за SyncVar такой?
Во-первых, не в курсе. Я таки не Java программист.
Во-вторых, в Java нет java.concurrent, есть java.util.concurrent, но там нет SyncVar, как в Scala.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Здравствуйте, Sinclair, Вы писали:
L>>>Угу, в курсе, что под ОО обычно понимают совсем не то, что создатель термина. Однако, имелось в виду несколько другое. Пусть ООП — это инкапсуляция, наследование, полиморфизм. Однако даже в таком случае реализаций очень много. Вот модификаторы доступа — public, private, protected и каждый язык добавляет какие ему надо. Можем ли мы задавать свои? Например, поля, которые видны только из классов из пакета ааа с именем AAASome* Это что касается инкапсуляции. Подобные примеры можно придумать и для наследования и полиморфизма. (Вспомним хотя бы вечные споры о множественном наследовании). S>>Не надо, ради байта, ничего придумывать. Private/protected/public/internal и т.д. это не совсем инкапсуляция. Это возможность предоставлять различные контракты различным потребителям. Классификация потребителей зависит от того, какие предикаты можно вычислить на паре типов. В С++ это ровно три предиката: тождественный TRUE, коммутативный Equals, и транзитивный InheritsFrom.
АХ>Неверно. Предикаты на чем? АХ>Если на классах, то в C++ АХ>1) есть отдельные функции вне классов, как насчет них?
Без ограничения общности можно считать все функции единственными статическими методами отдельных классов, не отнаследованных ни от чего. АХ>2) есть еще разные типы наследования, которые не вписываются в твою картину:
Виды наследования, как таковые — это то же самое. Уточнение контракта. Факт наследования точно так же "виден" тем классам, которые удовлетворяют соответствующему предикату.
АХ>Особенно интересная картина возникает если еще примешать множественное и виртуальное наследование:
Ничего особенно интересного не возникает. Все в рамках той же несложной мат. модели. АХ>Много умных слов о предикатах и транзитивности, да не о сути, как мне кажется. Предикаты можно вычислять какие угодно — хоть то, что названия типов с одной буквы начинаются.
Можно, но практического смысла не имеет. Поэтому нет никакого beginswith('A'): в качестве модификатора доступа. АХ> Вопрос в другом — какой смысл несут эти предикаты. Поэтому вопросы "а protected — это инкапсуляция или нет?" совершенно справедливо возникают.
1.2.0 alpha rev. 655
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, PhantomIvan, Вы писали:
PI>поздравляю — ты в толпе, зачем тебе толпа?
мне пофиг
PI>ну жди, штампик поставят — "релиз", тогда ты так же бодро поменяешь мнение о немерле? или будешь пару лет разогреваться? типа посмотрим, че они там на нем сделают, а вдруг там баги еще есть...
Мнение не поменяю, оно у меня о немерле вполне положительное, просто буду воспринимать его как реального кандидата в качестве рабочего инструмента.
FR>>, будут хоть какие-то гарантии что проект не забросят тогда да.
PI>гарантий нет PI>для себя — я вижу весь код сверху донизу, и знаю, если что нужно будет — поправлю PI>и вряд ли это будет больше, чем твик PI>хотя, может со временем, подумаю, каков следующий шаг
PI>>>и неважно чего именно не хватает для фортрана (к примеру) — гуи, xml-либы, tcp-классов, тест-фреймворка PI>>>если не хватает хотя бы одного пункта, то можно фортран вычеркивать из списка
FR>>Из какого списка? Нет никакого такого Списка пригодного для всех и всего. У каждого разработчика, проекта свои списки и часто с очень разными критериями.
PI>ага, но есть стандартизированные списки, типа "разработка веб-проектов" PI>или "разработка сетевого софта" PI>или "разработка софта для вычислений"
Я вижу не списки а классы списков
PI>и сразу ясно, что для веба например, без нормальной xml-либы язык можно списывать со счетов