4 ms·
Scala is a fantastic language, but my heart seems to resist due to things like this (slide 27/42): implicit class RichSeq[A, C[A] <: Seq[A]](underlying: C[A]
by BonoboBoner 13y ago
Scala is a fantastic language, but my heart seems to resist due to things like this (slide 27/42):
implicit class RichSeq[A, C[A] <: Seq[A]](underlying: C[A]{
def cycle: Iterator[A] = {
lazy val circular: Stream[A] = underlying.toStream #::: circular
circular.iterator
}
}
- vladev 13y agoThis is very dense code, and takes some getting-used-to in order to read. What it achieves is beyond the reach of many languages. All it does is convert a Seq (sequence) to a lazy stream that will infinitely cycle through the values. Seq(1, 2, 3).cycle.take(8).toList res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2) It will work for any seq-like structure (including List. Vector, Queue, etc.) If you try to use it with anything else, like a Map, it won't compile. Also, note from my example that it's generic and the resulting List is of the correct type. Just like novice JavaScript developers struggle with "Why 'this' changes here?", it requires some experience with the language.
- Stranger2013 13y agoBrainfuck language is even denser.
- dons 13y ago> This is very dense code, and takes some getting-used-to in order to read. I don't think so. It is full of syntactic noise, for what is really just notation for building a cyclic structure. * type annotations stated explicitly, not inferred * type variables given multiple times * too much non-verb, non-noun syntax e.g. `#:::` * and the actual construction of the cycle is stated imperatively with great ceremony (despite it being an applicative) It is the opposite of dense.
- prollyignored 13y agoAttention to syntax is what ruby is good at. Scala, Haskell treat syntax as a chore.
- dons 13y agoYou don't know Haskell. > take 8 $ cycle [1,2,3]
- pja 13y agocycleM x = x `mplus` (cycleM x) take 8 $ cycleM [1,2,3] might be more generic?
- lucian1900 13y agoScala maybe, not Haskell (which barely has any syntax).
- eloisant 13y agoWhat makes it a bit more complex than it would be in Ruby is the typesafety (what comes after RichSeq). So it's a bit harder to write such a library, but once it's written it's a breeze to use for users because the compiler tells them right away if something is wrong with the type.
- shangaslammi 13y agoThe same thing in Haskell: cycle seq = circular where circular = seq ++ circular (or if you want to really golf it) cycle = fix . (++) Ok, to be fair the Scala code is a bit more generic as it works for any abstract sequence, but still, Scala's syntax is awfully heavy compared to Haskell. That's one reason I still prefer Haskell even though Scala is easier to sneak into enterprise projects thanks to JVM. Not to mention that Haskell gives stronger static guarantees and has a more sophisticated type inference system.
- pja 13y agooo. I'd forgotten about fix. cycleM = fix . mplus gives a nice generic version that works on Lists & Sequences but falls afoul of the monomorphism restriction, so it needs a type: cycleM :: (MonadPlus m) => m a -> m a cycleM = fix . mplus
- trailfox 13y agoThat's not the sort of thing you'll commonly see in real world Scala code. It's the sort of thing that might be used internally by a library, but not likely something you will come across day-to-day in Scala code. Every language has examples of code where the syntax is hard to follow, but you need to look at common code rather than "ooh let's try some tricks" kind of code.