agentm / project-m36

Project: M36 Relational Algebra Engine
The Unlicense
876 stars 47 forks source link

views in with macro cannot be used by other views #279

Closed YuMingLiao closed 3 years ago

YuMingLiao commented 3 years ago

TutorialD (master/main): :showexpr with(a as true, b as a) b ERR: RelVarNotDefinedError "a"

agentm commented 3 years ago

In the current implementation, the with clause relations are macros which can only be used in the contained expression. I thought that your use-case could be fixed by nesting the with clause like this:

TutorialD (master/main): :showexpr with(a as true) (with (b as a) b)
ERR: RelVarNotDefinedError "a"

but that returns the same error. Hm... I will have to look into that more closely.

agentm commented 3 years ago

Nested with clause expression are now handled properly. I forgot to apply the expression macro substitution recursively. This is now fixed.

I still need to consider how with clause expressions might reference each other in the same with expr. I'm inclined to treat them as a set of macros rather than a list of expressions though this is different how SQL's CTE's work. The reason is that the order of macros really should not matter, making each expression and independent macro. What do you think?

YuMingLiao commented 3 years ago

Thanks for the fix! I never thought with macro can be used in a nested way. I think it's intuitive enough. Though every time I use with macros, I wish I can write it first like defining haskell functions, instead of inventing it every time.

What's the difference between a set of macros and a list of expressions?

In my mind, with here is like let or where in haskell, the order does not matter, but inevitably they will reference each other to form more complex expression if we want more expressitivity.

I wish these "shorthands" will eventually work like Haskell functions, then expressions can be more readable and concise. Then we can have an imperative way to write expressions like Haskell monads. It will make code more readable.

YuMingLiao commented 3 years ago

I guess there is a concern about where those views should be stored. Should it be with a schema? with a relation? with an expression?

If there is no argument, then it should be with an expression. If it has relation argument and can be reused for other expressions, ... maybe it should be stored where atom functions is stored, like a handy toolbox?

agentm commented 3 years ago

Indeed. After implementing this, I've been thinking similar thoughts, but:

I think you're right, though, that it would be a mistake to have an implied order to the with expressions, which is what I originally thought you were requesting. I'm uncertain of whether the Haskell "call-by-need" model fits here, so I'll be playing with various examples to see what makes sense. I can't think of a counter-example which would preclude allowing expressions within with to reference another as long as there are no cycles, but is that strict enough?

YuMingLiao commented 3 years ago

Hmm, it seems to introduce more trouble than features. I don't know much about optimization. And I don't know if relational expression should be lazy or strict. I guess right now there is not much need for this. Features can be "called-by-need." :)