3 ms·
Not really. Let’s first consider how this code would be translated to ocaml. One would expect to use variants instead of strings, so e.g. gender should be:
by dan-robertson 7y ago
Not really.
Let’s first consider how this code would be translated to ocaml. One would expect to use variants instead of strings, so e.g. gender should be:
type t = | Masculine | Feminine | Mixed
And then one can match on them and match on tuples and so on. But what about countries? In this case you could write out all the cases separately (difficult to maintain), or you could use polymorphic variants to achieve the @foo.any behaviour:
type vosotros = [ `Spain | ... ]
type dialect = [ vosotros | ... ]
And then do e.g.
match dialect with
| #vosotros -> ...
But this has the disadvantages that polymorphic variants usually bring (difficulties with type inference/exhaustiveness checks). So instead one would probably have some function to decide if a dialect Is vosotros, and then match on the result of that, a slightly annoying to read boolean.
And one would also need to match on the (perhaps) nonsense case of singular mixed-gender. One can get around this with types in one of two annoying ways. Either combine gender and number:
type gender = Masculine | Feminine
type genders = Masculine | Mixed | Feminine
type number = | Singular of gender | Plural of genders
Which is not great because it is now hard to extract the gender if that is all one wants (but it is perhaps not grammatically useful); or one can use GADTs:
type singular = [ `singular ]
type plural = [ `plural ]
type 'number gender =
| Masculine : 'a gender
| Feminine : 'a gender
| Mixed : plural gender
type 'number number =
| Singular : singular number
| Plural : plural number
type t =
T : { number : 'num number; gender : 'num gender } -> t
But this is also unpleasant.
And how does one do other smart-match predicates? For example * > 0. This could either be:
match number, ... with
| num, ... when num > 1 -> ...
Which separates the important part (num > 1) from the unimportant part (giving it the name when you don’t care), and you still need a catch all because of the exhaustiveness checks. So maybe instead you would have a helper function to change the number into a variant like One | Zero | Many.
This also ignores the case when one might want to write some more traditional style Perl and put regular expressions as the predicates of those when blocks. This isn’t really an ocaml/SML thing to do but that doesn’t mean it should be disregarded as something bad/useless.
- a-nikolaev 7y agoAre you arguing about data representation in Perl vs OCaml? Of course there will be differences in data representation, and that would make your pattern matching also look slightly different. However, the examples in the article do fit very well familiar ML-style (SML, OCaml, Haskell, Rust, etc.) pattern matching.
- oisdk 7y agoOther than the ability to put a predicate in the pattern position (which you can do in several languages, including Haskell with ViewPatterns), I still don't see what Perl 6 adds here? Of course it's more difficult to model the problem using sum types, but there's an asymmetry here: whereas given can't do powerful pattern-matching features like exhaustiveness checking, GADTs, auto case-split in an IDE, efficient case trees, etc., the opposite isn't true. Haskell can do everything Perl does here, just by using strings! The other features (multiple variables to split on) are pretty standard these days. vosotros = ["Spain", "EquitorialGuinea", "WesternSahara"] message = case (number, gender, formality, country) of (1 , "masculine" , "informal", _ ) -> "¿Cómo estás mi amigo?" (1 , "masculine" , "formal" , _ ) -> "¿Cómo está el señor?" (1 , "feminine" , "informal", _ ) -> "¿Cómo estás mi amiga?" (1 , "feminine" , "formal" , _ ) -> "¿Cómo está la señora?" ((> 1) -> T, (`elem` ["mixed","masculine"]) -> T, "informal", (`elem` vosotros) -> T) -> "¿Cómo estáis mis amigos?" ((> 1) -> T, "feminine" , "informal", (`elem` vosotros) -> T) -> "¿Cómo estáis mis amigas?" ((> 1) -> T, _ , _ , _ ) -> "¿Cómo están ustedes?"
- jonathanyc 7y agoIf you want to pattern match on strings as in the Perl code the OCaml code is almost exactly the same. Now try to recreate the types you just constructed in OCaml and get static checking. That’s just not possible. You’re comparing apples and screwdrivers.