xnd-project/libxnd

Use of "case statements"

teoliphant opened this issue · 6 comments

I've noticed several "case statements" used to manage code paths in libxnd.c This was a major problem for extending the type system in NumPy.

What other ways can be used to focus dispatch so that new types can be added easily?

skrah commented

There are two extension mechanisms: the Constr(name, type) type and the Nominal(name) type.

The gufuncs should match Nominal by name only and Constr by name and type.

Adding a constructor type is done by just writing e.g. MyStruct({a: float64, b: float64}).

The Constr mechanism allows creating new tags which are strings instead of the hard coded enums like Int64. You can see how the case statements work for constructors here:

https://github.com/plures/libndtypes/blob/master/match.c#L307

If there is any other use case of extending not covered by this, I would probably need a concrete example.

The Constr mechanism is roughly how other languages with heavy use of switch statements (OCaml) extend data types.

What about parameterized types, abstract types, traits or constrained type variables?

skrah commented

Parameterized types

I'm not sure where to use parameterized types in a data description language. Could you give a concrete example? Parameterized types aren't constrained by switch statements (which this issue is about) but by aesthetics. One major use case for Datashape is writing concise function types in string form.

At the very least you'd need to define the parameterized type somewhere:

type mystruct<T> = {a: T, b : T};

But we aren't writing a compiled language, so you'd have to write the uglier:

ndt_typedef("mystruct<T>",  "{a: T, b : T}"};

This is a lot of overhead for the ability to write mystruct<complex64> instead of {a: complex64, b: complex64}.

Abstract types

We have one "abstract" type called Nominal. It is more like an opaque type in C.

Traits

We are not implementing an OO language or a type system (and neither are some other projects who use that term). Semantically, Datashape maps directly to a single extensible tagged union in ML. Even the pattern matching is basically the same as in ML.

Could you give a concrete example how traits fit in or what you want to achieve?

Match constraints

We have discussed them internally recently and we also think we need them. However, they are orthogonal to switch statements.

skrah commented

That said, depending on people's use cases, it might be an idea to add the capability of reading larger schema definitions and typedefs from a file.

Ok, I think I understand. More broadly, gufuncs are meant to dispatch on concrete data patterns, not kinds or behavior, which is left to host language.

Or maybe I'm conflating the api with internal code.

skrah commented

Closing, switch statements are orthogonal to the dispatch in libgumath.