As a heads-up, ...

I've decided to make a couple of related large refactorings to Muldis D for the next release or two of the spec.

Feedback on this plan is welcome, but not required.

1. Currently, any built-in function which could conceivably be N-adic is N-adic, and that is the only version. There are several dozen of these, including [+, *, ~, and, or, join, union, intersect, min, max] etc.

The planned change is that, for any N-adic functions whose definition is the repetition of a dyadic operation (such as everything in the above list), the N-adic function would be replaced with a dyadic version, and users wanting to use N-adic syntax must then use a generic reduction function, giving the dyadic function as a closure argument to it.

Said generic reduction function already exists, to support user-defined N-adic functions, but now it will be used for all the relevant built-ins as well.

The primary reason for this change is to let user code be simpler, because for the majority of the times when they just want to have 2 arguments for a function, they can supply them directly rather than having to construct a set/array/bag/etc containing them, as N-adic versions require.

Moreover, users won't have to remember which functions need to be called with a collection argument just because they could possibly be used with more than 2 arguments; so the function-call syntax for addition and subtraction will now be the same, rather than different.

A related change is that the syntax for defining functions, and the system catalog structures they parse into, will be enhanced so that one can now explicitly declare traits of the functions. For example, whether dyadic functions are self-commutative or associative or idempotent or symmetric etc. An additional trait would declare the identity value of the function where applicable. Other traits might be possible.

Advantages of this change is that implementations, or user code, can discover and utilize, such as for optimization, automatically how to treat the functions such as in a generic reduction, to produce the correct results efficiently.

I have no plans currently for letting the syntax/catalog declare the interaction of different functions, such as when foo() commutes over bar(), simply because this may be complicated. But implementations can of course have hard-wired knowledge for say commuting restrictions/filters relative to joins.

2. Another major planned change is the creation and exploitation of some meta-operators, in the same sense as Perl 6 has them. See http://perlcabal.org/syn/S03.html#Meta_operators for reference.

I can think immediately of 3 meta-operators that I would use, and possibly a 
4th.

The first one is logical-not.

Any Bool-resulting op "foo" can have "!" prepended to the operator itself to reverse the result. For example, rather than having to write "!(x foo y)" or "not x foo y", they can write "x !foo y" or maybe "x not-foo y". Both of these would parse into the same thing as if you had written them in generic functional form, as "not(foo(x,y))". But for the sole purpose of preserving the user's lexical intent, I may make an alias function for "not" which the parser uses when parsing "x !foo y" versus "!(x foo y)", so that a code generator later can make code closer to what the user wrote.

Currently, every system-defined Bool-resulting function "foo" has an associated function "not_foo" which takes the same arguments but returns the opposite result. This was a historical decision based on several reasons including the desire to better preserve the user's chosen syntax. All current "!foo" syntax is system-defined and not extensible, mapping to the "not_foo" function.

A large part of the change would involve eliminating all the system-defined "not_foo" functions so that users must write "not(foo())" instead fundamentally, though the new meta-operator would mean that most common code, using "x != y" say, would not change, and hence this is a quasi-internal change.

I fully expect now that any decent implementation can easily optimize away any changes brought on by the conceptually larger call stack that the use of meta-operators would have, such as by compiling into implementation-native combined operations.

The second one is assignment.

Any function "foo" can effectively become an updater by prefixing ":=". For example, any "x := x foo y" can be written as "x :=foo y", and both would parse into the same thing as "assign(&x,foo(x,y))" would either way. But once again, I may add an alias for "assign" to use by the parser to preserve the user's actual syntax.

Currently, Muldis D has a couple dozen updaters named "assign_foo" that are typically the same as functions "foo" (except when "foo" is N-adic) but for assigning rather than returning the result, as in the previous example. And you can only use ":=foo" syntax for a subset of these updaters, not anything else.

A large part of the change would be in eliminating all of these updaters, and the meta-ing of :=foo means that you can use it with any function having the function infix/etc syntax.

The third one is reduction, related to change #1.

I'm not sure yet what syntax this would take, but Perl 6's version puts square brackets around the other operator being meta'd, eg letting one say "[+] (1,2,3)" rather than "1 + 2 + 3".

Another candidate for adoption is http://perlcabal.org/syn/S03.html#Hyper_operators but that I see the usefulness of this as being more limited as the generic relational "map" or "extend" etc provides the same hyper-meta functionality. But this alternate hyper-operator type syntax may be useful for sets/arrays/bags, if not relations in general.

See http://github.com/muldis/Muldis-D/commit/460f936 for my ramblings on these plans as TODO file items; some of this I've reworded in this email.

Feedback on this plan is welcome, but not required.

Thank you. -- Darren Duncan

_______________________________________________
muldis-db-users mailing list
muldis-db-users@mm.darrenduncan.net
http://mm.darrenduncan.net/mailman/listinfo/muldis-db-users

Reply via email to