Ono je to skor opacne. Preco mat typovu inferenciu ked zapisat typ do zdrojaku je otazka stlacenia klavesy a IDE ju samo doplni a je potom pre kazdeho kto cita kod uplne zjavne pohladom do zdrojaku o com je rec. Ale ano, bez typu je to viac demonicke a cool. Treba patrat. A to ze 'obvykle' je to zjavne neznamena ze sa to nezneuziva aj tam kde to zjavne nie je.
určítě, komu se to chce explicitně psát, ať si to píše, to OCaml/F# umožňuje (viz ty příklady "s dvojtečkami"). V praxi ale - dělám hodně Go - vidím, že i ta triviální typová inference v Go je ve 100% používána a nikdo nepíše věci jako var x int = 42 (stejně by neprošel přes review :-) A to je inference v Go skutečně dost triviální.
Preco mat typovu inferenciu ked zapisat typ do zdrojaku je otazka stlacenia klavesy a IDE
Jenže bez typové inference nemůže IDE ten typ odvodit.
A pak je tu druhá věc, že ten typ může být delší, takže ho tam ani nechcete explicitně zapisovat. Třeba tenhle ([> `A | `B | `C | `D ] as 'a) -> 'a
nebo ?dir:[ `Down | `Nearest | `Up | `Zero ] -> float -> float
(typ funkce pro zaokrouhlování).
já to vidím tak, že někde mají explicitně zapsané typy velký smysl a měly by se používat (nebo musely). V ML jazycích při definici nových typů, v Javě u public metod (jak ve třídách tak i v rozhraní).
Ale například o stupeň níž, tedy v pomocných (privátních) funcích a metodách už je to na hraně, jestli se s tím musím crcat. A ještě o level níž, třeba u lokálních proměnných, mě explicitní zápis typů neskutečně zdržuje od vlastního řešení problému (a tady už i java nabízí var a jako obezličku i diamant - to nevzniklo jen tak, k tomu byly praktické požadavky, sám jsem se toho trošku zúčastnil).
Takže vlastně ML jazyky se od Javy liší v tom mezistupni, řekněme zjednodušeně na úrovni privátních metod a funkcí. Tady dobré type systémy (třeba ten v ML) mohou hodně pomoci.
Java má len veľmi obmedzenú inferenciu, len pri priradeniach. To ste si mohli zvoliť teda lepší jazyk.
Java, veľmi limitovaná inferencie na pravej strane priradenia.
package com.example; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { Map<String,Integer> fruits1 = new HashMap<>(); fruits1.put("oranges", 2); fruits1.put("bananas", 3); Map<String,Integer> fruits2 = new HashMap<>(); fruits2.put("plums", 6); fruits2.put("apples", 7); List<Map<String,Integer>> all = new ArrayList<>(); all.add(fruits1); all.add(fruits2); for (Map<String, Integer> mapsData : all) { mapsData.forEach((k, v) -> System.out.printf("k: %s v %d%n", k, v)); } } }
F# (Ionide vám poskytuje typy ako hinty)
let fruits1 = Map [ "oranges", 2; "bananas", 3 ] let fruits2 = Map [ "oranges", 2; "bananas", 3 ] let fruits = [ Map[1, fruits1]; Map[2, fruits2] ] fruits |> List.iter (Map.iter (fun k v -> printfn $"{k} {v}"))
Proti gustu žiaden dišputát.
Zaujimave, inferenciu vnutri pouzijete ale vo vonkajsom cykle nie, preco?
Map<String,Integer> fruits1 = Map.of("oranges", 2, "bananas", 3); Map<String, Integer> fruits2 = Map.of("plums", 6, "apples", 7); List<Map<String,Integer>> all = List.of(fruits1, fruits2); all.forEach(mapsData -> mapsData .forEach((k, v) -> System.out.printf("k: %s v %d%n", k, v)));
20. 9. 2023, 14:44 editováno autorem komentáře
Alebo uplne bez typov ale toto je presne to preco neznasam var:
var fruits1 = Map.of("oranges", 2, "bananas", 3); var fruits2 = Map.of("plums", 6, "apples", 7); var all = List.of(fruits1, fruits2); all.forEach(mapsData -> mapsData .forEach((k, v) -> System.out.printf("k: %s v %d%n", k, v)));
20. 9. 2023, 14:46 editováno autorem komentáře
Tú vonkajšiu som prehliadol. Čo sa týka Map.of
a List.of
, to je len ďalší Java bazmeg. Vytvára defaultne immutable kolekcie v jazyku, ktorý je predovšetkým mutable a nemá ekvivalent MutableList.of
.
Pre normálnu prácu s kolekciami si človek musí stiahnuť Eclipse Collections. To Javacke je neopraviteľne dodrbané.
Ináč, v F# inferencia v iterácii funguje v deklaratívnom aj v imperatívnom kóde.
let fruits1 = Map [ "oranges", 2; "bananas", 3 ] let fruits2 = Map [ "plums", 2; "kiwis", 3 ] let fruits = [ Map[1, fruits1]; Map[2, fruits2] ] fruits |> List.iter (Map.iter (fun k v -> printfn $"{k} {v}")) for nested in fruits do for e in nested do printfn $"{e.Key} {e.Value}"
20. 9. 2023, 14:57 editováno autorem komentáře
Tak celkovo nejake konstanty vnutri programu obzvlast typu Map a List su dost vzacne a neviem na co by som ich chcel este s niecim mixovat. Preto su immutable. Ak to velmi potrebujete mate napriklad:
new HashMap(Map.of("plums", 6, "apples", 7));
Ale to je pre mna cista akademicka debata, hardkodovany list v realnom kode nepouzivate. Nacitavam XML, JSON, YAML, properties, ... ale hard kodovany list?!?!
> inferencia v iterácii funguje v deklaratívnom aj v imperatívnom kóde.
Aj v Jave:
for (var nested : all) for (var e : nested.entrySet()) System.out.println(e.getKey() + " " + e.getValue());