How to implement filterMap

Siarhei Siamashka siarhei.siamashka at gmail.com
Sun Dec 31 10:30:21 UTC 2023


On Sunday, 31 December 2023 at 09:47:27 UTC, Siarhei Siamashka 
wrote:
> On Saturday, 30 December 2023 at 13:25:00 UTC, Christian 
> Köstlin wrote:
>> The "original" 
>> https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map works with the Option(Some/None) ...
>
> Here's an example with `Nullable`, inspired by the earlier 
> comment from Alexandru Ermicioi:
>
> [...]

And for comparison, here's a Ruby/Crystal example too:

```Ruby
# Emulate the Crystal's method ".to_i?" for Ruby
class String def to_i?; self.to_i rescue nil if self =~ 
/^\s*\-?[0-9]+\s*$/ end end

a = ["1", "2", "abc", ""]
pp a.map {|s| (v = s.to_i?) ? v * 2 : nil}.compact
pp a.map {|s| s.to_i?}.compact.map {|v| v * 2}

b = ["1", "2", "abc", "", "99999999999999999999", "99"]
pp b.map {|s| (v = s.to_i?) ? v * 2 : nil}.compact
pp b.map {|s| s.to_i?}.compact.map {|v| v * 2}

c = ["1", "2", "abc", "", "1999999999", "99"]
pp c.map {|s| (v = s.to_i?) ? v * 2 : nil}.compact
pp c.map {|s| s.to_i?}.compact.map {|v| v * 2}
```

Running as a Ruby program:
```
[2, 4]
[2, 4]
[2, 4, 199999999999999999998, 198]
[2, 4, 199999999999999999998, 198]
[2, 4, 3999999998, 198]
[2, 4, 3999999998, 198]
```

Running as a Crystal program:
```
[2, 4]
[2, 4]
[2, 4, 198]
[2, 4, 198]
Unhandled exception: Arithmetic overflow (OverflowError)
```

Ruby is an interpreter with an arbitrarily large BigInt integer 
type. Crystal is a native compiler with the default 32-bit 
integer type (but it also supports 64-bit integers, 128-bit 
integers and BigInts via optional type annotations).

This particular Crystal code is badly written and stinks because 
it's silently filtering out "99999999999999999999" (similar to my 
earlier D example, which has exactly the same problem). But the 
arithmetic overflow during multiplication is at least caught at 
runtime. The code can be of course updated to allow wraparounds 
or filter out the arithmetic overflows from the resulting array 
too, but I think that this is a dubious approach in general.

By the way, under the hood Crystal is effectively using a more 
powerful generalization of D's `Nullable`: 
https://crystal-lang.org/reference/1.10/syntax_and_semantics/union_types.html


More information about the Digitalmars-d-learn mailing list