What are some of its advatanges over JS?

  • ☆ Yσɠƚԋσʂ ☆
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    4 years ago

    I use Reitit for routing on server side, and it leverages spec to generate APIs, do validation, coercion, and even produces a Swagger test page for the API. Here’s an example of how that looks:

    ["/plus"
      {:get  {:summary    "plus with spec query parameters"
              :parameters {:query {:x int? :y int?}}
              :responses  {200 {:body {:total int?}}}
              :handler    (fn [{{{:keys [x y]} :query} :parameters}]
                            {:status 200
                             :body   {:total (+ x y)}})}}]
    

    The completion will of course be better with static typing, but you can get surprising amount with a dynamic language as well via static analysis. At the same time, completion isn’t really as much of a problem in a functional language because you’re just using the same set of common functions to transform any kind of data. With OO, each class creates its own ad hoc API in form of its methods. And this makes completion really important since knowing how one class behaves tells you nothing about the next.

    Your functional components I imagine also still need a structure to the data they’re receiving (is this a bunch of dogs, or car doors), to be able to work with it. Strict types give you compile-time errors when its the wrong function argument.

    I find that the code that cares about concrete types tends to live at the edges, while a lot of the code in the application is just routing the data where it needs to go. For example, if I pull some records from the db, the code that sends those records to the client doesn’t care about the content of the payload. It only becomes meaningful when I go to render it in the UI. Unfortunately, static typing can easily introduce unnecessary coupling where the code that shouldn’t care about the types ends up being tied to the specific types it operates on. An analogy here would be having delivery trucks that you can only put specific types of packages into. The truck shouldn’t care about the content of the package it’s delivering.

    With runtime contracts I can decide where the type checks will provide the most value and add them there. Most of the projects I end up working on the specs end up being applied around the API level, and act as a specification for what the component is doing. If the specs pass at the API level, then the code behind the API necessarily has to be doing what’s intended as well.

    And you can use spec driven development along side the REPL driven workflow as seen here, so that works quite similarly to type driven development except that you get live feedback as you’re working. The key advantage is that you can build up the state of the application as you’re working on it incrementally without having to restart it to see changes.

    I find the problem is that most people just haven’t used a decent dynamic language with good tooling around it. Pretty much everybody has experience with languages like Js or Python, and I would much rather use a statically typed language than either of those as well.

    I’d argue that the overall language design plays a far bigger role than the type discipline, and it’s misguided to treat it as the defining feature of a language. In practice, there are great languages using both static and dynamic disciplines and vice versa.