xacid: (Default)
как это уже известно, в хаскеле всё по умолчанию ужасно ленивое до такой степени что иногда, в редких к счастью случаях, приходится даже строго форсить вычисление (это в хаскеле так, понятно вобщем наверное :)

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

это вобще к чему я повторяю такие известные всем трюизмы? сравнительно недавно прочитал в списке рассылки такие вот примерно слова нашего уважаемого runarorama:

The problem with this kind of thing is almost always that something is too strict. In this case there are a few places where we are not quite lazy enough. One of those is the (,) Tuple2 constructor in unfold.

When we say (x, y) in Scala, both x and y are evaluated strictly, because this constructor is strict in both of its arguments.

A solution here is to use a lazy pair data type:

case class LazyPair[A,B](a: () => A, b: () => B)

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

но в данном случае я хотел сказать немного другое (это всё было как бе предисловие). я вот о чем на досуге подумал както - а почему собственно нужно определять LazyPair? то есть вопрос собственно в том что если делать всё таким образом то получится нужно для каждого отдельного случая (структуры данных) определять отдельную ленивую версию. и действительно - я посмотрел scalaz и вижу что там много таких ленивых структур данных:

object LazyEither extends LazyEitherInstances with LazyEitherFunctions
object LazyEitherT extends LazyEitherTInstances with LazyEitherTFunctions with Serializable
object LazyOption extends LazyOptionInstances with LazyOptionFunctions with Serializable
object LazyOptionT extends LazyOptionTInstances with LazyOptionTFunctions with Serializable
object LazyTuple extends LazyTupleFunctions
object LazyTuple2 extends LazyTuple2Instances
object LazyTuple3 extends LazyTuple3Instances
object LazyTuple4 extends LazyTuple4Instances

с одной стороны конечно в этом возможно и есть какойто глубокий смысл, но с другой стороны а что если мне нужно еще что нибудь сделать ленивым? мне что полностью переопределять весь тип заново чтобы создать его ленивый вариант? а что если вместо этого просто определить следующий тип:

class Lazy[T](f: => T) {
  lazy val get = f
  def apply() = get
}
object Lazy {
  def apply[T](f: => T) = new Lazy(f)
}


и тогда например можно так написать (ну это только пример для аналогии с тем что Рунар показывал, думаю понятно конечно):
type LazyPair[A,B] = (Lazy[A],Lazy[B])

будет ли это чем нибудь плохо? ну есть конечно определенный недостаток - меняется тип: вместо просто T он становится уже Lazy[T]. но даже если считать это и недостатком (что еще не факт но допустим) то есть зато другое серьезное преимущество - мы можем делать ленивой вообще любую существующую уже в скале структуру данных. то есть мы можем произвольным образом в любой момент перейти от строгих вычислений к ленивым - и даже в типе данных этот факт будет отражен, что на самом деле может быть даже очень и полезно (факт отражения ленивости в типе).

написать что ли им об этом в это их спортлото?

это ж монада получается даже:
  implicit val m = new Monad[Lazy] {
    def point[A](a: => A) = Lazy(a)
    def bind[A, B](fa: Lazy[A])(f: A => Lazy[B]) = Lazy(f(fa())())
  }
xacid: (Default)
... не помешали всем желающим сегодня послушать и посмотреть довольно интересную (на мой взгляд) функциональную тусовку под названием Most Functional Day в Киеве:

http://frameworksdays.com/event/most-functional-day

В частности, широко известный в узких кругах Роман Чепляка рассказал о "мета-дженериках" в хаскеле:

http://ro-che.info/docs/2014-08-09-generic-programming-in-haskell/

Духовно продвинутый Номдак Томпа (да пребудет с ним его нирвана!) вдохновлял публику своей личной закисью азота на которой он сам уже давно и плотно сидит:

http://slides.com/maximsokhatsky/n2o#/

А обаятельный Александр Соловьев непринужденно демонстировал особую скриптовую магию с заклинанием змей:

https://github.com/piranha/qsnake

Так же были диковинные но любопытные Nix и Genera LispOS

https://speakerdeck.com/proger/nix-l-toolchain
http://www.slideshare.net/vseloved/todays-view-of-the-lisp-machine

А из довольно беглого доклада нашего Scala-активиста Руслана Шевченко я даже узнал новое для себя слово - Mahout:

http://www.slideshare.net/rssh1/ruslanshevchenko-most-functionalday2014

Вобщем я не могу не отметить это позитивное событие :)

За развитием событий можно проследить в твиттере по тегу #fwdays

Profile

xacid: (Default)
xacid

June 2017

S M T W T F S
    123
45678910
11121314151617
18192021222324
252627282930 

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 26th, 2017 06:35 am
Powered by Dreamwidth Studios