One of my own (nearly abandoned) toy projects is something similar. It's not easy — at least to me it wasn't — to design a language that is forgiving on as many aspects as possible. Both syntactically and semantically. Turning every error into a warning during development time and keep the impact as local as possible. Type errors turn into implicit holes of type bottom, just make sure the IDE is explicit about it.
One of the tricks I applied is to use indentation style syntax (like Haskell/Python). Now syntax errors only break one level of code. Preventing the IDE from coloring the rest of your buffer red because you still need to type out your closing parenthesis.
Edit: I see Hazal takes the valid-by-construction approach, which is different from be-forgiving-but-explicit. Both are approaches worth of experimentation.
Repo: https://github.com/xixixao/Shem Playground: http://xixixao.github.io/Golem Talk: https://www.youtube.com/watch?v=HnZipJOan54
Hazel looks fantastic - I don't think I've come across it before. I think an obstacle structural editors have to becoming more widely adopted is that they start out very general and don't immediately solve a problem that people have. You can usually build little toy programs but not much more. What I've tried to do is to focus on creating an editor for a small DSL that helps with a specific problem.
Code demo:
https://github.com/web3cryptowallet/Web3CryptoWallet
More info about Animation CPU:
Suppose I have an assigned variable, which later I plan to use. When I'm about to use it, but not yet did, I have a hole. Suppose before filling the hole I've realized that the current type of the variable - and assigned value - is wrong, so I want to use the correct type.
Can hole-oriented programming help me with that change of mind? When we use a program, using a configuration file but also allowing command-line overrides of values, we assume last-time command-line overrides have precedence over values in the configuration file. Can we consider later-time use of variable with different type overriding the previous type, which now considered to be incorrect? Of should the language catch us making a type error here?
In the first case, the hole has a type. I believe this type is inferred by the compiler/editor/type-checker, and I believe it will tell you if they type is wrong (in Dark, we'll tell you if the type is wrong, though we'll still let you put that variable in that hole to support the transition from one valid state to another).
In the configuration file example, you can't change the type: these are statically typed functional languages, and they don't permit "later-time" type changes.
With a statically typed language, the choice is up to you. Every statically typed language is just a "dynamically typed" language with the ability to statically assign types. For example, you can type the variable as an "Int" or for more runtime flexibility, a "Variant" (if using C++).
int q // q is considered a hole of int type
q <- // but we're typing "hello" there
Practicalities ask for the situation to be considered a problem - not of incorrectly plugged hole (when into "int" place you're putting "string" value), but of incorrectly previously stated type (it's the original "int q" which is wrong, should have been "string q").
This is the kind of thing I come to HN to discover! Cool ideas.
You aren't writing code in a text file, but rather in a very constrained graphical environment.
The bet they're making is that in return for giving up this flexibility you hopefully get powerful refactoring and code analysis capabilities.