%w[Peter Julia Xi].map { |name| "Hello, #{name}" }.each { |greeting| puts "#{greeting}! Enjoy your Crystal" }
As they put it:>Crystal is a general-purpose, object-oriented programming language. With syntax inspired by Ruby, it's a compiled language with static type-checking.
But this time, one can probably say that Crystal will lake the benefits of ecosystem that only a large popular language enjoy.
I guess on that side F#, relying on .Net, is closer to Kotlin with Java ecosystem.
List<string> names = ["Peter", "Julia", "Xi"]; names.Select(name => $"Hello, {name}").ForEach(greeting => Console.WriteLine($"{greeting}! Enjoy your C#"))
or
new List<string> { "Peter", "Julia", "Xi" }.Select(name => $"Hello, {name}").ForEach(greeting => Console.WriteLine($"{greeting}! Enjoy your C#"))
To jump in a REPL (or any debug breakpoint observation facility), having optional type inference is a great plus to my mind.
Note that Crystal does allow to make type explicit, and keep the fluent interface on track doing so:
Array(String).new.push("Peter", "Julia", "Xi").map{|name| "Hello, #{name}"}.each{|greeting| puts "#{greeting}! Enjoy your Crystal"}
Let’s remark by the way that, like with C# lambda parameters, block parameters are not explicitly typed in that case.