Closed YuMingLiao closed 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.
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?
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.
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?
Indeed. After implementing this, I've been thinking similar thoughts, but:
with
macro is unused, then it is not evaluated- this happens now is a quite natural and logicalwith
/"common table expressions" can be either chosen to be folded in to the expression executed in an additional step by the optimizer- what impact does that have on the expression replacement semantics. Perhaps none like in Haskell?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?
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." :)
TutorialD (master/main): :showexpr with(a as true, b as a) b
ERR: RelVarNotDefinedError "a"