Open kwangure opened 7 months ago
Hi, yes I have been thinking about this as well.
I like the idea of having a named binder, and it works well when the tests are on variables like in your example. However, I am not sure what to do in the case of other expressions:
if none (x.foo().g) {
//what is the binder name here
}
One option would be to say that for non-variable expressions the binder name is just $
as it is now. Another option would be to add some syntax for naming the binder explicitly -- maybe:
if !none |calledg|(x.foo().g) {
return $calledg;
}
I like that this is a more uniform way to do the binding names but I am not sure if the added complexity is worth it.
Interested to hear what ideas on this.
Hmm. I hadn't thought about how to deal with expressions.
I did various prompts guiding ChatGPT4 to hallucinate its way to a syntax for expressions given the above suggested syntax for simple variables. It consistently either autocompleted with the assignment or a postfix before the curly brace as below:
// Alternative A
if $foo = none (x) {
return $foo;
}
if $bar = none (x.foo().g) {
return $bar;
}
// Alternative B
if none (x) $foo {
return $foo;
}
if none (x.foo().g) $bar {
return $bar;
}
For completeness, I'll also add a few suggestions from generated outputs that were more murky or I did not like:
if none $foo (x.foo().g) {
return $foo;
}
if none (x.foo().g) {
return $x.foo().g;
}
if none (x.foo().g) {
return x.foo().$g;
}
let temp = x.foo().g; // i.e. require an assignment variable
if none (temp) {
return $x.foo().g;
}
I was initially hesitant about a naming syntax, but it has grown on me pretty quickly. I find that it's quite inline with Bosque's current goals and patterns, and it gives a nice visual cue to both human and LLM readers as to where the narrowed value is actually coming from (particularly with the assignment syntax).
As a quick update on this. The current priority is to get the BSQON notation and parser code in a beta shippable state. Then the roadmap is to pivot to the core Bosque runtime. I'll include this feature as a revision in that work.
The proposed design will to:
$v$
syntax when the test expression is itself a variable that is not already a binder (prefixed with a $
) $_
for any other expression formAs opposed to normal values we will allow binders to shadow (since this is a general requirement when we support them in other areas) so in following is valid (if weird) code where the definition of $x
in the inner non test shadows not reassigns the definition of $x
in the outer one.
function f(x: Int?, y: Int?, b: Bool): Int {
if !none (x) {
if(b) {
return $x;
}
if $x = !none (y) {
return $x;
}
}
}
f(2, 3, true) //2
f(2, 3, false) //3
Added support in Parser and Type Checker in PR #86. Needs more testing and such.
Modified the grammar a bit to put assignment inside parens:
if ($x = y) ...
and shift ITest to after expression + explicit choice to bind:
if(x)!none %%ITest, no bind
if(x)@!none %%ITest, bind $x
if($y = x)@!none %%ITest bind $y to x
if($y = x)!none %%Error since no set of bind
Would you consider making binders named? It feels more explicit, intuitive and can allow narrowing of multiple values.