LINUX.ORG.RU

Scala, красиво инициализировать массив


0

2

Есть тут на ЛОРе люди, которые получше пишут на Scala, чем я нуб. Как очень кратко и красиво заполнить массив случайными числами (или например 5ками). Массив уже есть, нужено существующий. Как сделать это максимально божественно и кратко? Циклом и я могу

★★★★★

Ты хочешь заполнить уже имеющийся массив - что противно функциональной парадигме => ничего лучше цикла нету - он проще и понятнее, и даже если записать это лямбдами будет хуже. Присвоение слайсов в скале AFAIK нету, да и по эффективности лучше уж тогда просто новый массив создать.

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

Да вроде без цикла тут никак. Вот если бы не нужно было в условии использовать существующий массив, то все было бы проще:

Array.fill(10)(5)
Но внутри это все тот же цикл.

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

А, все понял, не то. Тебе в существующий нужно.

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

Ну тогда, как уже упоминал theos, только цикл. Ну или менять условия задачи чтоб функциональщину во все поля :-)

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

>> да и по эффективности лучше уж тогда просто новый массив создать.

почему?

Да потому что он и так создается - так чегоже добру зря пропадать :)

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

5 баллов! блин выкрутились круто, одобряю.

Но по сути вопроса не подходит ибо внутри будет создан все равно список, почему бы просто не создать новый и так. Я хочу экономить на new

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

Нет уродливых length и _теоретически_ не обязуется исполняться последовательно насколько я понял. А если так, то возможен параллелизм. Естественно теоретически, ибо автоматический параллелизм где не надо - не очень торт

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

> Нет уродливых length и _теоретически_ не обязуется исполняться последовательно насколько я понял.

Т.е. от первого же представленного варианта, (0 until x.length) foreach(x(_)=5), это отличается только тем, что length спрятан в indices?

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

Вообще да ) Они все не идеальны. Идеалом был бы какой нибудь a.foreach(_=rnd), но упоротые сделали переменную в foreach immutable

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

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

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

меньше возможности перепутать массивы

вообще можно

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

> но упоротые сделали переменную в foreach immutable

По-моему ты фигней страдаешь :)

dave ★★★★★
()

Кстати, foreach в скале реализован неэффективно, что мне ужасно не нравится. Только для того, чтобы пройтись циклом, зачем то выделяется на куче память, создается замыкание и вызывается метод foreach. Жуть.

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

Не согласен. В лиспе еще есть вещи, которых нет в других языках/платформах. Не все использовали. Взяли только то, что могли.

Кстати, мне лично нужен. Жаль только, что лисп с возможностью делать приложения с красивым GUI стоит денег. Я имею ввиду LispWorks.

Что касается скалы, она не только жручая до памяти, но и ужасно монструозная. Я понимаю, классы типов через имплисыты - это клево, но выглядит это жутковато. Да, и отсутствие TCO делает недавно введенные продолжения почти бесполезными. Плюс, for-comprehension выглядят непродуманной вещью по сравнению с computation expressions из F#: тогда не надо было бы, вообще, писать плагин к компилятору скалы для поддержки продолжений. Анбоксинг тоже не самая лучшая штука, если пишешь в функциональном стиле, но это как и TCO камни в огород JVM.

Ну, еще что-то мне не понравилось. Хотя не безрыбье скала очень хороша. Конечно, если не дают писать на Common Lisp :)

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

> Жаль только, что лисп с возможностью делать приложения с красивым GUI стоит денег. Я имею ввиду LispWorks.

сейчас должен прийти Архимаг и объяснить тебе, что красивый современный GUI запросто делается на JS (а CL в качестве «сервера приложений»)

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

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

Но это не все TCO. Хвостовые вызовы еще должны оптимизироваться на уровне среды исполнения. Здесь это виртуальная машина JVM. Поскольку далеко не любой код, полагающийся на TCO, может быть преобразован к циклам. Пример - продолжения.

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

> сейчас должен прийти Архимаг и объяснить тебе, что красивый современный GUI запросто делается на JS (а CL в качестве «сервера приложений»)

А его что-то давно не видно :)

Веб - stateless. Апликуха же обычно stateful. И никак это противоречие нельзя победить. Существующие попытки тщетны. Например, ASP.NET передает состояние в скрытых полях, но это же никуда не годится!

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

А вы scalaz смотрели, конкретнее к примеру state monad. (В целом, библиотека классная, требует конечно определенных знаний). Считай на каждое изменение состояние создается экземпляр типа Tuple2[_,_]. Так что да - на объектах не экономим в угоду, удобству, выразительности и чистоте.

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

Но я так понял что это для pure functional, и скала потому и хороша, что не pure functional, так как оно не нужно

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

Кстати, удобный случай пропробовать исходя из вашего задания - есть изменяемый массив, так, как говориться for fun :)

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

Синтаксический сахар для монад и моноидов. Более общий, чем for-comprension в скале или do-синтаксис в хаскеле. Например, там поддерживаются for, while, use, try. Последние преобразуются в функциональную форму.

В общем, получается так, что можно внутри вычислительного выражения (computation expression) писать обычный или почти обычный код на f#, который затем будет преобразован (интерпретирован) в функциональное выражение, соответствующее той или иной монаде или моноиду. Конечно, есть аналог flatMap.

В качестве примера можно взять f# sequence expression, который позволяет красиво задавать последовательности, разбавляя почти обычный код в нужных местах конструкциями yield и yield!, через которые собственно и формируется возвращаемая последовательность.

Посылка в том, что вычислительные выражения сделали бы излишним написание плагина к компилятору скалы для поддержки продолжений. Похожая на продолжения вещь в f# называется async worklflow, и она полностью определена на самом f# без дополнительной поддержки со стороны компилятора. Кстати, в async три продолжения используются вместо одного.

За дополнительной информацией лучше обратиться к учебникам.

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

Хм, почему неэффективно? Один вызов foreach, одна функция f: A => B применяемая для каждого элемента последовательности и тот же цикл с tail/head.

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

На common lisp можно написать эффективный код, который выделяет память в самом начале, а затем работает без обращения к GC. На яве, кстати, тоже. Похоже, что на скале это сделать намного сложнее.

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

>Хм, почему неэффективно?

Потому-что скорее всего создаётся отдельный класс (та самая функция), это раз, потом создаётся объект этого класса, это два, потом происходит динамический вызов (или не дай бог виртуальный вызов), это три. Хотя если в foreach вписывается конкретный код, а не подставляется именно сторонняя функция, кто запрещает всё заинлайнить?

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

>Что в вашей терминологии виртуальный и что такое динамический?

угу, сморозил, имелось в виду invokevirtual и invokeinterface

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

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

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

foreach это higher-order функция, поэтому про вписывание конкретного код не совсем ясно, впрочем как и про создание отдельного класса.

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