4 ms·
I always read about those nice functional languages, but when I try to learn them myself I struggle pretty hard. Can anybody point me to some small (5k LOC may
by Double_a_92 9y ago
I always read about those nice functional languages, but when I try to learn them myself I struggle pretty hard.
Can anybody point me to some small (5k LOC maybe) project on github that solves some "real world" problem?
I'd like to get some overview. As opposed to the usual tutorials that start with the very basics and don't seem to get anywhere...
- robstu 9y agoThis is exactly the reason I'm doing this :-) From my past efforts, I can offer you https://github.com/cognician/datomic-doc https://github.com/cognician/datomic-doc, which is a riff on the idea of marrying a Markdown editor to doc strings on entities in a Datomic database. It exposes a handful of Ring handlers as a library, so you can plug it into any Ring web app that uses Datomic and get a turn-key tech doc system. It's a complete Clojure/ClojureScript/Datomic application, and it's only 800 lines. I hope it helps you, and feedback is totally welcome! As for 'book learning'; Living Clojure by Carin Meier is currently in the USD 1 Humble Bundle at https://www.humblebundle.com/books/functional-programming-books https://www.humblebundle.com/books/functional-programming-bo.... It has a 13 week FP course in it. Highly recommended.
- fiddlerwoaroof 9y agoIt’s not Clojure, but the practical chapters in the book Practical Common Lisp might be a good way to get a feel for the way a Lisp works in a practical application.
- flavio81 9y ago>book Practical Common Lisp It is a wonderful book and Common Lisp is powerful to the max, but note that CL is a multi-paradigm language and examples won't necessarily be in the "functional" style. Quite the opposite, Common Lisp makes imperative programming very comfortable (and OOP as well.)
- fiddlerwoaroof 9y agoWhile Common Lisp definitely allows for imperative constructs, I’d argue that its flavor of OOP is part of the functional paradigm: i.e. generic functions aren’t part of the classes, they are protocols that can be implemented in different ways by different classes. They are closer to typeclasses than to java-style OOP
- deleted 9y ago[deleted]
- achikin 9y agoI've created this repo [1] exactly for that purpose i.e. show a solution for some clean, moderately complicated problem in Clojure. [1] https://github.com/achikin/game2048-clj https://github.com/achikin/game2048-clj
- nogridbag 9y agoWe all learn differently, but I found Brave Clojure was a quick read: https://www.braveclojure.com https://www.braveclojure.com From there I just started small by building some command line applications to solve every day needs. Many enjoy solving problems at http://www.4clojure.com http://www.4clojure.com as a method of learning. Perhaps one of the main differences for someone coming from an OO world is that in OO, to learn an SDK means learning about all the classes and the methods they expose to operate on encapsulated data. You're limited to what you can do on the data via those public methods. In a functional language, you instead learn a large amount of functions that operate on raw data directly. Then you build your app by creating functions that take an input and transforming it into a new output using these common set of functions. One of the exciting things for me is Clojure Spec. One of the recurring problems in web development in an OO app is that you have some domain class like User and you have some service function which does CRUD on that User. // Look how great our model layer is! createUser(User) Then as the app grows you have another service function which takes a Order object and 80% of the properties of User. So you may start with this: // uses 100% of order, 80% of user doSomething(Order order, User user) Then you have another service function which takes 3 object but only uses a few properties of each: // this feels like a code smell doAnotherThing(Order order, User user, SomethineElse somethingElse) If you have a large team without a strong common practice an application can quickly turn into a ball of spaghetti: // let's list out specifically what this function takes doAnotherThing2(long orderId, double orderTotal, long userId, String userName, A something1, B something2) And then you reach some maximum amount of parameters and refactor it to this: doAnotherThing3(DoAnotherThingRequest request) DoAnotherThingRequest feels right but it's redefining the types of all of the properties already defined in our domain model: class DoAnotherThingRequest { long orderId; double orderTotal; ... } And then you have another function which needs DoAnotherThingRequest and a few properties of another class: class YetAnotherThingRequest extends DoAnotherThingRequest { A something; ... } And eventually you realize this is stupid and instead you do this: // Let's just use the raw JSON! doAnotherThing4(JSON json) Clojure Spec on the other hand makes much more sense to me. You can define specs on namespaced keywords: :order/total is an integer :user/userName is a string with a maximum length of 10 And then your function can specify the shape of the data they receive: ; this requires an order total and a userName (Note: it doesn't redefine their specifications) (s/def ::do-another-thing-request (s/keys :req [:order/total :user/userName ...]))) This makes much more sense to me as a way of building large systems. And then you find out that Clojure spec can generate tests on your functions automatically based on the specifications you created and your mind is blown. :)