minimalistic cache
isFinite
tells us whether we can cache it; maybe it's coming from a predicate that checks the size, or something.class Cache[K,V](isFinite: Boolean, build: K => V): private val cache: mutable.Map[K, V] = mutable.Map[K, V]() private val app: K => V = if (isFinite) (k: K) => cache.getOrElseUpdate(k, build(k)) else (k: K) => build(k) inline def apply(k: K): V = app(k)
а я-то думал
Всё мне не нравится, что тесты на мой категорный код идут часа чуть ли не два. Науськал наконец на неё кводану (Qodana) - типа вот, найдут дефекты перформанса. И вот что я утром вижу:
No problems detected
The found no issues.
Придётся вручную изучать вопрос. Но на самом деле больше вопросов с зависимыми типами.
scala 3.6.1, 3.6.2
Затрахался последние дни с проблемами компиляции - добавишь что-нибудь в trait, а компилятор бац - и несёт какую-то херню. Собрался уже вырезать кусочек и послать им багрепорт. Погуглил. Ха, в 3.6.1 баги. А вот 3.6;2 уже вроде бы не рушит компиляцию.
Ну посмотрим, посмотрим. А то сидишь такой рефакторишь, и тут бац - не связанные с этим классом классы перестают компилироваться.
Тьфу.
жизнь собачия
Теперь что. Добавил тесткейс.
Упс. Компилятор кирдык. scalac. Зацикливается.
Окей. Закомментировал пока большую часть того кейса.
Упс. Другие тесты не идут. А чо? А-а--а-а-а! Вставил запятую.
Вот что это вообще.
Настанет, наверно, момент, что я завяжу со скалой. Там какие-то ебанаты. Сейчас пошел очередной скандал, там какая-то дура, "заведующая скальной комьюнити", образование у нее - политология, из белградского университета, решила Джона де Гоуза не допускать в качестве спикера (или вообще?) на конференции. (Ну, к Джону главная претензия - что он лысый и мускулистый: не иначе расист.) Другого Джона (Прити) вообще выпинали отовсюду, потому что гелфренда одного левого экстремиста из Берлина нажаловалась публично, что ранее Джон Прити с ней трахался (а жениться не захотел).
Какая хуйня, прости господи. Надо вернуться на Форт, там дедушки мирные, все улыбаются (и я их почти что в лицо знаю, а уж по сорс-коду так точно, читал как стихи когда-то). Тоже маразм, конечно.
(no subject)
object Pathos {
val firsts =
"авто,агро,апо,арахно,аристо,астро,аэро,био,бюро,вело,гастро,гео,гербо,геронто,герпето,гетеро,гидро,гипер,гипно,гомео,гомо,графо,демо,дендро,зоо,изо,ихтио,како,квази,клепто,крипто,мегало,метро,микро,моно,мото,невро,нейтро,некро,неонато,нимфо,олиго,опто,орто,орфо,охло,панто,пара,пато,парто,педо,пиро,плуто,поли,прото,психо,птеро,ретро,тео,топо,физио,фило,фито,фото,шизо,экзо,эко,эндо,энцефало,эпи".split(",").toList
val seconds = "арх,граф,крат,лог,ман,мах,метр,ном,пат,пед,соф,тон,топ,фил,фоб,фон,френ".split(",").toList
val isEndVowel = "аеоуэюя".toSet
val isVowel = "аеиоуэюя".toSet
def word(first: String, second: String) =
if (isVowel(second.head) && isEndVowel(first.last))
first.dropRight(1) + second else first + second
val header =
s"<td/>${seconds map (w => s"<th> $w </th>") mkString ""}"
def row(f: String) =
s"<th aligh=left> $f </th>${seconds map (s => s"<td style='text-align:center'> ${word(f,s)}ия </td>") mkString ""}"
val content = (header :: (firsts map row)).mkString("<tr>", "</tr>\n<tr>", "</tr>\n")
def main(args: Array[String]): Unit = {
println(s"<table>$content</table>")
println("<br/>")
println(firsts map(f => s"${f}сексуализм") mkString(", "))
}
}
here's a better transformer version
class Test extends AnyFlatSpec with Matchers { "transformer" should "work" in {
// source: https://contributors.scala-lang.org/t/ability-to-force-the-caller-to-specify-a-type-parameter-for-a-polymorphic-method/2116/26
sealed trait NotNothing[-T]
object NotNothing {
@implicitAmbiguous("inst() method needs a generic parameter type, which is missing")
implicit val nothingIsNothing = new NotNothing[Nothing]{}
implicit def notNothing[T] = new NotNothing[T] {}
}
implicit class Transformer(source: String) {
def as[T : NotNothing : ClassTag] = {
import scala.reflect._
val cls: Class[T] = classTag[T].runtimeClass.asInstanceOf[Class[T]]
val cons: Constructor[T] = cls.getDeclaredConstructor(classOf[String])
cons.newInstance(source)
}
}
val a0 = "good A".as[A]
val b0 = "good B".as[B]
a0.getClass shouldBe classOf[A]
b0.getClass shouldBe classOf[B]
a0.toString shouldBe "A(good A)"
b0.toString shouldBe "B(good B)"
}
}
class Base
case class A(val s: String) extends Base
case class B(val s: String) extends Base
тонкая фигня со скальной рефлексией
def inst[T](s: String)(implicit tag: ClassTag[T]): T = {
val cls = tag.runtimeClass
val cons = cls.getDeclaredConstructor(classOf[String])
cons.newInstance(s).asInstanceOf[T]
}
Мол, возьми строку и проинстанциируй тип, какой тебе дадут. Такого конструктора может и не быть, но здесь просто примерчик.
А штука в том, что вот нарисуем мы юзкейсы,
class A(val s: String) extends Zero
class B(val s: String) extends Zero
val a1: A = inst("anA")
val b1: B = inst("aB")
- и чо? Скомпилируется, а рантайм не пойдет - в строке, где мы конструктор ищем, выяснится, что класс у нас Nothing - упс!
Ну, Nothing - это инициальный объект; скала не нашла, какой там ClassTag подсунуть, и подсовывает ClassTag инициального.
Ну хорошо, хорошо, давайте подымемся по иерархии, и станем проверять параметр типа:
def inst[T >: Null](s: String)(implicit tag: ClassTag[T]): T = {
val cls = tag.runtimeClass
val cons = cls.getDeclaredConstructor(classOf[String])
cons.newInstance(s).asInstanceOf[T]
}
А хрен вам, опять в рантайме обломится. Потому что Null можно присваивать хоть кому (спасибо Хору).
Ну ладно, Null никто не подставляет. Запрещать имеет смысл только дефолтный Nothing.
Вот как это делается:
sealed trait NotNothing[-T]
object NotNothing {
@implicitAmbiguous("Method needs a generic parameter type, which is missing")
implicit val nothingIsNothing = new NotNothing[Nothing]{}
implicit def notNothing[T] = new NotNothing[T] {}
}
И затем пишем
def inst[T : NotNothing : ClassTag](s: String): T = {
import scala.reflect._
val cls: Class[T] = classTag[T].runtimeClass.asInstanceOf[Class[T]]
val cons: Constructor[T] = cls.getDeclaredConstructor(classOf[String])
cons.newInstance(s)
}
В результате компиляции
val a0 = inst[A]("good A")видим
val a1:A = inst("ana")
val b1:B = inst("ab")
/Users/vpatryshev/projects/test/Test.scala:185:20
inst() method needs a generic parameter type, which is missing
val a1:A = inst("ana")
my funny old code
package scalakittens
/**
* A trait that describes a goodness of data or outcome or something
*
* Created by vpatryshev on 10/18/15.
*/
trait Goodness:
def isGood: Boolean
def isBad: Boolean = !isGood
trait PositiveAttitude extends Goodness { def isGood = true }
trait NegativeAttitude extends Goodness { def isGood = false}
Scala: Free, back with a vengeance
https://www.youtube.com/watch?v=2yRtxYbV1h4