proj-jasper-jasperDataThoughts

maybe in line with the 'everything is an interface' policy, when a function needs to create a new instance of a data type, it doesn't provide the implementation type; rather, the implementation type must be passed in from the outside. It can, however, make these type arguments optional keyworrd args, providing a default that the caller can choose not to override.

perhaps in line with this, top-level functions should also be required not to have implementation type constants, just like lower level ones; the type constants passed by the 'caller' are provided via some externally configured 'environment'.

---

so in general, perhaps we should supply an external configuration 'environment' and infrastructure for configuring it, similar to python's paste/WSGI

(i get the sense that the java web frameworks are the most developed along these lines, should look into what they do)

---

in languages like Haskell, an important think is to have ADTs, e.g. lists, which are discriminated unions/tagged unions (eg each instance of a List is either a Nil or a Cons), and this is exhaustive (each List is exactly one of Nil or Cons) and can be 'case'd upon (eg you can say switch l1..case Nil: ...; case Cons:... ), destructured (if a List is a Cons, you can tell what the arguments to the Cons constructor were, and get those back by binding a pattern to it eg. (l1_head, l1_tail) = Cons(l1))

Jasper should probably have these too. How to square that with Everything Is An Interface? Well, we make the ADT not actually corresponding to the data implementation, but rather only an interface itself. So, e.g. something that supports the List interface must provide __-prefixed functions like __which, which returns which List constructor a value is, and __constructorArgs, which give the constructor args that would have created this value.

Note that this requirement is itself just an interface signature, so it can fit within our usual structural typing pattern as a 'graph regex'/structural pattern.

Note also that the List interface support of some data value is per-view. There may be multiple views onto the same data value which support List, and some that don't, for example.

---

so, in order to discourage functions from discarding metadata from their inputs by using new() to create new objects (e.g. in a list filtering function, even if the algorithm is to start with an empty list and then add in those items that pass the filter, you want the hidden metadata that was attached to the input list in other views to be copied to the new, empty list), we could: not provide a direct way to construct new objects of a certain type; provide a "new" but this is really "clone", and it requires a prototype to clone. In generic (parametrically polymorphic) functions, this makes it easier to type new(x), which is the right thing, rather than new(getDefault(type(x))), which would give an empty list without metadata.

---