Are SPA's particularly well suited to statically typed languages, compared to software systems in general?

Interestingly I just found this in Scott’s preface to his book “Domain modelling made functional”:

"This book focuses on the ‘mainstream’ way of doing domain modeling, by defining data structures and the functions that act on them, but other approaches might be more applicable in some situations. I’ll mention two of them here in case you want to explore them further:

If the domain revolves around semistructured data, then the kinds of rigid models discussed in this book are not suitable and a better approach would be to use flexible structures such as maps (also known as dictionaries) to store key-value pairs. The Clojure community has many good practices here."

Even complex SPAs would likely be considered mainstream by most, including Scott.

The other thing about the philosophical approach of DDD is that it approaches software design from the business first at a very fundamental level. I just read how a dynamic language programmer appreciated just being able to dive into starting to code without needing to think about and define types at this early stage. This is definitely not a DDD approach and I think this is where the rigidity of concrete algebraic types is not a disadvantage but are an advantage. Adding the ease in which code can be safely and quickly refactored in Elm further reduces the seeming disadvantage of the rigidity of an algebraic type system.

One question is could something like a map system be used with an algebraic type system? How complementary would they be? I guess Record Aliases are a kind of map but perhaps a map based modelling system is so fundamental to the language as to be entirely different and incompatible with the idea of Maps with Types (either containing types or being contained by types). I’m wondering if Typeclasses are an attempt to solve some of the rigidity of algebraic types, albeit in a very different way.

The thing that Rich seemed to also indicate was that maps handle highly nested data quite easily.

It’s a fascinating topic.

1 Like

So we are limited to common denominator of wire protocol types. This is big limitation and can cause tight coupling between boundaries, because different context need to serialize/deserialize same types.

I beg to differ. First, I think applications are not only “mainstream” or only “semistructured”. They are both.

That’s why Clojure talks about information (open, with maps etc.) and computation primitives (closed, limited, with records and protocols).

And it is easy to get lost in the weeds with computation primitives in elm SPA. Of course, it is sensible to define props of button as few variants! But in the end, application gives value only if help to read or transform information.

So please, don’t be se dogmatic - truth lies in the middle.

First, I don’t understand why are you fixated with “algebraic type system”? I don’t think there’s a practical language that limits itself only to sums and products.

What may surprise you, I’m mostly working with static languages, just use Rich ideas. As I wrote in this topic already - extensible records are great tool to capture openness of information. I also have few macros for simple operations on extensible record types like pick, omit, exclude. The just generate anonymous record definitions. In Haskell, which still doesn’t have sufficient extensible records syntax, I used classy optics. In the end, they are like . operator in Elm, with similar type safety.

Clojure maps are not cool because they can have arbitrary, heterogenic types inside. They are cool because they understand that information is open - that sometimes you have more data but you’re not interested in it. It also get’s it’s value not from nominative information (it is a user because I said so) but from structure (is is a user because it has all fields a user should have).

Extensible records are maps with extra steps.

What is your proposal for Elm’s Extensible Records?

I don’t understand question? What proposal? Extensible records are complete and working fine …

Can Extensible Records be used to implement Rich’s ideas on maps? Elm isn’t going to move away from its current algebraic type system so I’m curious about your ideas to implement Hinkey maps in Elm.

I see here few misunderstandings.

  1. Extensible records can be used to model open information, just fine like maps in clojure.
  2. Elm doesn’t have “algebraic type system”. ADTs are just one of many features of its type system. Nobody want to remove this feature.
  3. Maps in clojure is just one part. Idioms are second and only then at third place is clojure.spec.
  4. I don’t think that clojure model is strictly superior. I think it is also important to push for ability to encode more information in types, like for example GADTs.
  5. If I could add one feature in spirit of clojure I would add (extensible) record combinators to mirror clojure.spec selections. Type level functions that can manipulate records as sets of fields. Like typescript Pick and Omit.

I’m getting the impression that we’re spinning in circles.

@solificati, I’m fascinated by your perspective, but have some trouble putting the different pieces together. Does the following make any sense?

  • You acknowledge the problems static types have with modeling ‘open’ information
  • Due to their relative ‘closed’ nature, SPA’s don’t have to deal as much with open information, but are not immune to it.
  • When open information does leak in, Elm can save its grace by using extensible records, although this involves some extra hassle like code generation for record functions like pick and omit.
  • This best-of-both-worlds approach is not limited to Elm and SPA’s. You also apply it in Haskell using an alternative for extensible records.
  • Rather than going full dynamic with Clojure + spec, you prefer to keep the benefits of static typing. They outweigh the extra hassle when dealing with open information.
1 Like

Your answer clarified a few things for me so it doesn’t seem like we’re going in circles.

This. The following points seem to indicate a desire to seek clarification of @solificati 's position and, in particular, whether his thoughts and perspective can help the Elm community achieve the utilisation of ‘maps’ in a way that fits well with Elm.

I was just watching this talk by Rich Hinkey about how Clojure came to be. It is interesting that he was highly motivated to significantly improve the expression of the semantics of domain modelling in software development.

He also wanted easy composition of semantically named values.

One particular problem he identified in Haskell’s Type system appeared to be the widespread use of primitive types and poorly named type models.

And he pointed out the unreasonable proliferation of Classes in Java/C++.

Just about all of the major problems he identified in Haskell and in Java/C++ appear to be less of a problem for developers in Elm due to :

  • strong cultural bias and motivation to implement semantic type design and domain modelling
  • language provides best-in-class semantic type design, composition and refactoring thanks to language size, clarity and exceptional compiler feedback
  • streamlined user-friendly development environment for beginners and experienced developers
  • highly optimised for web app development, especially SPAs, and increasingly providing benefits from web friendly MPA, PWAs, and the JAMStack.

Perhaps the area still in early stages is the establishment of new patterns that improve type and data composition.

During the talk, Rich discovered that most of the audience were highly experienced programmers who, like himself, were looking for solutions to problems they had struggled with for most of their professional lives. I think these people have a high level of skill in many areas of software development. The absence of beginners was notable.

I think Elm has such a narrow target - frontend modern web app development - that it’s entire environment is optimised in the way that suits frontend.

But in this thread you’ve presented a really interesting perspective and I think many might be very interested to understand how to introduce more maps into their solutions.

Is there a combination of Phantom Types, Extensible Records, Record Aliases, etc, that can provide additional map capabilities in Elm?

1 Like

Huh, at the start I wanted just to point out that divide is not on static-dynamic language. But of course got lost in the weeds :slight_smile:

You got all right. I’ll just clarify minor points.

Yes, but that’s a result that a lot of complexity in SPA is around technical stuff - event handlers, rendering functions, routing etc.

Purescript also have nice records. Typescript is cantered around structural typing so it also fits well. Reason is lacking in this area but still have few tricks that make task easier.

This is also a very complicated question - which tool would work best. I don’t have good answer. I still use clojure sometime and I’m satisfied :slight_smile:

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.