LINUX.ORG.RU

Ядро на ООП

 ,


2

4

А как вам идея написать ядро ОС, по сложности и возможностям сопоставимой с Linux, с применением ООП (например, на C++) Каждый драйвер, сервис и др. сделать классом (ну группой классов).

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

Минус - необходимость поддержки ООП в ядре влечёт за собой некоторый overhead (вот насколько он будет заметен - тоже интересный вопрос).

Высказывайтесь.

★★★★★
Ответ на: комментарий от tailgunner

Для начала нужно будет ввести новое определение термина «ООП».

Похоже, что люди никак не могут договориться на счет того, что же значит слово ООП :)

dave ★★★★★
()
Ответ на: комментарий от tailgunner

Для начала нужно будет ввести новое определение термина «ООП». Армстронг уже идет по этому пути, ага %)

ирония?

Ну мне тоже так показалось, что он где-то на пол-пути. Не хватает так сказать или вдохновения или «импульса извне». Где-то в поиске, но понимает, что так дальше нельзя. Либо соединять не соединяемое: ФООП==ООП+ФП, либо? Скорее всего дальнейшее развитие Эрланга.

Тут он однажды запилил: А нафига нам все эти модули, библиотеки. Давайте весь код держать как набор безымянных функций в дереве и прикрутим это к репозитариям. Старина Джо, что тут скажешь!

Когда идешь по новому пути весьма непросто... Но внушает доверие то, что человек реализовавший матчинг и все остальное, хотя и не полностью, может вдохновить на что-нибудь дельное. Он не скрывает, что не имеет устоявшейся точки зрения, но хоть что-то пытается делать. В отличии от бесконечных споров о проблеме курицы и яйца и т.д. Как говорится: «Less slogan, more code...(c)»

Хотя, по моим наблюдениям, не только он один задает тон в Эрланге. Есть дань Эриксону. Есть коммерческий Эрланг. Та черная дыра, именуемая в Эрланге стэком SNMP открыта, но без каких-либо обширных комментов. У меня есть подозрение, что Эрикссон не дает все открывать или оно так выглядит со стороны.

swwwfactory ★★
()
Ответ на: комментарий от dave

Похоже, что люди никак не могут договориться на счет того, что же значит слово ООП :)

Похоже, что кто-то решил урвать наконец свою долю славы.

tailgunner ★★★★★
()
Ответ на: комментарий от quasimoto

классическое ООП со своими терминами и паттернами

Какое из «ООП» - «ООП» Кея или «ООП» Буча и К° ты называешь «классическим»? ;)

уникальные плюшки ООП это подтипирование и интерфейсы

Лёгким движением руки в ОО-языки превращаются..в ОО-языки превращаются.. чуть ли не все языки от лиспа до хаскеля.

Можно сказать, что это всё было «не тем ООП», но тогда понятие «ООП» станет общим местом.

Бинго!

LamerOk ★★★★★
()
Ответ на: комментарий от swwwfactory

Для начала нужно будет ввести новое определение термина «ООП». Армстронг уже идет по этому пути, ага %)

ирония?

Это издевка. Уже 20 лет понятно, что такое ООП, и когда хоть Кей, хоть Армстронг начинают объяснять, что кто-то всё не так понял и суть ООП в другом, это выглядит троллингом или маразмом.

Когда идешь по новому пути весьма непросто...

Кто идет по новому пути, что за путь и в чем новизна?

tailgunner ★★★★★
()
Ответ на: комментарий от dave

всегда найдутся люди, которые ради своей выгоды будут приписывать новый смысл старым словам

obvious fix, чо

tailgunner ★★★★★
()
Ответ на: комментарий от quasimoto

Недурно как стэнд. Но в реальности лучше делать на gen_server, будет проще.

Там где делаешь бэкап в «конструкторе» recell и cell, ты в другом пиде не recell-а Соответственно не сможешь потом его прочитать по get. Надо чтобы оно тоже было живущим процессом и по «ресиву» смогло обработать твои «пожелания».

вот интересный материал: http://en.wikibooks.org/wiki/Erlang_Programming/Example1 Не разбирал пока код, но выглядит концептуально.

Me = self() obj = spawn(object, element, [Me, data]) -> pid ... obj ! {self(), get} ... receive {Pid, get} -> Pid ! {self(), {reply, get}, data}, ok; {Pid, set, new_data} -> put('_state', {action, save, new_data}), Pid ! {self(), ok}, ok; end, loop([some, data]). ....

Это без наследования. Наследование надо реализовывать примерно так-же, но помнить (таскать в состоянии или держать в сторедже) всю цепочку пидов предков. Передавать им сообщение в ресив каждого последовательно если они могут его обработать. Этот вызов должен в итоге либо обработан (спасибо кэп ))) либо крэш, либо «мягкая обработка».

Насчет хаскеля мало что могу сказать: только теоретические познания.

Лучше объекты делать на gen_server + superwisor как блок управления «чилдами», либо писать свой супервизор т.к. у эрланга он заточен в основном на убийство и переподъем и жестко мониторит. Но если c gen_server тяжеловато, то лучше тренироваться на простых ресивах. Эрланг не дает ответа на вопрос как обрабатывать: ассинхронно или синхронно. Он просто предоставлят оба интерфейса и с возможностью таймаута.

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

Извиняюсь. Псевдокод.

...
Me = self(),
Obj = spawn(object, element, [Me, data]), %% -> pid
...
Obj ! {self(), get}
...
receive
  {Pid, get}  -> 
    Pid ! {self(), {reply, get}, data},
    ok;
  {Pid, set, new_data}  -> 
    put('_state', {action, save, new_data}), 
    Pid ! {self(), ok},
    ok;
end,
loop([some, data]).
....  
swwwfactory ★★
()
Ответ на: комментарий от tailgunner

Уже 20 лет понятно, что такое ООП

Более чем понятно. Можно сделать вывод: ООП устарел.

это выглядит троллингом или маразмом.

Вполне. А может Джо решит потроллить)) Куда сейчас без юмора?

Кто идет по новому пути, что за путь и в чем новизна?

Разработчики эрланга. Аналогов нет. Успешно воплотили на практике функциональшину. Пытаются взять все лучшее из ООП.

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

Кто идет по новому пути, что за путь и в чем новизна?

Разработчики эрланга. Аналогов нет.

А можно кратенько - список новых идей Эрланга? Насколько я могу судить, Эрланг - смесь нескольких языков, сразу можно назвать Occam, Ada и Prolog. Что в нем дествительно нового - это идея fail fast. Правда, и она была новой лет 20 назад.

Пытаются взять все лучшее из ООП.

Хм. Дык Эрланг же единственный Ъ-ООП язык, сам у себя берет? %)

tailgunner ★★★★★
()
Ответ на: комментарий от LamerOk

Какое из «ООП» - «ООП» Кея или «ООП» Буча и К° ты называешь «классическим»?

Буча и К°, ну или Пирса и Кардели.

чуть ли не все языки от лиспа до хаскеля.

CLOS? Наследование в defclass c (a b), так что c предполагает вызываемость, переписывание и дописывание методов a и b, интерфейсы как наборы defgenericов, мульти-диспатч. Вполне классическое ООП. Хаскель не превращается, там слишком много нужно делать руками:

class a :> b where sup :: b -> a; inout :: (a -> t) -> b -> t; inout f = f . sup

data Cell = Cell (IORef Int)
instance IORef Int :> Cell where sup (Cell ref) = ref

class CellI t where get :: t -> IO Int; set :: t -> Int -> IO ()
instance CellI Cell where get = inout readIORef; set = inout writeIORef

data ReCell = ReCell (IORef Int) Cell
instance Cell :> ReCell where sup (ReCell _ cell) = cell
instance IORef Int :> ReCell where sup (ReCell ref _) = ref

class CellI t => ReCellI t where restore :: t -> IO ()

instance CellI ReCell where
  get = (inout :: (Cell -> IO Int) -> ReCell -> IO Int) get
  set rc x
      = (inout :: (Cell -> IO Int) -> ReCell -> IO Int) get rc
    >>= (inout :: (IORef Int -> Int -> IO ()) -> ReCell -> Int -> IO ()) writeIORef rc
    >>  (inout :: (Cell -> IO ()) -> ReCell -> IO ()) (flip set x) rc

instance ReCellI ReCell where
  restore rc
      = inout readIORef rc
    >>= (inout :: (Cell -> Int -> IO ()) -> ReCell -> Int -> IO ()) set rc

подтипы нужно настраивать и для inout нужные типы часто не выводятся, это ещё не касаясь динамической диспетчеризации.

Но в более простом виде:

data Cell = Cell (IORef Int)

class CellI t where get :: t -> IO Int; set :: t -> Int -> IO ()
instance CellI Cell where get (Cell ref) = readIORef ref; set (Cell ref) = writeIORef ref

data ReCell = ReCell (IORef Int) Cell

class CellI t => ReCellI t where restore :: t -> IO ()

instance CellI ReCell where
  get (ReCell _ cell) = get cell
  set (ReCell ref cell) x = get cell >>= writeIORef ref >> set cell x

instance ReCellI ReCell where
  restore (ReCell ref cell) = readIORef ref >>= set cell

будет работать - есть нотация для наследования интерфейсов, нет для агрегации данных (records и record subtyping вообще). Ну и динамическая диспетчеризация по-прежнему требует дополнительных конструкций (работающих нормально только в относительно новом GHC).

quasimoto ★★★★
()
Ответ на: комментарий от tailgunner

А можно кратенько - список новых идей Эрланга?

Безусловно, есть много спорных моментов в новых идеях, приведу список наиболее сильных сторон, на вскидку:

  • Yes, let it crash.
  • nodes, rpc
  • superwising
  • hot code loading (наиболее удачная реализация)
  • gen_tcp, gen_udp, gen_fsm, gen_server
  • «case match», «function match»
  • guards
  • ets/dets/mnesia (спорно, но неплохо)
  • словари процессов (возможно есть у других)
  • легковесные и дешёвые процессы
  • receive
  • tail recursion

Хм. Дык Эрланг же единственный Ъ-ООП язык, сам у себя берет? %)

))) Ну и не только. Из пролога нахватал точно. Из других языков явно нет, но выжимка думаю да.

fail fast. Правда, и она была новой лет 20 назад.

Новое, это хорошо забытое старое.

swwwfactory ★★
()
Ответ на: комментарий от swwwfactory

nodes, rpc

ЩИТО? RPC уж точно не Эрланг придумал.

hot code loading

OK.

superwising

Хм. «Супермудрение» штоле? Или ты о supervising? Так это вполне очевидная фича (причем _не_ языковая), которую для себя делал каждый второй прогер.

gen_tcp, gen_udp, gen_fsm, gen_server

Библиотеки, не язык. Ну и опять же - ничего нового.

«case match», «function match»
guards

Pattern matching не в Эрланге изобрели.

легковесные и дешёвые процессы

Occam

receive

Occam, Ada, куча экспериментальных языков начала 80-х.

tail recursion

Плакал.

Новое, это хорошо забытое старое.

Кто забыл-то? Новички в ремесле просто не успели узнать, ветераны считают очевидным: «Rule of Repair: Repair what you can — but when you must fail, fail noisily and as soon as possible».

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

ЩИТО? RPC уж точно не Эрланг придумал.

RPC, да не они. НО ноды где еще есть на уровне языка? Забыл добавить PID на уровне языка. Есть такой встроенный тип: pid. Почитайте про структуру пида в эрланге. Довольно оригинально.

Библиотеки, не язык. Ну и опять же - ничего нового.

Не встречал более лучших реализаций. И это часть системных библиотек - почти часть ядра. Там фигурирует некий behaviour, но его роль слабовата. Просто следит при компиляции, есть такой метод или нет в реализации сервера.

Pattern matching не в Эрланге изобрели.

Но зато как реализовали!

Кто забыл-то?

Некоторые... Не ты, точно )))

Хм. «Супермудрение» штоле?

Извиняюсь, да supervisor. Что-то подумалось от слова wide происхождение.

swwwfactory ★★
()
Ответ на: комментарий от korvin_

Не знаю, что это.

http://research.microsoft.com/en-us/um/people/simonpj/papers/stm/stm.pdf

Если a и b - атомичные транзакции, то a >> b и a >>= b - тоже атомичные транзакции, равно как и все производные комбинации. При этом есть набор примитивных транзакций.

Можно сделать, например

receive :: ((ThreadId, TChan m) -> m -> STM ()) -> (ThreadId, TChan m) -> IO ()
receive dispatch self = forever $ atomically $ readTChan (snd self) >>= dispatch self

оно будет засыпать на канале TChan m пока не появятся данные, и при появлении данных читать их и отправлять в функцию dispatch, при чём это всё внутри atomically, так что и чтение из канала и все вычисления в dispatch (произвольные монадические вычисления в STM, с переменными, массивами и т.п.) пройдут атомично.

quasimoto ★★★★
()
Ответ на: комментарий от LamerOk

даже atom - обладает типом и интерфейсом с рантайм-дисптачингом.

Во-первых, это примитивный тип (не record / union), во-вторых, от такого типа нельзя унаследовать произвольный тип и расширить либо изменить его интерфейс, потому что интерфейс состоит из обычных не расширяемых функций в которых весь «рантайм-дисптачинг» это один большой typecase по захардкоженным типам - не таблица диспетчеризации. Например, довольно проблематично написать свой my-string <: string и дописать string= без разных хаков уровня реализации и правки существующего кода.

http://www.stefanwehr.de/publications/ThiemannWehr2008.html

Там как раз ExistentialQuantification, начиная с 7.4 такие вещи стали немного удобнее (если нужен не фиксированный набор классов).

quasimoto ★★★★
()

«классами» и модульно можно писать хоть на чистом C, а тут видимо предлагается апофеоз с кучей темплейтов, наследований и reinterpret_cast. я тут наблюдаю как одному гражданину сказали условно построить сортир а он уже больше года на вычурном C++ проектирует завод по производству нанодосок для сортира которые выдержат ядерную войну на марсе и смогут мутировать и видоизменяться в зависимости от спектра голоса пришельцев с альфацентавра в теории случайно посетивших этот сортир с 5 до 6 часов утра пятницы в високосный год земли. как результат есть куча кода которая не может ВООБЩЕ ничего, совершенно ничего.

quest ★★★★
()
Ответ на: комментарий от DeVliegendeHollander

Встречался мне один программер, у которого код на С выглядел так, как будто написан на басике, на котором он до этого писал лет 5-6. Я даже вообразить себе не мог, что на С возможно такое сотворить. :)

Можно пример?)

quest ★★★★
()
Ответ на: комментарий от quasimoto

оно будет засыпать на канале TChan m пока не появятся данные, и при появлении данных читать их и отправлять в функцию dispatch, при чём это всё внутри atomically, так что и чтение из канала и все вычисления в dispatch (произвольные монадические вычисления в STM, с переменными, массивами и т.п.) пройдут атомично.

Эм... Что значит «атомично»? Т.е. либо весь код в dispatch отработает либо нет?

korvin_ ★★★★★
()
Ответ на: комментарий от theNamelessOne

Как и в куче других функциональных языков, не?

Приведу некоторые примеры:

tokenize_string_fast(B, O) ->
    case B of
        <<_:O/binary, ?Q, _/binary>> ->
            O;
        <<_:O/binary, $\\, _/binary>> ->
            {escape, O};
        <<_:O/binary, C1, _/binary>> when C1 < 128 ->
            tokenize_string_fast(B, 1 + O);
        <<_:O/binary, C1, C2, _/binary>> when C1 >= 194, C1 =< 223,
                C2 >= 128, C2 =< 191 ->
            tokenize_string_fast(B, 2 + O);
        <<_:O/binary, C1, C2, C3, _/binary>> when C1 >= 224, C1 =< 239,
                C2 >= 128, C2 =< 191,
                C3 >= 128, C3 =< 191 ->
            tokenize_string_fast(B, 3 + O);
        <<_:O/binary, C1, C2, C3, C4, _/binary>> when C1 >= 240, C1 =< 244,
                C2 >= 128, C2 =< 191,
                C3 >= 128, C3 =< 191,
                C4 >= 128, C4 =< 191 ->
            tokenize_string_fast(B, 4 + O);
        _ ->
            throw(invalid_utf8)
    end.
tokenize(B, S=#decoder{offset=O}) ->
    case B of
        <<_:O/binary, "<!--", _/binary>> ->
            tokenize_comment(B, ?ADV_COL(S, 4));
        <<_:O/binary, "<!DOCTYPE", _/binary>> ->
            tokenize_doctype(B, ?ADV_COL(S, 10));
        <<_:O/binary, "<![CDATA[", _/binary>> ->
            tokenize_cdata(B, ?ADV_COL(S, 9));
        <<_:O/binary, "<?php", _/binary>> ->
            {Body, S1} = raw_qgt(B, ?ADV_COL(S, 2)),
            {{pi, Body}, S1};
        <<_:O/binary, "<?", _/binary>> ->
            {Tag, S1} = tokenize_literal(B, ?ADV_COL(S, 2)),
            {Attrs, S2} = tokenize_attributes(B, S1),
            S3 = find_qgt(B, S2),
            {{pi, Tag, Attrs}, S3};
        <<_:O/binary, "&", _/binary>> ->
            tokenize_charref(B, ?INC_COL(S));
        <<_:O/binary, "</", _/binary>> ->
            {Tag, S1} = tokenize_literal(B, ?ADV_COL(S, 2)),
            {S2, _} = find_gt(B, S1),
            {{end_tag, Tag}, S2};
        <<_:O/binary, "<", C, _/binary>>
                when ?IS_WHITESPACE(C); not ?IS_LITERAL_SAFE(C) ->
            %% This isn't really strict HTML
            {{data, Data, _Whitespace}, S1} = tokenize_data(B, ?INC_COL(S)),
            {{data, <<$<, Data/binary>>, false}, S1};
        <<_:O/binary, "<", _/binary>> ->
            {Tag, S1} = tokenize_literal(B, ?INC_COL(S)),
            {Attrs, S2} = tokenize_attributes(B, S1),
            {S3, HasSlash} = find_gt(B, S2),
            Singleton = HasSlash orelse is_singleton(Tag),
            {{start_tag, Tag, Attrs, Singleton}, S3};
        _ ->
            tokenize_data(B, S)
    end.
%% All kind of flavors !
translate_lookup(["bind" | Ls]) -> [dns | translate_lookup(Ls)];
translate_lookup(["dns" | Ls]) -> [dns | translate_lookup(Ls)];
translate_lookup(["hosts" | Ls]) -> [file | translate_lookup(Ls)];
translate_lookup(["files" | Ls]) -> [file | translate_lookup(Ls)];
translate_lookup(["file" | Ls]) -> [file | translate_lookup(Ls)];
translate_lookup(["yp" | Ls]) -> [yp | translate_lookup(Ls)];
translate_lookup(["nis" | Ls]) -> [nis | translate_lookup(Ls)];
translate_lookup(["nisplus" | Ls]) -> [nisplus | translate_lookup(Ls)];
translate_lookup(["native" | Ls]) -> [native | translate_lookup(Ls)];
translate_lookup([M | Ls]) when is_atom(M) -> translate_lookup([atom_to_list(M) | Ls]);
translate_lookup([_ | Ls]) -> translate_lookup(Ls);
translate_lookup([]) -> [].
decode(Segment) ->
    case Segment of 
	<< SourcePort:16, DestinationPort:16,
	   SequenceNumber:32,
	   AckNumber:32,
	   DataOffset:4, _Reserved:4, Flags:8, WindowSize:16,
	   Checksum:16, UrgentPointer:16,
	   Payload/binary>> when DataOffset>4
	->
	    OptSize = (DataOffset - 5)*32,
	    << Options:OptSize, Message/binary >> = Payload,
	    <> = <>,
 	    %% Can now process the Message according to the
	    %% Options (if any) and the flags CWR, ..., FIN. 
	    binary_to_list(Message)
    end.
swwwfactory ★★
()
Ответ на: комментарий от korvin_

Что значит «атомично»?

Атомично. Например, в контексте IO следующий код

write(channel, msg1)
write(channel, msg2)

не гарантирует, что в channel будут последовательно помещены msg1 и msg2 - после первого write контекст может переключиться и другая нить вставит между msg1 и msg2 что-то своё. В контексте IO нужно сделать

lock(channel)
write(channel, msg1)
write(channel, msg2)
unlock(channel)

то есть добавить channel возможность блокировки - после lock (тут предполагается, что lock, unlock и write атомичны) все остальные нити которые хотят доступа к channel будут ожидать unlock и потом конкурировать за следующий захват блокировки.

В контексте STM с атомичными транзакциями объединяемыми в атомичные транзакции можно обойтись без блокировок, например:

channel1, channel2 :: TChan Int
[channel1, channel2] = map unsafePerformIO [newTChanIO, newTChanIO]
{-# NOINLINE channel1 #-}
{-# NOINLINE channel2 #-}

var :: TVar Bool
var = unsafePerformIO $ newTVarIO True
{-# NOINLINE var #-}

atOnce :: STM ()
atOnce = do
  writeTChan channel1 1
  b <- readTVar var
  when b $ do
    x <- readTChan channel2
    writeTChan channel1 x

выполняя atomically atOnce :: IO () можно быть уверенным, что все операции будут совершены последовательно и будут совершены исключительно только они. Ещё учтём, что STM функции могут вызывать друг друга, быть рекурсивными и т.п. Всё это не значит, что блокировок нет в рантайме, это значит, что их нельзя потерять.

Т.е. либо весь код в dispatch отработает либо нет?

В данном случае он всегда отработает (если dispatch сам не вызовет исключение или не сбросит транзакцию на повторение с помощью retry) - если в сообщении пришло self, некий набор PID-ов других процессов, TVarы и т.п., то dispatch может общаться с ними сколько угодно без явного локинга - другие нити не смогут сломать логику этой функции.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Надо было сразу говорить - binary pattern matching.

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

Третий пример - общеупотребимый pattern matching + guards

Но элегантно. Вдохновляет. Во многих языках этого к сожалению нет.

swwwfactory ★★
()
Ответ на: комментарий от quasimoto
lock(channel)
write(channel, msg1)
write(channel, msg2)
unlock(channel)

то есть добавить channel возможность блокировки - после lock (тут предполагается, что lock, unlock и write атомичны) все остальные нити которые хотят доступа к channel будут ожидать unlock и потом конкурировать за следующий захват блокировки.

Теперь понятно. А почему нельзя просто посылать список значений? Т.е. например вместо Chan Foo использовать Chan [Foo]?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

А почему нельзя просто посылать список значений?

Если write достаточно умная, то можно. Просто может быть более сложная ситуация в которой одной примитивной операцией не обойтись - нужно читать из одного канала, проверять какие-то условия, потом, может быть, писать прочтённый результат в другой канал и так далее - проще сделать одну большую транзакцию и закоммитить её, чем настраивать блокировки данным и тут и там их получать / освобождать. В Clojure ещё используется подобный подход (dosync).

Т.е. например вместо Chan Foo использовать Chan [Foo]?

Это только если все сообщения актора совместимы. Смысла посылать [pause, play] явно нет. Ну или можно делать mapM_ (actor !) [pause, play] и оставить Chan Foo - проще писать dispatch.

quasimoto ★★★★
()
Ответ на: комментарий от quest

1) Это было в суровые 1990-е. Мне, что, идти искать того персонажа и просить его предоставить С-код а-ля бейсик для демонстрации на ЛОРе?

2) Я подобные коллекции не собираю. Видеть-видел, но хранить такие шедевры 20 лет — это не моё.

3) Зачем?!!

DeVliegendeHollander ★★
()
Ответ на: комментарий от quasimoto

- проще сделать одну большую транзакцию и закоммитить её, чем настраивать блокировки данным и тут и там их получать / освобождать.

В Go предлагают писать без блокировок:

In particular, consider structuring your program so that only one goroutine at a time is ever responsible for a particular piece of data.

http://golang.org/doc/go_faq.html#What_operations_are_atomic_What_about_mutexes

Т.е. я так понимаю вместо «большой транзакции» посылать «большое сообщение», а получатель пока его не обработает все равно другие не примет.

korvin_ ★★★★★
()

А как вам идея написать ядро ОС, по сложности и возможностям сопоставимой с Linux, с применением ООП (например, на C++)

см. Бьярн Страуструп, «Дизайн и эволюция С++», история.

С++ появился как попытка структурировать в ООП стиле Unix ядро.

//тред не читал

anonymous
()

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

а нафига?

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

нельзя. Всё равно понадобится какой-то более общий примитив, чем классы. Например, «модули ядра», которые можно загружать/выгружать.

hint: вот например в Inferno сделаны модули: (1, 2 там их можно загружать/выгружать, подгружать модули в Shell, расширять с Си в сторону Limbo и с Limbo в сторону Си).

Без всякого «ООП», заметь.

В Eclpise же для этого целую OSGi наворотили, «типа-пакеты-как-в-лиспе-только-в-яве»

Минус - необходимость поддержки ООП в ядре влечёт за собой некоторый overhead

исчо минусов:

- нестабильный ABI для драйверов. драйвера в BeOS/Haiku, например 1, 2 )

- Проблема FBC : «Fragile Base Class» (1) в C++ (2).

- сложности расширения и повторного использования именно С++-ной реализации ООП.

Тащемта, минусы в основном — к реализации на C++, к языкам с нормальной реализацией ООП претензий нет.

anonymous
()
Ответ на: комментарий от anonymous

Без всякого «ООП», заметь.

В Eclpise же для этого целую OSGi наворотили, «типа-пакеты-как-в-лиспе-только-в-яве»

я так понимаю, что годный примитив для реализации «модулей ядра» — это аспекты. а не классы и отдельные объекты.

anonymous
()
Ответ на: комментарий от anonymous

нестабильный ABI для драйверов.

итого: хотя С (ядро) и С++ (драйвера, приложения) можно правильно смешивать, (как пример — BeOS API см. BeBook или например, IOKit в MacOSX) в итоге получается и не С++ и не С, а что-то среднее (embedded C++).

В итоге польза от С++ не так велика, как могла бы быть, и не очень нужно (в сочетании с хрупким С++ ABI).

anonymous
()
Ответ на: комментарий от korvin_

В Go предлагают писать без блокировок

Прямо как в Эрланге они там советую делать.

Но мьютексы тоже есть - с разделяемой памятью иначе никак, либо они, либо STM.

quasimoto ★★★★
()
Ответ на: комментарий от quest

а тут видимо предлагается апофеоз с кучей темплейтов, наследований и reinterpret_cast

Не, вот темплейтов я действительно не хочу. Насмотрелся уже, как они себя ведут на разных компиляторах и даже на разных версиях одного и того же gcc. В опу такую «переносимость».

А вот классическое «крестовое» наследование, если им пользоваться разумно - вполне мощная и неплохая штука.

hobbit ★★★★★
() автор топика
Ответ на: комментарий от anonymous

хотя С (ядро) и С++ (драйвера, приложения) можно правильно смешивать, (как пример — BeOS API см. BeBook или например, IOKit в MacOSX) в итоге получается и не С++ и не С, а что-то среднее (embedded C++).

Кстати, по моим ощущениям, большинство программ, авторы которых заявляют, что они написаны на C++, на самом деле представляют собой дикую смесь C и C++, как правило, ещё и усугублённую применяемым тулкитом.

hobbit ★★★★★
() автор топика
Ответ на: комментарий от buddhist

Сами додумаете остаток срача.

Додумывать не пришлось, он и так получился очень интересным, в отличие от унылых дебатов «KDE4 vs Gnome3 vs Windows8». Столько хороших ссылок накидали - месяца на 2 хватит.

hobbit ★★★★★
() автор топика

С++ подобное ооп уже юзают теже WinNT - не факт , что на пользу.

если ж юзать в ОС ооп но СObj(smalltalk-like) - иначе :(

qulinxao ★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.