LINUX.ORG.RU

В каких высокоуровневых языках программирования есть пайпы и конвеер?

 ,


1

2

Доброго времени суток

Пощупал powershell ( под linux тоже есть ) и был приятно удивлён тем, что внутри есть конвееры. Даже то, что он работает с объектами, не так значительно.

Написал пару скриптов для vsphere и понимаю, что на любом другом языке несколько пайпов пришлось бы менять на трёхэтажные циклы. Код по сравнению с конвеером крайне раздувается и становится менее читаемым. Да, вместо циклов можно взять например лямбды. Но они тоже усложняют код. Возможно, даже больше циклов. На перле уже 2-3 вложенных map'а переполняют стек в голове :)

Да, можно взять старый добрый bash. Но любой пайп порождает процессы. И что хуже, более-менее сложную обработку данных приходится переносить на другие языки. И чтобы объединить такие куски кода в конвеер, придётся оформлять их в виде отдельных файлов. Хотелось бы что-то высокоуровневое вроде питона

Так вот. Есть ли высокоуровневые языки, в которых можно использовать пайпы для объединения в конвеер отдельных частей кода ? Или хотя бы можно организовать что-то подобное конвееру без нагромождения кода

★★★★★

Последнее исправление: router (всего исправлений: 2)

REXX же.

А вообще, непонятно, что тебе надо. Или этот тред только для тех, кто знает Powershell?

tailgunner ★★★★★
()

Но любой пайп порождает процессы

Это хорошо.

обработку данных приходится переносить на другие языки. И чтобы объединить такие куски кода в конвеер, придётся оформлять их в виде отдельных файлов.

$ function uscore() { tr ' ' _; }
echo "derp
> herp derp
> herp derh shit
> shitty crap
> wow" | uscore | grep shit
herp_derh_shit
shitty_crap
legolegs ★★★★★
()

в любом где есть вызов процедур

var stdout;

stdout = source();
stdout = subpogram(stdout);
....
stdout = subpogram(stdout);

и т.п.

если хочется сахарку то надо смотреть конкретный ЯП и его синтаксис

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от tailgunner

REXX же.

Хмм... Забыл добавить - «живой» :) Судя по вики это была хорошая вещь, но у меня нет задачи писать код под такие раритеты

А вообще, непонятно, что тебе надо. Или этот тред только для тех, кто знает Powershell?

Хочется пайпы, как в bash, но для высокоуровнего языка вроде python Т.к. с конвеером большинство циклов можно выбросить

Get-VDSwitch -Name dVSwitch-DS | Get-VDPortGroup | Where-Object { $_.Name -like "*uplink*" } | 
   Get-VDPort |  Where-Object { $_.ConnectedEntity -match "vmnic" }  | 
   foreach-object { 
     blahblah. тут выполняем какие-то действия и возвращаем уже новый объект с нужными полями
   }

Вместо примерно такого

@result = ();
for my $dvswitch in ( Get-VDSwitch -Name dVSwitch-DS ) {
    for my $portgroup in ( Get-VDPortGroup( $dvswitch ) {
        if ( $portgroup.Name =~ m/uplink/ ) {
            for port in ( get-vdport( $portgroup ) ) {
                if ( $port.ConnectedEntity =~ /vmnic/ ) {
                    blahblah. тут выполняем какие-то действия и добавляем в масссив @result новый объект
                }
            }
        }
    }
}
router ★★★★★
() автор топика

Так вот. Есть ли высокоуровневые языки, в которых можно использовать пайпы для объединения в конвеер отдельных частей кода ? Или хотя бы можно организовать что-то подобное конвееру без нагромождения кода

Haskell, F#, не?

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

Это хорошо.

Хорошо, если ползено и удобно. Но в большинстве языков есть работа с регулярками и не нужно выполнять fork на элементарный grep

> «wow» | uscore | grep shit

Да, bash можно включать в конвеер свои функции. Но для меня bash часто оказывается недостаточно высокоуровневым. Я не программист, а админ. Поэтому давно использую Perl и Python

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

в любом где есть вызов процедур

Это мягко говоря не то. Попробуй подать в такой конвеер лог файл гигов на 10

router ★★★★★
() автор топика
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

Ну на Хаскелле, условно, было бы так:

getVDSwitch "dVSwitch-DS" >>= getVDPortGroup >>= filter (\g -> (name g) `like` "*uplink*") >>=
    getVDPort >>= filter (\p -> (connectedEntity p) `match` "vmnic") >>=
    mapM_ (\x -> do
        blahblah
    )

На F# примерно также, но я не знаток, пусть меня поправят.

korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 1)
Ответ на: комментарий от router

Это мягко говоря не то. Попробуй подать в такой конвеер лог файл гигов на 10

не поверишь, элементарно, никто не утверждает же что stdout - строка

посмотри как например сделаны stream (те которые над коллекциями) в java

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

REXX же.

Хмм... Забыл добавить - «живой» :) Судя по вики это была хорошая вещь

Это было УГ (ага, я на нем писал).

Хочется пайпы, как в bash, но для высокоуровнего языка вроде python

Это понятно. Вопросы 1) что ты хочешь объединять в конвееры - чистые функции? или нечто с внутренним состоянием? 2) тебе нужен именно синтаксис «cmd1 | cmd2 | cmdN» или, например, «pip = mkpipe([cmd1, cmd2, cmdN])»?

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

какой то у вас странный вопрос. В конвеере берешь результат выполнения одной команды и отдаешь его в качестве аргумента другой. В любом ЯП ты делаешь то же самое. Берешь функцию результат ее выполнения отдаешь другой функции. Тот же «конвеер» только намного более гибкий. Оформить ты это можешь как в виде отдельного треда так и с помощью колбеков или событий.

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

Идеально :)

А это честный конвеер, или передача через временную переменную всего объёма данных сразу?

Т.е. можно ли через конвеер хаскеля прогнать 10 Гб на машине с 1 Гб RAM ?

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

Мне нужно избавиться от лишних циклов и вложенности, и при этом по-прежнему иметь возможность гонять большой объём данных, как через обычные линуксовые пайпы.

Именно синтаксис не так принципиален

router ★★★★★
() автор топика
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от antech

См. выше - «Это мягко говоря не то. Попробуй подать в такой конвеер лог файл гигов на 10»

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

В любом ЯП ты делаешь то же самое. Берешь функцию результат ее выполнения отдаешь другой функции

Значит ты берёшь, и 1000 Гб кладёшь в стек? Ну, ок. У меня есть серверы, в которых такое теоретически пройдёт. Но за такую «оптимизацию» побьют тряпками

Оформить ты это можешь как в виде отдельного треда так и с помощью колбеков или событий.

Именно что через треды и какой-то буфер. Вручную порождая процессы и контролируя наполнение буферов. На любом языке программирования написать и таскать с собой существенную часть ядра linux?

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

А это честный конвеер, или передача через временную переменную всего объёма данных сразу?

В Хаскелле всё лениво по-умолчанию, в т.ч. и списки, например.

Т.е. можно ли через конвеер хаскеля прогнать 10 Гб на машине с 1 Гб RAM?

А хз, я не пробовал. Попробуй.

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

Именно синтаксис не так принципиален

Тогда Java Stream API ещё, например.

Да в общем-то в любом языке можно это реализовать.

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

Ну вообщем то да. Можно конечно и сразу, но лучше наверно по частям. Зачем вам контролировать объем буфера? Вручную вы только код пишите остальное делает машина за вас. В этом и есть суть.

antech
()

теги: я познаю мир

В большинстве взрослых языков есть итераторы/генераторы/ленивые последовательности/хоть горшком назови. А также map/filter/reduce/list comprehensions/you name it.

Ты кроме ракушечки и жемчужинки ни на чём не писал штоле?

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

Важнее был ответ на «устроят ли тебя чистые функции». Если устроят, то на Python примерно так (вероятно, такая функция есть в stdlib более-менее новых Python):


def mkpipe(cmdlst):
   def run1(a):
     for cmd in cmdlst:
       a = cmd(a)
     return a
   return run1

def c1(a): return str(a) + "-- cmd"

map(mkpipe([c1, lambda x: str(x) + "-- lam"]), [1, 2, 3])

Объединение через «|» тоже можно сделать, но там придется писать декоратор.

А вот если нужна зависимость от внутреннего состояния, придется делать на итераторах, и там всё становится несколько нетривиально.

P.S. https://toolz.readthedocs.io/en/latest/streaming-analytics.html

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: теги: я познаю мир от anonymous

Я чесно не понимаю чего автор хочет и чем недоволен. Неужели этот непрограммист-админ всерьез считает что то что он пишет на повершеле нельзя написать на cpp? что за бред про 10гигов лога и ручной труд по управлению буферами он несет? Быть может он уже 1г этих логов таки прочитал вручную :D вот крышу и унесло.

antech
()
Ответ на: теги: я познаю мир от anonymous

теги: я познаю мир

Добавил :D

Ты кроме ракушечки и жемчужинки ни на чём не писал штоле?

Неожиданно, да? Моя профессия не программист, поэтому я трачу время на изучение других вещей.

Список несколько длиннее, но в основном perl и python. Причём последний я изучал не досконально, а только чтобы начать его использовать

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

Наверное это здорово, но читается сложно. Я догадываюсь, что конвеер в последней строке, но в упор не вижу, что в каком порядке пойдёт

Пока посмотрю хаскель

router ★★★★★
() автор топика
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

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

O_o

Если тебе это сложно... ну, посмотри Хаскель %)

tailgunner ★★★★★
()

тогда уж наверняка есть реализации в стиле c++ cout

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

Неужели этот непрограммист-админ всерьез считает что то что он пишет на повершеле нельзя написать на cpp?

Нет. Но то, что я напишу на повершеле за 5 минут, ты на cpp будешь писать 5 дней, а потом ещё столько же отлаживать.

Да, твой софт будет работать в разы и даже на порядки быстрее

Но для админа-непрограммиста важно то, что код является не целью, а средством. Мне нужно не написать скрипт, а решить задачу. Часто код пишется для автоматизации однократного действия. Однократного, Карл!

что за бред про 10гигов лога и ручной труд по управлению буферами он несет?

Про pipe что-нибудь слышал? Обычный unix/linux pipe. Одна команда пишет в буфер. Другая из него читает. Буфер создаётся ядром linux. И ядро же поддерживает его размер. Размер буфера, навскидку, порядка мегабайта. И через него без проблем пройдёт любой объём данных без дополнительных требований к ресурсам. Буфер заполнен? Ядро приостановит первый процесс и запустит второй. Освободился - снова запускаем первый

Ты предлагаешь то, что выполняет ядро, just for fun написать на твоём cpp и таскать с собой в виде библиотеки? Да это ты обкурился :) Я уже сильно сомневаюсь, что ты работаешь программистом. Или хотя бы просто работаешь ;)

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

Ты хочешь странного. У тебя уже все есть в системе.

Но любой пайп порождает процессы.

Один раз! — не в цикле же миллионы раз.

Да, можно взять старый добрый bash.

Да это клей для:

более-менее сложную обработку данных приходится переносить на другие языки.

Для специфических данных тебе все равно придется запустить что-то от вендора (типа для vsphere)

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

Если тебе это сложно... ну, посмотри Хаскель %)

Ничё-ничё, вот узнает функцию compose, может и твой mkpipe осилит. =)

korvin_ ★★★★★
()

Можно поизвращаться в питоне: дать multiprocessing.Pool. Туда нарезать задачи и запускать через apply_async, указывая коллбек, который полученные данные запихнёт уже с новой функцией и новым коллбеком в тот же пул процессов. Финальный коллбек запишет туда, куда ты хочешь.

Надо попробовать. Может получиться неплохой многопроцессный конвеер. А может говно.

Можно ограничивать всё, конечно. Обычная producer-consumer задача.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 1)

Судя по запросам про файлы на 100500 ГБ вам таки нужен std::fstream. Ну а по сути: чем не устроили Python'ные генераторы?

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

Т.е. можно ли через конвеер хаскеля прогнать 10 Гб на машине с 1 Гб RAM ?

Да, но аккуратно. Можно выжрать стек рекурсией и/или память thunk-ами.

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

Хочется пайпы, как в bash, но для высокоуровнего языка вроде python

Get-VDSwitch -Name dVSwitch-DS | Get-VDPortGroup | Where-Object{ $_.Name -like «*uplink*» } | Get-VDPort | Where-Object {$_.ConnectedEntity -match «vmnic» } | foreach-object { blahblah. тут выполняем какие-то действия и возвращаем уже новый объект с нужными полями }

Баламут! Ты хочешь SQL-like, а просишь пайпы :-\

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

Я думаю, что осилить mkpipe попроще, чем осилить Хаскель в объеме, достаточном для написания приведенного тобой конвейера.

tailgunner ★★★★★
()

Есть ли высокоуровневые языки, в которых можно использовать пайпы для объединения в конвеер отдельных частей кода ?

Любой, из которого можно pipe(2), dup(2) and such? Соединяйте старые дескрипторы. Создавайте новые дескрипторы. Пишите и читайте! А перегрузив бар |, вы получите милую безделушку, которая обязательно понравится детям до 40 лет.

d_a ★★★★★
()

Да, можно взять старый добрый bash. Но любой пайп порождает процессы. И что хуже, более-менее сложную обработку данных приходится переносить на другие языки. И чтобы объединить такие куски кода в конвеер, придётся оформлять их в виде отдельных файлов.

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

Хотелось бы что-то высокоуровневое вроде питона

Пыхтонг можно прямо так заинлайнить, но это забавно только первое время.
https://github.com/Jajauma/www-data/blob/master/.bin/ShutdownAndBackup#L111

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

Я думаю, что осилить mkpipe попроще, чем осилить Хаскель в объеме, достаточном для написания приведенного тобой конвейера.

Ну, может, сработает метод «от противного»: попытается ТС осилить Хаскелл, поплюётся от борьбы с системой типов, монадами и прочим, да и возьмётся за Пайтон, что для админа-непрограммиста более приемлемо. В общем, вариантов ему тут накидали достаточно, чтобы было что попробовать и выбрать, что ему проще будет. Странно, что имея опыт с PS, он не обратил внимание на F#.

router, F# вроде как можно интегрировать с PowerShell'ом.

korvin_ ★★★★★
()
Последнее исправление: korvin_ (всего исправлений: 1)
Ответ на: комментарий от d_a

Соединяйте старые дескрипторы. Создавайте новые дескрипторы. Пишите и читайте!

Копируйте данные в ядро! Копируйте данные из ядра! Ждите! Дожидайтесь! Сериализуйте! Десериализуйте!

tailgunner ★★★★★
()
Ответ на: Вот и хорошо от d_a

Вот и хорошо

И быстро.

IPC получился заодно, и на SMP само всё загрузит

«Ничего себе сходил за хлебушком» (ц)

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

Т.е. можно ли через конвеер хаскеля прогнать 10 Гб на машине с 1 Гб RAM ?

Можно. Даже со стандартными строками. А со специальными библиотеками а-ля conduit или pipes это получается ещё и достаточно быстро.

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

В Matlab всю жинь каждую функцию надо было в свой одноимённый файлик класть. Зато принудительная модульность, всё такое.

Можно в один файл класть несколько. Но они будут в локальной области видимости.

nezamudich ★★
()

Чет я вспомнил openssl-ные BIO и GStream-овский конвеер ...

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