Partly preamble. A week ago, I began to learn **Scala** - so how about **Nim**
(and it's disappointing) read almost nothing (in my native language -
especially). Written for **Nim** module nimfp, implements very similar
functional paradigm that is in the **Scala** - and this is well documented in
**Scala**.
Therefore, a book about **Scala**, telling about **flatMap, foldLeft, flatten,
forall** and so on is very useful.
I should add that in **Scala**, all the methods used in the code implemented
for all collections, and are also supported for strings. And it is very
convenient.
At the end of the study I did a little comparison of two languages ââin the
functional plane of working with strings.
Maybe **Nim** should develop in this direction? This is not a criticism, but
just a suggestion for the future.
```nim
import sequtils
import strutils,future
echo "test".len # "test".length
echo "hello world".capitalize # "hello world".capitalize
echo "hello world".toUpper # "hello world".toUpperCase
echo "HELLO WORLD".toLower # "HELLO WORLD".toLowerCase
echo " test".strip # " test ".trim
echo "hello world".split(" ") # "hello world".split(" ")
echo "hello world".startsWith("hel") # "hello world".startsWith("hel")
echo "hello world".endsWith("rld") # "hello world".endsWith("rld")
echo "test".replace('e','o') # "test".replace('e','o')
echo "test".replace("e","o") # "test".replace("e","o")
echo "hello world".replaceWord("hello","") # "hello
world".replaceAll("hello","") или "hello
world".replaceAllLiterally("hello","")
echo "test".count('t') # "test".count(_ == 't')
echo "*".repeat(10) # "*" * 10
echo "test".find('t') # "test".indexOf('t')
echo "test".find('t',1) # "test".indexOf('t',1)
echo "test".rfind('t') # "test".lastIndexOf('t')
echo "test".rfind('t',1) # "test".lastIndexOf('t',1)
echo "hello world".substr(0,5) # "hello world".substring(0,5)
echo "test".contains('t') # "test".contains('t') or
"test".exists(_ == 't')
echo "hello"[^1] # "hello".last == o
echo "hello"[0] # "hello".head == h
echo "hello"[0..^2] # "hello".init == hell
echo "hello"[1..^1] # "hello".tail == ello
echo "hello world"[1..3] # "hello world".slice(1,4) == ell
echo "hello"[0..2] # "hello".take(3) == hel
echo "hello"[2..^1] # "hello".drop(2) == llo
var str = "weekend"
str.removeSuffix("end");echo str # "weekend".stripSuffix("end") ==
week
str.delete(0, 1); echo str # ???
```
Some things in Scala performed functions can be simulated on Nim for loop or
list comprehensions:
```nim
for s in "test": s.echo # "test".foreach(println _) -> t
e s t
# code examples on Nim similar to expression on Scala: (1 to 10).map("*" *
_).foreach(println _)
for s in toSeq(1..10).map(x => repeat("*",x)): echo s
for s in toSeq(1..10).mapIt(repeat("*",it)): echo s
for s in {1..10}.mapIt(repeat("*",it)): echo s
for s in {1..10}: echo repeat("*",s)
for s in 1..10: "*".repeat(s).echo
echo lc[x|(x <- "abc123"), char].anyIt(it.isDigit) #
"abc123".exists(_.isDigit)
echo lc[x|(x <- "test", x == 't'), char] # "test".filter(_ ==
't') -> tt
echo lc[x|(x <- "test"), char].filter(x => x == 't') # "test".filter(_ ==
't') -> tt
echo lc[x|(x <- "tttt"), char].all(x => x == 't') # "tttttt".forall(_ ==
't') -> true
echo lc[$x.toUpper| (x <- "test"), string] #
"test".map(_.toString.toUpperCase) -> Vector(T, E, S, T)
echo lc[x.toUpper| (x <- "test"), char]
echo lc[x|(x <- "qqwweerrtyy"), char].deduplicate.join #
"qqwweerrtyy".distinct -> qwerty
```
However, Scala's a lot of things, the implementation of which is not in Nim
```nim
# "test".count(_.isLower) -> 4
# "scala".matches("s(c|k)al\\w") -> true
# "test".filter(_ == 't') -> tt
# "tttttt".forall(_ == 't') -> true
# "test".map(_.toString.toUpperCase) -> Vector(T, E, S, T)
# "test".flatMap(x=>x.toString.toUpperCase) - TEST
# "test".intersect("west") -> tes
# "abcde".diff("efghi") -> abcd
# "hello".union(" world") -> hello world
# "test".replaceFirst("t","f") -> fest
# "test".zipWithIndex -> Vector((t,0), (e,1),(s,2), (t,3))
# "hello world".reverse -> dlrow olleh
# "test".splitAt(2) -> (te,st)
# "0xffff".stripPrefix("0x") -> ffff
# "hello".takeRight(2) -> lo
# "hello".dropRight(2) -> hel
# "eeeetest".dropWhile(_ =='e') -> test
# "eeeetest".takeWhile(_ =='e') -> eeee
# "Harry".patch(1,"ung",2) -> Hungry
# "test".partition(_ == 't') -> (tt,es)
# "hello world".find(_.toInt > 110) -> Option[Char] = Some(o)
# "test".indices -> Range(0, 1, 2, 3)
# "abcd".permutations.foreach(println _) -> abcd,abdc,acbd ... dcba
# "zyxwvutsrqponmlkjihgfedcba".sortWith((x,y)=>x < y) ->
abcdefghijklmnopqrstuvwxyz
# "zyxwvutsrqponzMlkjiHgfedcba".sortWith((x,y:Char)=>x.isUpper) ->
HMzyxwvutsrqponzlkjigfedcba
# "zyxwvutsrqponmlkjihgfedcba".sortBy((x:Char) => x.toInt) ->
abcdefghijklmnopqrstuvwxyz
# "HwEoLrLldO".groupBy { _.isUpper } -> Map(false -> world, true -> HELLO)
# "test".toCharArray -> Array(t, e, s, t)
# "test".getBytes() -> Array(116, 101, 115, 116)
# "test".foldLeft(0)((x:Int,y:Char)=>x+ y.toInt) -> 448 (the same: 't'.toInt +
'e'.toInt +'s'.toInt + 't'.toInt)
# "1234567890".grouped(2).foreach(println _) -> 12 34 56 78 90
# "1234567890" sliding 2 foreach println -> 12 23 34 45 56 67 78 89 90
```
PS: Some examples, of course, artificial and have no practical significance.
They just show possible.
PSS:Sorry for my English, spoken I do not know at all, and I can only read the
technical documentation.