[nim-dev] Nim vs Scala (not holywar). Compare functions for strings

  • From: "Garry_Galler" <dmarc-noreply-outsider@xxxxxxxxxxxxx> (Redacted sender "ggaller" for DMARC)
  • To: nim-dev@xxxxxxxxxxxxx
  • Date: Sat, 16 Jul 2016 12:30:28 +0000

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.


Other related posts: