Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TASK] Mandatory def input types #108

Closed
2 of 4 tasks
kurtlawrence opened this issue Jul 5, 2022 · 1 comment
Closed
2 of 4 tasks

[TASK] Mandatory def input types #108

kurtlawrence opened this issue Jul 5, 2022 · 1 comment
Labels
breaking-change Likely to break existing code bases

Comments

@kurtlawrence
Copy link
Member

kurtlawrence commented Jul 5, 2022

Goal

Constrain the type system such that all defs have a known input type.

Benefits

More robust type inference is the major goal here. By knowing the set of concrete types that a def is expecting, only that set of types has to be tested.

Concerns

Agnostic defs

Many defs are input agnostic. This will still be a requirement.
The proposed solution is to force the input to be Nil. Unfortunately, this will break how the current type inference flows types.
The convention will break certain patterns, for example:

# This would previously work, and list out along folder `foo-bar`.
\ 'foo' | ls { + '-bar' }

# Now the concatenation would have to occur sooner, be bound to a variable, and then passed as an argument.
\ 'foo' | + '-bar' | let $x | ls $x

Since this pattern becomes unwieldy with the change, it might be worthwhile adding a definition which can handle this:

\ 'foo' | + '-bar' | zog ls $z
                     ^^^ --- ^ a def which stores input in $z and calls `ls` with Nil input

Another approach would be to consider defs with Nil input types to be agnostic. It is rare to actually switch input to Nil to call a def, so rather than having a distinction between Nil and anything, combine the two and add a special variable (or literal?) which can be populated with the output of the previous block.
This approach may grate with the goal of reducing type inference complexity. The issue is the coercion to any output type, it makes the type inference unconstrained.

def foo Nil (len:Num) { \ $len | + 2 }

ls | foo { \#i | len }

Maybe a combination?

To keep the input type as a constraint, a defining characteristic of the call needs to be present.
The input def (\) would be a good candidate.
Parsing would need to be altered to such that trailing characters are taken as a def identifier.

def foo Nil (len:Num) { \ $len | + 2 }
                         ^ a space is now necessary

ls | \foo { \ $prev | len }
     ^^^^     ^^^^ store output of previous block in `$prev`
     `foo` is known to be called with `Nil`.

# Another way to write this
ls | len | \foo $prev

The let def

The let def is special, since it is required to be general.

@kurtlawrence kurtlawrence added the breaking-change Likely to break existing code bases label Jul 5, 2022
@kurtlawrence
Copy link
Member Author

A show stopping concern is how general definitions will be constrained by this change.
For example, the min definition is intended to be generalised in #83, which would be something like: def min (b) { {> $b} $b #i }.
Introducing an input requirement would place a burden on introducing generics to handle this polymorphism (eg def min 'a:'a (b:'a) { {> $b} $b #i }).
This detracts from the goal, reducing the set of types to infer.

Instead, the solution should combine some ideas initially proposed, and undertake a rework of the inferencer. The \ overload is potentially useful for arithmetic operators, and better set management could be employed on the type graph.

@kurtlawrence kurtlawrence closed this as not planned Won't fix, can't repro, duplicate, stale Jul 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Likely to break existing code bases
Projects
None yet
Development

No branches or pull requests

1 participant