7 ms·
"The default way a Java/C# dev would probably approach this is to create a class" No, not for a long time. The idiomatic C# way would be to use LINQ which actu
by yyyk 6y ago
"The default way a Java/C# dev would probably approach this is to create a class"
No, not for a long time. The idiomatic C# way would be to use LINQ which actually predates Clojure a tiny bit. Java (since version 8 in 2014) could use Streams to similar effects. Either way the solution would be as short as your example.
- adamkl 6y agoAssuming that you are mapping the results to a Dictionary, sure it would be similar. My point was more that C#/Java developers (myself included at one point in time) would typically reach for classes to store the results, rather than just a Dictionary<String, String>. It’s not that other languages can’t to this, it just that this approach doesn’t always jive with their conventions like it does with Clojure.
- Jare 6y agoI can't help but feel that all arguments defending how this Clojure solution supposedly can't be done as elegantly in other languages, use "idiomatic Clojure" as the judging criteria. Of course the conclusion writes itself.
- adamkl 6y agoWell, you can write code a lot like this in JavaScript using a library like Ramda, and get a lot of the benefits. But then everyone that you on-board to that project has to be up to speed with how the code is being written and why. With Clojure, that understanding is table-stakes. So in that respect, the conclusion does write itself.
- onetom 6y agoI've actually tried that: https://github.com/enumatech/sprites/blob/master/lib/__tests__/sprites-tests.js#L77-L82 https://github.com/enumatech/sprites/blob/master/lib/__tests... reads quite like Clojure, but looks foreign to JavaScript programmers... I even made extensions to Ramda, so you can thread a mixture of async and non-async code with it: https://github.com/enumatech/sprites/blob/master/lib/fp.js#L51-L54 https://github.com/enumatech/sprites/blob/master/lib/fp.js#L... At the end the friction was just annoying and no one else really understood the greatness of this approach, since they didn't know Clojure...
- didibus 6y agoIn my experience, it's not that you can't do these things in some other languages, it's that you won't, and if you try too, there will be more ceremony and friction. That said, this is where a lot of people who took a detour through Clojure, come out of it saying when they went back to their prior language or some other language, they felt like they had suddenly become better programmers, and it helped them even in other languages to write better programs. Clojure showed them the way, and now they can recognize it and think of doing it as such in other languages as well. Maybe a different way to think of it is that you can do OOP in Clojure if you really want, but you won't. Similarly, in Java, you could try and do FP with immutable collections and value semantics, but most likely you're not going too. And I'm using Java here because in theory, Java and Clojure have the exact same set of available features, they run on the same JVM, same runtime, compile to the same bytecode, can share libraries, etc. So it goes to show that the language itself does influence the style that is most convenient for writing your programs in.
- jmchuster 6y agoRight, the more idiomatic approach in java would be - define the class - let the framework fully handle serializing/deserializing it from your file to the neat in-memory object
- adamkl 6y agoThat’s great if your dealing exclusively with CSV files and a fixed set of data types, but the point is that this approach in Clojure is universal regardless of where the data is coming from, or going to. Everything comes in as a map, gets manipulated with the powerful set of core Clojure core functions, and spit back out as a different shaped map. It’s a very flexible approach to dealing with data, and that is one of the main appeals of Clojure.
- deleted 6y ago[deleted]
- jmchuster 6y agoYup, Java in its current incarnation is definitely a better fit for larger companies that can present more standardized workloads. You want to give each team clean and explicit interfaces that they have to work with, and not have to worry about different shaped maps. Flexibility and power just lets junior developers shoot themselves in the foot.
- adamkl 6y agoI agree, I wouldn’t suggest Clojure for a large company with lots of junior developers. I wouldn’t suggest Java either, though. Go would be a better fit for that situation these days. I look at Clojure and Go as different sides of a coin. One is a powerful language the let’s a small team of experienced developers get a lot done with a small amount of code. The other is a simple language that lets a lot of less experienced developers get a lot done with a lot of code. I want to stress in this comparison though, that I don’t view one as better than the other. Go was designed for development at scale, where you have lots of developers, all at different levels, all needing to contribute large amounts of code. In this respect, it does a great job at removing most of the rope that people can use to hang themselves. If I needed to pick one language to use at a large enterprise, it would probably be Go. Clojure gives you a (different) set of limited functionality, but what it gives you is very powerful, and very foreign to most developers, so you can definitely hang yourself trying to force everyone into using it. If I got to choose one language for myself to use, it would be Clojure.
- sharms 6y agoI am familiar with C#, and in good faith spent a bit of time trying to find examples to support this, but in the end using a class is both common and typical (omitting the many StackOverflow results with the same pattern): https://dotnetcoretutorials.com/2018/08/04/csv-parsing-in-net-core/ https://dotnetcoretutorials.com/2018/08/04/csv-parsing-in-ne...
- yyyk 6y agoHis example is just something like .ToDictionary(column => column.First(), column => column.Skip(1).ToList())* . The motivation to eventually use a Class would be to make use of static typing, e.g. when using an ORM like Entity Framework (a common usecase: reading a CSV file into a relational database). Static typing is usually considered a strength these days, but it does have its downsides (that debate has been done to death). Showing the parallel Clojure code for that could be very interesting. However, reading CSVs doesn't require enforcing types, even if one wishes to use a library to deal with the complex quoting cases. CsvHelper is tilted in that direction of mapping to a static type, but it's not the only Csv reading library (I'm a pretty happy user of ExcelDataReader[0] for other reasons, and it doesn't enforce mapping. I'm sure there are more functional-style solutions out there). The original post picked the one place C# uses a powerful functional-like syntax, its generalized query language.... * From my limited understanding, not being a user of Clojure yet (I've been considering learning it for some time, just need to find time to do it seriously), each 'sequence' in the original example is a column, not a row. Were each sequence a row, in C# we could have used the positional lambda argument to get the columns. [0] https://github.com/ExcelDataReader/ExcelDataReader https://github.com/ExcelDataReader/ExcelDataReader