Пікірлер
@TeuvoLaaksonen
@TeuvoLaaksonen Ай бұрын
А какие методы работы с неизменяемыми структурами данных вы считаете наиболее эффективными? я сам недавно закончил универ и понял, что моя специальность мне не подходит, поэтому пошел на курсы Skypro и теперь работаю веб-дизайнером))
@zahodiChe
@zahodiChe 7 ай бұрын
11:13 минутка украинского😂
@Selavy82
@Selavy82 7 ай бұрын
Максим, приветствую! Не планируете курсы на этот год? Насколько я понимаю, Вы раз в 2 года запускаете обучение... И, если да, то - будет ли в этот раз 3-я Scala?
@sergio_leone_
@sergio_leone_ 8 ай бұрын
Здравствуйте. Спасибо за курс. Есть ли еще планы продолжить лекции?
@MaximValyanskiy
@MaximValyanskiy 7 ай бұрын
Курсы пока что на паузе.
@abazhutov
@abazhutov 9 ай бұрын
отличная лекция
@SergeyTarabara
@SergeyTarabara 10 ай бұрын
Спасибо за интересный контент! А можно ещё такое же, но про ZIO )
@oleg20century
@oleg20century 11 ай бұрын
Максим, спасибо!
@Blukkering
@Blukkering 11 ай бұрын
классный курс
@himmih
@himmih Жыл бұрын
Спасибо огромное за эти лекции!!!
@maslyakscala
@maslyakscala Жыл бұрын
нудновато)
@TheRedbeardster
@TheRedbeardster Жыл бұрын
Ух, итить, сам Макском! :) Правда ли, что русские физики выбрали шлакварь, а Луговский набил морду Руту? Шучу-шучу, лор - сила! :)
@ivanpriz4547
@ivanpriz4547 Жыл бұрын
Подскажите пожалуйста, у меня вот такая ошибка подсвечивается в VSCode + Metals: class org.apache.lucene.index.Term is not a value Для вот такого кода: import org.apache.lucene.analysis.ru.RussianAnalyzer import org.apache.lucene.index.Term import org.apache.lucene.analysis.tokenattributes.{CharTermAttribute, OffsetAttribute} import scala.collection.mutable.ArrayBuffer object Main extends App { def getTokenSequence(text: String): Array[Term] = { val analyzer = new RussianAnalyzer() val ts = analyzer.tokenStream("text", text) ts.reset() val out = new ArrayBuffer[Term] while (ts.incrementToken()) { val word = ts.getAttribute(classOf[CharTermAttribute]).toString() val offsets = ts.getAttribute(classOf[OffsetAttribute]) out += Term(word, offsets.startOffset(), offsets.endOffset()) // Вот здесь ошибка } out.toArray } } В чем может быть проблема? Не оттуда импортнул?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
В этом коде используется case class Term, объявленный на предыдущем слайде. Не нужно импортировать Term из Lucene.
@ivanpriz4547
@ivanpriz4547 Жыл бұрын
@@user-io8nj2ly1m Большое спасибо!
@andreyg1511
@andreyg1511 Жыл бұрын
Лекции у вас классные! А где же работающие примеры на гитхабе? Обнаружил только заготовки для проектов.
@user-wr2mp9gm1w
@user-wr2mp9gm1w Жыл бұрын
Спасибо!
@armanazhkhanov335
@armanazhkhanov335 Жыл бұрын
Слушайте а Datomic не решает все эти проблемы?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Эту задачу хотелось реализовать внутри нашего приложения. Если бы это не требовалось, то подошла бы какая-нибудь in memory СУБД, например Redis.
@Andrey-vw8kq
@Andrey-vw8kq Жыл бұрын
Очень интенсивная лекция. Спасибо! Заметил пару мелочей: 1. В этих строках не хватает возвращаемых типов (Encoder[Foo] и Encoder[Bar]): implicit val encodeFoo = Encoder.forProduct1("i")(f => f.i) implicit val encodeBar = Encoder.forProduct1("ls")(f => f.ls) 2. И не хватает декодеров для Foo и Bar в примере про очередность парсинга: implicit val decoderFoo: Decoder[Foo] = (c: HCursor) => c.get[Int]("i") .map(i=>Foo(i)) implicit val decodeBar: Decoder[Bar] = (c: HCursor) => c.get[List[String]]("ls") .map(ls=>Bar(ls)) 3. Там, где парсинг с type не нужны енкодеры, мы же декодим. Можно использовать deriveConfiguredDecoder. Вот так: import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto._ implicit val genDevConfig: Configuration = Configuration.default.withDiscriminator("type") implicit val decodeEvent: Decoder[Event] = deriveConfiguredDecoder val inFoo = """{"ls": ["a", "b"], "i": 1000, "type": "Foo"}""" val inBar = """{"ls": ["a", "b"], "i": 1000, "type": "Bar"}""" parser.decode[Event](inFoo) // Right(Foo(1000)) parser.decode[Event](inBar) // Right(Bar(List(a, b)))
@Andrey-vw8kq
@Andrey-vw8kq Жыл бұрын
Очень содержательный курс, Максим. Спасибо! Весь посмотрел, многое почерпнул и вспомнил. Мне кажется, в эту презентацию было бы неплохо добавить еще один слайд про анатомию type классов (3 компонента). И потом пояснить на примере моноида эти три компонента, что он как раз и есть непосредственно тайп класс (параметризованный трейт с функциями, которые надо реализовать), "implicit val busMonoid: Monoid[BusValue]" - наша реализация тайп класса для BusValue. И функция combineAll, вместе с остальными функциями Ops, это что-то вроде интерфейсного синтаксиса.
@esimitley4729
@esimitley4729 Жыл бұрын
Спасибо за уникальный контент
@GlebGigalov
@GlebGigalov Жыл бұрын
Спасибо за лекции
@mediazador
@mediazador Жыл бұрын
Максим, спасибо большое за данный материал. При первом знакомстве сталкивался с тем, что разные авторы рекомендовали начинать изучать либо с v2.x, либо с v3.x. Как понимаю, они отличаются достаточно, скажите пожалуйста, если начинать изучать scala, то с какой версии вы порекомендовали бы?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Зависит от целей изучения. В production сейчас чаще используется Scala 2, по этому если цель найти работу Scala-разработчика, то изучать нужно 2-ю. А если для развития кругозора или для личных проектов, то я бы выбрал Scala 3.
@LuckyCatAlex
@LuckyCatAlex Жыл бұрын
Это cats 2?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Да.
@helloworld5469
@helloworld5469 Жыл бұрын
Будет ли в этом году курс?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Весной курса не будет.
@Vikisnevistay
@Vikisnevistay Жыл бұрын
@@user-io8nj2ly1m А где можно будет узнать о старте курса?
@SergeyTarabara
@SergeyTarabara 10 ай бұрын
​@@user-io8nj2ly1m Когда ближайший курс?
@voynere
@voynere 3 ай бұрын
Когда?
@user-hn1ey5hn8u
@user-hn1ey5hn8u Жыл бұрын
14:22 в scala 3 можно не создавать отдельный объект, а написать функцию (через def) с аннотаций @main
@user-yq4gp4gv6d
@user-yq4gp4gv6d Жыл бұрын
Максим ваша эп пожалуйста.
@andrefimenko
@andrefimenko Жыл бұрын
21:10 У меня не работает этот код. Что я не так сделал? val fibs: LazyList[BigInt] = BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map {n => n._1 + n._2} val a = fibs.take(5).toVector println(a) forward reference to value fibs defined on line 13 extends over definition of value fibs fibs.zip(fibs.tail).map {n => n._1 + n._2}
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Этот код работает в случае если он находится внутри класса или объекта и fibs является его полем. Для того чтобы он заработал внутри функции нужно заменить "val" на "lazy val".
@andrefimenko
@andrefimenko Жыл бұрын
@@user-io8nj2ly1m Как тогда понять начинать код с object -name- extends App или def main....?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
@@andrefimenko В коде на слайде лучше всегда писать lazy val. То, что оно в объекте работает без "lazy" это довольно неочевидная особенность того, как устроены классы. По поводу main - я бы всегда использовал "App", просто потому что это немного корочем чем объявлять main.
@andrefimenko
@andrefimenko Жыл бұрын
48:57 Вариант хвостовой рекурсии: def filter(list: List[Int], pred: Int => Boolean, acc: ListBuffer[Int] = ListBuffer[Int]()): List[Int] = if (list.isEmpty) acc.toList else {if (pred(list.head)) filter(list.tail, pred, acc += list.head) else filter(list.tail, pred, acc)}
@andrefimenko
@andrefimenko Жыл бұрын
44:21 ------------------------------ val shortList = List(1, 2, 2, 3, 2, 4, 6, 5, 5, 10, 1) def count(list: List[Int], f: Int => Boolean): Int = list.filter(f).length println(count(shortList, x => x > 4 && x < 10)) ----------------------------- Что бы запустить эту неэффективную функцию нужно подать в неё и предикат, в моём случае x > 4 && x < 10. Вопрос: как можно создать переменную, что бы она и была предикатом? Типа того, но не работает ----- val pred = {x > 4 && x < 10}
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Проще всего просто объявить предикат через def как обычную функцию: "def f(x: Int) = x > 4 && x < 10". Но если очень хочется, то можно и вот так: "val f = (x: Int) => x > 4 && x < 10". С точки зрения последующего использования разницы нет, первая форма проще и понятнее.
@andrefimenko
@andrefimenko Жыл бұрын
@@user-io8nj2ly1m Методом тыка нашёл такие варианты: val pred: Int => Boolean = x => x > 4 && x < 10 val pred: Int => Boolean = (x => x > 4 && x < 10) val pred: Int => Boolean = {x => x > 4 && x < 10} val pred: (Int => Boolean) = x => x > 4 && x < 10 val pred: (Int => Boolean) = (x => x > 4 && x < 10) val pred: (Int => Boolean) = {x => x > 4 && x < 10}
@andrefimenko
@andrefimenko Жыл бұрын
Merge Sort Unique ------------------------------- import scala.annotation.tailrec import scala.util.Random object main extends App{ def mergeSort(seq: Vector[Int]): Vector[Int] = { val seqList = seq.toList seqList match { case Nil => Nil.toVector case xs::Nil => List(xs).toVector case _ => val (left, right) = seqList splitAt(seqList.length / 2) merge(mergeSort(left.toVector), mergeSort(right.toVector)).toVector } } @tailrec def merge(seq1: Vector[Int], seq2: Vector[Int], accumulator: List[Int] = List()): List[Int] = { val (seq1List, seq2List) = (seq1.toList, seq2.toList) (seq1List, seq2List) match { case (Nil, _) => accumulator ++ seq2List case (_, Nil) => accumulator ++ seq1List case (x::xs, y::ys) => if (x == y) merge(xs.toVector ,seq2List.toVector, accumulator) else if (x < y) merge(xs.toVector, seq2, accumulator :+ x) else merge(seq1, ys.toVector, accumulator :+ y) } } private val v = Vector.fill(1000)(Random.nextInt) // private val v = Vector(1, 1, 2, 3, 6, 1, 8, 8, 9, 3, 4, 2, 4) println(mergeSort(v)) }
@andrefimenko
@andrefimenko Жыл бұрын
Top-N Sort ------------------------------- import scala.collection.mutable.ArrayBuffer import scala.util.Random object TopN_Sort extends App { val data = ArrayBuffer.fill(1000000)(Random.nextInt) // println(data) def topN_Sort(data: ArrayBuffer[Int], n: Int): ArrayBuffer[Int] = { val acc = ArrayBuffer[Int]() for (i <- 0 to n - 1) acc += data(i) println("First acc: ", acc) for (i <- data.slice(n, data.length)) if (i < acc.max) { acc -= acc.max acc += i } acc } println(topN_Sort(data, 5)) }
@andrefimenko
@andrefimenko Жыл бұрын
Merge Sort -------------------------------- import scala.annotation.tailrec import scala.util.Random object main extends App{ def mergeSort(seq: Vector[Int]): Vector[Int] = { val seqList = seq.toList seqList match { case Nil => Nil.toVector case xs::Nil => List(xs).toVector case _ => val (left, right) = seqList splitAt(seqList.length / 2) merge(mergeSort(left.toVector), mergeSort(right.toVector)).toVector } } @tailrec def merge(seq1: Vector[Int], seq2: Vector[Int], accumulator: List[Int] = List()): List[Int] = { val (seq1List, seq2List) = (seq1.toList, seq2.toList) (seq1List, seq2List) match { case (Nil, _) => accumulator ++ seq2List case (_, Nil) => accumulator ++ seq1List case (x::xs, y::ys) => if (x < y) merge(xs.toVector, seq2, accumulator :+ x) else merge(seq1, ys.toVector, accumulator :+ y) } } // private val v = Vector.fill(1000)(Random.nextInt) private val v = Vector(1, 1, 2, 3, 6, 1, 3, 4, 2, 4) println(mergeSort(v)) }
@andrefimenko
@andrefimenko Жыл бұрын
37:06 polymorphic expression cannot be instantiated to expected type; found : [A](=> A) => List[A] required: Int => ? println(list.map(List.fill(2))) Это выдаёт IDEA. Почему у меня не работает укороченный синтаксис, а (x => List.... и т.д. норм?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Да, действительно не работает 😞. Надо будет переделать этот слайд на следующей итерации курса. Тут проблема в том что второй блок параметров это call by name параметр, с которым такой трюк не проходит. Про call by name будет рассказано на 3-й лекции.
@andrefimenko
@andrefimenko Жыл бұрын
Спасибо за ответ!, да и за лекции) Будет ли ещё возможность попасть на курс, где следить за новостями?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
@@andrefimenko Анонс будет на этом канале. Пока конкретных планов нет.
@valeriyemelyanov9090
@valeriyemelyanov9090 Жыл бұрын
На 2023 год планируете обучение? Где отслеживать, чтобы не пропустить?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Пока что планов нет. Когда будут сделаю анонс на этом канале.
@ns-bj6nj
@ns-bj6nj Жыл бұрын
@@user-io8nj2ly1m Ждем курс по Scala 3 =)
@xaircore
@xaircore Жыл бұрын
А чем call by name отличается от передачи лямбда функции в Java и вызове ее?
@user-io8nj2ly1m
@user-io8nj2ly1m Жыл бұрын
Под капотом оно так и работает. Отличие в том, что в Scala это происходит неявно, что позволяет строить довольно лаконичные API.
@romanzubriichuk8763
@romanzubriichuk8763 Жыл бұрын
Спасибо за лекции!
@helloworld5469
@helloworld5469 Жыл бұрын
Вроде как в Scala больше не поддерживается функция get у коллекций, вместо неё теперь lift, разве нет?
@andrefimenko
@andrefimenko Жыл бұрын
IDEA get не воспринимает, lift - да. Ещё заметил, что Option[Int] можно вообще не писать.
@EugeneKarasev
@EugeneKarasev 2 жыл бұрын
Не тратьте время
@user-se5jr1sx2o
@user-se5jr1sx2o 2 жыл бұрын
Отличные лекции! Все круто! Только в хвостовой рекурсии в условии n должен быть больше 1, а не 0)
@Alexander-is1eq
@Alexander-is1eq 2 жыл бұрын
Очень интересное начало, но хотелось бы поменьше видеть лектора, и побольше кода. Когда код занимает всего треть экрана приходится сильно напрягаться, чтобы разглядеть полезный контент на экране планшета, а две трети экрана занимает какой то мужик в очках, не несущий совсем никакой смысловой нагрузки. За уроки большое спасибо.
@TheJabberwahh
@TheJabberwahh 2 жыл бұрын
...ретУрн...
@user-se5jr1sx2o
@user-se5jr1sx2o 2 жыл бұрын
Круто! Спасибо за лекцию!
@olegtarasow8509
@olegtarasow8509 2 жыл бұрын
Спасибо!
@mikhaillermontov8228
@mikhaillermontov8228 2 жыл бұрын
Начал изучать скала из-за того что нужен спарк и что то простое написать могу ) но чем больше погружаюсь в сам язык тем интересней )))!!! Очень хорошая подача материала ИМХО))! Так держать 👏
@mortrap3000
@mortrap3000 Жыл бұрын
подписался на канал и стал смотреть из-за твоего коммента Р))
@user-lp9id4xq6x
@user-lp9id4xq6x 2 жыл бұрын
что то я также сделал, но ничего не происходит (:
@alfsiedner151
@alfsiedner151 2 жыл бұрын
p̾r̾o̾m̾o̾s̾m̾ 💯
@olegtarasow8509
@olegtarasow8509 2 жыл бұрын
лет 15 назад похожую прогр. для одного амер. издания (сложнее функционал, но где то рядом) писали 5 программистов пол года😁
@user-io8nj2ly1m
@user-io8nj2ly1m 2 жыл бұрын
Будем считать это примером того как Scala повышает эффективность разработки ;-)
@olegtarasow8509
@olegtarasow8509 2 жыл бұрын
Вроде все по делу, но совсем нет готовых решений для примеров
@user-io8nj2ly1m
@user-io8nj2ly1m 2 жыл бұрын
А каких примеров не хватает?
@olegtarasow8509
@olegtarasow8509 2 жыл бұрын
мне кажется еще нужна постоянная обратная связь и обмен информацией между людьми по теме. Может ТГ группа. По примерам было бы удобнее в таком формате. Only in my opinion)
@olegtarasow8509
@olegtarasow8509 2 жыл бұрын
Спасибо, интересно!
@gavsafety
@gavsafety 2 жыл бұрын
Как жаль, что я поздно увидел. Очень хочу начать изучать Scala
@user-io8nj2ly1m
@user-io8nj2ly1m 2 жыл бұрын
На семинары и проверку ДЗ попасть уже не получится, но лекции курса выкладываются на этот канал. Можно начать с них. Еще есть хорошие курсы на Coursera, но я не знаю что сейчас с их доступностью.
@DRVTiny
@DRVTiny 2 жыл бұрын
Максим, дико извиняюсь, но не тарджет, а "таагет". Послушайте, например, на translate'е, как это звучит.
@user-io8nj2ly1m
@user-io8nj2ly1m 2 жыл бұрын
Спасибо, постараюсь исправиться.
@DRVTiny
@DRVTiny 2 жыл бұрын
@Aslan Ali есть правила фонетики, и нужно их соблюдать. Акцент - вообще не про это, он о "тонкостях" в произношении, но конечно не о том, что человек вместо одного слова произносит другое (например, вовсе не существующее)
@ergo_____3491
@ergo_____3491 Жыл бұрын
Андрей Коновалов, знаешь почему у твоего коммента одинаковое количество лайков и дизлайков? Потому что дизлайки не отображаются. Общепринято и повсеместно распространено произношение иностранных слов на русский манер, когда разговор идёт на русском языке. По очевидной причине: правила произношения иностранных слов нужно соблюдать, чтобы вас понял иностранец, так как он знает именно такое звучание слова, как предусмотрено правилами иностранного языка. А когда все на русском говорят, то для всех и так понятно, что таргет/тарджет - это target, поэтому нет нужды соблюдать правила фонетики, зато намного удобнее и быстрее произносить иностранное слово на русский манер - на манер родного языка, вместо смешивания русской фонетики и фонетики иностранного языка (это даже звучать будет дико). Но тут ворвался ты и решил научить всех как правильно жить. Так обычно делают люди с комплексами неполноценности, которые при этом из себя ничего не представляют, поэтому к другим докапываются на ровном месте и необоснованно. Иди ещё юристов поучи как "форс мажор" произносить.
@ergo_____3491
@ergo_____3491 Жыл бұрын
@@user-io8nj2ly1m вы все правильно делали, не стоит обращать внимание всяких рандомных оленей.
@jollyroger2757
@jollyroger2757 2 жыл бұрын
Всегда хотел понять монады, но что-бы понять монады надо понять монады.