5 ms·
These seem extremely similar to Scala's case classes. In my experience, case classes are often the feature that sells people on moving over to Scala from Java (
by dangerlibrary 7y ago
These seem extremely similar to Scala's case classes. In my experience, case classes are often the feature that sells people on moving over to Scala from Java (the other being exhaustive pattern matching warnings from the compiler).
Fingers crossed Java never implements the `implicit` keyword...
- McDev 7y agoAnd Kotlin data classes: https://kotlinlang.org/docs/reference/data-classes.html https://kotlinlang.org/docs/reference/data-classes.html
- q3k 7y ago... all of these are likely inspired by the extremely powerful namesake of Java Records: Haskell Records [1]. [1] - http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax http://learnyouahaskell.com/making-our-own-types-and-typecla...
- taeric 7y agoI'm going on a limb and saying the namesake goes back to pascal. If not farther.
- kryptiskt 7y agoThe original COBOL had them, maybe it's not surprising, it's a pretty natural metaphor for a business language. Fortran, Lisp and Algol 60 didn't have them. So I guess we can thank the bean counters for the idea.
- tombert 7y agoGonna take an unpopular opinion here, but I completely hate Haskell records. I'm sure that there's some kind of purity to them, but the fact that a two records can't share field names ends up making them incredibly difficult to use for anything practical. Granted, using the makeFields function with Lenses allows you to kind of avoid the clashing, but that in itself feels like somewhat of a hack.
- teruakohatu 7y agoFor those of us who don't do haskell, can you give us an example of what does not work and then work around?
- dwohnitmok 7y agoFor an example of clashing: data Person = Person { id :: Int, name :: Text } data Account = Account { id :: Int, # Oh no! Name clash amount :: Int } This is because `id` isn't really a "field," among other thing it's a generated function so that id :: Amount -> Int id (Amount actualId _) = actualId This particular case is compounded by the fact that `id` is already the name of the identity function in Haskell's standard library (one reason why many projects that roll their own standard library rename `id` to `identity`). For the partiality: data AllowedItems = Person { id :: Int, name :: Text} | JustANormalInteger Int name (JustANormalInteger 5) # Blows up at runtime That is name has the type AllowedItems -> Text, even though JustANormalInteger 5 is also a member of AllowedItems The workaround for clashing is to prefix your fields with your type name (luckily Haskell still has module namespaces so you don't need a globally unique name, just one unique for your module). The workaround for partiality is to disallow a type with a record to be anything other than that record (e.g. disallow JustANormalInteger or require that Person {...} must first be an independent type before it can be used in AllowedItems). The talk of lenses is a way to generalize the notion of field accessors and talk about the "path" generated by a series of field accessors in a first class way. E.g. you might imagine that in a standard OO language myClass.field0.subField0.subSubField0 could have a stand-alone concept of `field0.subField0.subsubField0` as a path through `myClass` that you could then use either to get a value (get(field0.subField0.subSubField0, myClass)) or set a value (set(field0.subField0.subSubField0, myClass, newValue)). Moreover, if you can talk about the paths through a class in a first-class way, what's to say that this path must actually correspond to a true field in a class? It could just be anything "field-like." For example: lens = integer.lastDigit.leastSignificantBit set(345, lens, 0) // Yields 344 even though the individual digits of myInteger aren't actually generally truly fields in any OO language nor are the individual bits of a number. Because you have now removed the need for true "fields," lenses are one strategy to get around the hackiness of fields in Haskell and in fact in many ways represent an advance in expressiveness over "true" fields (although they suffer from not really being integrated into the language in the way faux-fields are currently in Haskell).
- deleted 7y ago[deleted]
- pron 7y agoKotlin's data classes are quite different from the other three (Scala's case classes, Java's records and Haskell records), and those three are inspired by ML's records, but the name "record" predates even ML.
- harryh 7y agoThe implicit keyword is extremely powerful when used appropriately and not something that should just be shunned completely. My favorite usage is probably in a typesafe Query engine that several people[1] built at Foursquare that is a lot better than what you can find in the java world. Venue.where(_.closed eqs false) .orderAsc(_.popularity) .limit(10) .modify(_.closed setTo true) .updateMulti It allows for all sorts of typesafe queries that will fail at compile time if things are malformed including stuff like failing to query on an index. https://github.com/foursquare/rogue https://github.com/foursquare/rogue 1. Hi Jorge, Liszka & Neil!
- dangerlibrary 7y agoI've never shown a use of "implicit" to an experienced developer unfamiliar with Scala and seen them get excited about the language. The best case scenario is that they aren't instantly horrified / confused / repulsed.
- harryh 7y agoThere are a lot of tools in the world that are confusing at first but are extremely powerful and useful once you understand their use. implicit is one of them
- dangerlibrary 7y agoI never said it wasn't powerful.
- fiddlerwoaroof 7y agoThe one thing that I like about Scala is Spark which is a really good example of what something like implicits can enable
- sk5t 7y agoAutomatic capture of Manifest / type parameters might be the most immediately appealing thing to a Java person learning about Scala, I dunno. Maybe don't show them implicit conversion.
- Joeri 7y agoI only see a superficial similarity. Case classes are much more powerful. Copy constructor, private constructor, pattern matching, overrideable apply/equals/hashcode. Granted, some of that stuff is esoteric, but it does make case classes a very different beast.
- halfmatthalfcat 7y agoImplicits are very powerful when used tastefully but are being replaced/deprecated in Scala 3 regardless.
- virtualwhys 7y agoActually, implicits aren't going anywhere in Scala 3. There will be new syntax, but otherwise the underlying semantics will remain the same; it's just the implicit keyword itself and the kitchen sink of functionality that it provides in Scala 2 will be split up into new (soft) keywords like "given foo(using: Bar) = ..." rather than "implicit def foo(implicit bar: Bar) = ...", along with "extension listOps of" replacing "implicit class ListOps ...". The community isn't united over the proposed changes (mostly due to migration concerns it seems), but overall it looks like a nice improvement over the status quo, particularly around typeclass definitions.
- ecoffey 7y agore: implicits... https://twitter.com/ecoffey/status/1179198362924404736?s=21 https://twitter.com/ecoffey/status/1179198362924404736?s=21
- LordHeini 7y agoI would say there are tons of other features as well. More often than not Java programming just consists of throwing gang signs on your keyboard for your Ide to create tons of boilerplate. Well case classes can implement traits, might have a companion object and can (poorly) replace enums. Scala sometimes seems to not need standard classes. Other languages like go, rust or c can do just fine without classes at all.