5 ms·
Which language?
by marvel_boy 9y ago
Which language?
- tomerbd 9y agomostly javascript, but I had a very similar experience in ruby and python. The main challenge was maintaining projects developed by other people.
- yogthos 9y agoI worked exclusively with statically typed languages for about a decade before moving to Clojure. I've been using it for about 7 years now professionally, and haven't found dynamic typing to be a problem. If it was I would've gone back to using a static language a long time ago. I think dynamic typing is a lot more problematic in imperative/OO languages. One problem is that the data is mutable, and you pass things around by reference. Even if you knew the shape of the data originally, there's no way to tell whether it's been changed elsewhere via side effects. The other problem is that OO encourages proliferation of types in your code. Keeping track of that quickly gets out of hand. Clojure embraces immutability, and any changes to the data happen explicitly in a known context. This makes it much easier to know exactly what the shape of the data is at any one place in your application. Meanwhile, all the data is structured using a set of common data structures. Any iterator function such as `map`, `filter`, or `reduce` can iterate any data structure, and it's completely agnostic regarding the concrete types. The code that cares about the types is passed in as a parameter. Pretty much any data transformations in Clojure are accomplished by chaining functions from the standard library together, with domain specific code bubbling up to a shallow layer at the top. There's also the culture of using Spec and Schema in Clojure, so you often have assertions at the interface level. For example, there's ring-spec https://github.com/ring-clojure/ring-spec/blob/master/src/ring/core/spec.clj https://github.com/ring-clojure/ring-spec/blob/master/src/ri... providing the specification for Ring.
- tomerbd 9y agoHi, I went on and searched for a random clojure project in github, and have chosen some function which is of a small size: (defn parse-seq [parse-el form] (when (sequential? form) (reduce #(if-let [parsed (parse-el %2)] (conj %1 parsed) (reduced nil)) [] form))) without knowing really clojure i take it "[parse-el form]" are the arguments of this function. How is it possible with minimal effort to know what am I supposed to pass as parse-el and form? what are they? https://github.com/tonsky/datascript/blob/master/src/datascript/parser.cljc#L47 https://github.com/tonsky/datascript/blob/master/src/datascr...
- augustl 9y agoThis is a very interesting question. To me, understanding in isolation some random function deep down in the code somewhere is not really something I do. Maybe that's why I prefer dynamic languages. And other people like to be able to do that, and therefore prefers static languages.
- sgrove 9y agoThis has definitely been a challenge for me in Clojure when trying to use a library that isn't well-documented. Using the REPL helps because I can throw random things at it quickly, but it's still very frustrating. An interesting corollary to this problem though is the wandering type-path, where when consuming (again, poorly documented) a Java library, I know the type of the function I want to call, but not how to get that type. Usually it's: "I have B value [byte-array, int, whatever] and I need Z from this library so I can call `Z.foo`... Z's constructor takes Y, which takes X, which takes..." Types help there, but they also hinder quite a bit if I have the correct underlying data type, but can't get Java to accept it.
- ajss 9y agoLook at the function doc string. Look at the function spec/fdef Look at the function comments. OK, there aren't any. Pull requests accepted?
- junke 9y agoLet's try to look at it in isolation. "parse-el" is used as a function, which takes one argument, the first argument when invoked from reduce (the accumulator), which is first [] then another vector (because of conj). So "parse-seq" parses a sequence (named "form") and produces a vector, or nil. It applies "parse-el" to each form using reduce. When the result of any form gives a nil value, the whole result is also nil (see https://clojuredocs.org/clojure.core/reduced https://clojuredocs.org/clojure.core/reduced). The result is also nil if form is not sequential. There is no other contract about "parse-el", it just should be able to "parse" whatever occurs in "form". You could use it on your own with any kind of data that has a corresponding parse function. A documentation string would have been nice, or different names ("parse-el"?) Now, if you look at the usage of "parse-seq", you can see for example: (let [vars* (parse-seq parse-variable vars) .... And it looks like "parse-variable" parses a form and returns an instance of Variable. (defn parse-variable [form] (when (and (symbol? form) (= (first (name form)) \?)) (Variable. form)))
- flavio81 9y ago>mostly javascript Well, javascript does not have some of the features that other dynamic programming languages have, that help you manage complexity and create successful projects of large size.
- always_good 9y agoLike what?
- flavio81 9y agoStrong typing, powerful package and namespacing facilities, a good object oriented system (if you want to do OOP, that is), interactive development with a REPL that can tell you easily which function calls which others, etc.
- always_good 9y agoWhat's wrong with Javascript's module and OOP systems?
- fasquoika 9y agoAFAIK JS doesn't really have modules, just ad-hoc use of functions and objects for namespacing