5 ms·
Lack of types. I don't want to start a discussion here on typed vs untyped so please consider everything I say to be qualified "It is only my personal opinion
by GreaterFool 12y ago
Lack of types.
I don't want to start a discussion here on typed vs untyped so please consider everything I say to be qualified "It is only my personal opinion and experience".
I'm writing Haskell in my day job, Clojure for fun side project, OCaml because it's a nice language that's a bit underused and C++ because it's useful to know and not so evil as most people say (and it's progressing fast!). I should throw Rust into the mix because it might have a bright future.
WARNING: personal opinions and anecdotal evidence ahead!
Maybe there's a level of lisp enlightenment that I haven't reached yet but I can't just get by with writing lisp without writing tests. On the other hand I can get by with writing Haskell and OCaml without writing tests.
This is particularly true when I'm coming back to a project that I haven't touched for a few weeks. I change something and something breaks. In Haskell and OCaml I change something and compiler complains.
Maybe we'll see HaLispML one day.
- swah 12y agoAt some point, I thought OCaml would be the NBL since the writing part was fun and easy due to type inference (mostly, I hate using +.) and the refactoring felt safe. BUT those guys are much smarter than us... so creating a language that combines the qualities of dynamic and static languages is probably a hard problem.
- bmh100 12y agoHave you tried typed Clojure [1]? It seems promising for bringing in types. [1]: https://github.com/clojure/core.typed/ https://github.com/clojure/core.typed/
- GreaterFool 12y agoI tried core.typed and I think it's pretty cool. However, if you're using external libraries in your typed code you'll need annotations for those libraries too.
- jacobm 12y agoThe types objection may apply to Clojure (I've never used it, I don't know) but one of Racket's major development thrusts has been providing a way to get the benefits of both typed and untyped languages. * Racket has a sophisticated contract system that allows you to enforce "type-like" properties at runtime very easily (e.g., you can say "This function should behave as an ((int -> int) -> int) function" and it will do all the necessary runtime checks to make sure that contract is honored as your program executes) * It also has an optional modern type system, Typed Racket, that you can opt into on a per-module basis. Typed Racket modules can interact with untyped modules safely via contracts. The Typed Racket type system was designed specifically so that it's easy to migrate untyped, idiomatic Racket code to the type system, so you can write untyped Racket code idiomatically, and then go back and port your untyped module to Typed Racket with a minimum of fuss and get the benefit of the type system.
- steveklabnik 12y agoClojure has Core.Typed, which lets you add optional typing.
- ufo 12y agoCore.Typed is directly inspired by typed racket :)
- kyllo 12y agoDoes Typed Racket give you a way to run your whole program through a typechecker without executing the code? Because catching type errors at compile time is a major benefit you get from a static type checker, that you wouldn't get from just runtime type checking.
- samth 12y agoTyped Racket operates on a per-module basis -- only some of your program has to be typed. But it's entirely static -- errors are caught at compile time.
- bad_user 12y agoI'm a Scala developer and I use its type system to approximately its full potential and I prefer it to other languages precisely because of its static-ness. With a powerful type system you effectively eliminate certain problems from happening, like I once had a bug that I couldn't understand, yet I eliminated the possibility of it happening. And I prefer it precisely because I'm not smart enough for the problems I'm working on, so I prefer having a static type-system holding my hand. That said ... > On the other hand I can get by with writing Haskell and OCaml without writing tests Tests and static type-safety serve different purposes. If you end up writing tests for properties that should have been inferred by a static compiler, then you're using the language in a wrong way or you've picked the wrong language for the problem at hand. When working with a dynamic language, I don't need to write tests just to see that my code works. It's because I work with a REPL and in terms of happy paths, that's just as effective as having a static type system. And surely having a compiler is very cool when refactoring, however we tend to miss the fact that (a) the kind of refactorings we are doing are very superficial and for architectural / design refactorings the compiler doesn't save you and (b) in a dynamic language there is less need for refactoring, because you don't end up modelling the whole world through types. > I don't want to start a discussion here on typed vs untyped I'm also thinking you're making a confusion. Dynamic languages can be strongly typed. A language Clojure is very much typed. The difference is in the moment those types are used, at compile time or at runtime. This is important, because a dynamic language like Clojure can do optional typing when you want it. Of course, something like core.typed will never be as expressive and potent as Haskell's type-system, however this leads to gradual evolution - at first you don't have a well defined shape for the data you're working with, so you can enjoy the relaxed rules and protocols of Clojure and afterwards you can start introducing type definitions with core.typed or with prismatic/schema. As I said, I'm a developer that leans on the static side of the argument, however this debate will never be settled simply because which tool is the best depends on the problems you're trying to solve, therefore people will never agree on anything, because people are always thinking from their "personal experience".
- mordocai 12y ago> On the other hand I can get by with writing Haskell and OCaml without writing tests. Well, I never want to have to maintain one of your Haskell or OCaml projects. If you think you can get by with any language without tests you are wrong. That being said, yes it is easier to deal with lack of tests in a staticly typed/compiled language than in a dynamic language like clojure/ruby/python/perl/etc. The main point I'd like to make to you is you aren't complaining about Clojure per say, you are complaining about dynamic languages in general. It just so happens clojure is the one you are picking on. Either way, you might like Shen (http://www.shenlanguage.org/ http://www.shenlanguage.org/) though it is very much academic and has few tools around it, it is very much a HaLisp, though i'm not sure about the ML part.
- agentultra 12y agoAs others have noted and in my own limited experience picking up OCaml -- a static type system does not solve the problem you need unit tests and functional tests for. They're good for readability if you explicitly annotate everything (and forgo the type inference) and they're good for flushing out a whole class of run-time type errors. But that's about all. At this point in my learning it's more about pleasing a SAT solver than getting anything useful done... but I'm sure that will change with time. Common Lisp does have a type system... it's just dynamic so you can hit things at run-time. This is great in development because it allows you to under-specify things that aren't terribly important (like types) at that time. However when you begin to find your code is ready to be locked in place you can annotate your function to hint to the implementation what the types should be. In particularly well-tested and heavily-typed code you can even turn off dynamic type-checking entirely for your production builds and get the performance boost from that. Regardless of your approach and requirements, tests have a completely different use beyond ensuring type consistency. They set expectations, inform API design, and catch mistakes in refactoring; they act as a specification for the module under test. I've had plenty of OCaml code compile that still failed tests. Even in the presence of strong static typing you need unit, integration, and regression tests. Just food for thought.