AvailLang/Avail

availlang.org doesn't resolve, did it expire?

stylpe opened this issue · 16 comments

Not much more to say...

Oh wow, that's a shame.

How "not very modern" are we talking here? Is it part of this repo? I can't promise I would be able to help (mostly due to my own lack of time) but it shouldn't be too hard to bring up at least a static replica of the essentials, given either an old copy from web archive or the ability to bring it up locally.

Or at the very least set up a GitHub action to (or even completely manually) build and deploy the docs to GitHub pages and point the domain there.

I’ll try to block off some time to look into setting up GitHub Pages in the next few days. I’ll try to remember to post here once it’s up.

No rush for me 😁 but I can encourage you with saying it was super simple the one time I did it myself, with custom domain name too!

And I'd say it's no more than a nice to have to try to replicate and preserve old URLs, that can always be fixed later, and if you didn't have a lot of traffic anyway then it's even less important. You're not gonna break it more than it already is, and something is better than nothing!

We've translated the website to run on GitHub Pages, using Jekyll, and it's running under the former domain name, www.availlang.org. Yay! We've also fixed up some simple things like getting a passable dark mode, updating some external links, and removing former team members. Bad news: The website rewrite from the ground up probably won't happen any time soon. Good news: Most of the content is still valid and relevant, or at least pretty close.

Thanks for letting us know there are still people outside the core team poking at Avail!

Yeah! It's been a long time since I had a look, actually mostly because I forgot the name and wasn't able to explain it well enough to Google...

Are there any community sites of any kind, by the way? Discord, Reddit, Gitter?

There aren’t any active fora for discussing Avail. Oh, and the email subscription thing mentioned on the website disappeared a loooong time ago. I’ll remove it from the site when I get a chance. Same with RSS, I think (I removed Google Plus while reviving the site!). We do have a Facebook page for announcements, which is quite dormant.
Every few years someone writes an article about Avail, or includes it in some list, and a lively discussion ensues on ycombinator or Reddit for a few days. That’s always fun, but hasn’t been deeply useful to us. As we get more visible work done, such as the development tools, we’ll be reviving our publicity efforts once again.

Ok, thanks for the candid info!

I hope it's ok that I use this issue in lieu of other alternatives then for one more question, and then I'll stop distracting you for now ;)

I have lots of ideas I want to try with Avail, ranging from contributing bugfixes, to making a devcontainer-like experience using https://blog.jetbrains.com/blog/2021/03/11/projector-is-out/ enabling instant zero effort project onboarding, to writing an end-to-end acceptance test suite using webdriver (as an alternative to or even reusing Gherkin syntax), to crafting my own simple natural language programming dsl to give to my kid, with little to no punctuation or symbols and atypical programming features like context sensitive implicit variable usage (type- and name-based inference of the correct variable to use just by saying "it" and automatically select which values to provide as function and method arguments), to exploring high-level IDE features for writing Avail with auto-complete, auto-suggest, annotations, and so on to really squeeze that type system to get an ergonomic dev experience...

Some of them would benefit from a bit of discussion, but might not be well suited as GitHub issues. Would you mind if I create issues just for discussion for now though, until you establish new channels? Don't worry, like I already said, I don't have a lot of time on my hands so I promise I won't spam you 😇 Nor will I expect you to prioritize my grandiose schemes over anything at all.

Speaking for everyone at The Avail Foundation, I think we'd love to have user-created issues to discuss and explore. We can always close them if they're out of scope or in conflict with other directions we might want to go. And without a more "live" discussion mechanism, it'll have to do for now.

[Quick tip: use the development branch for now. It's the most recent, and seems stable.]

I see you've forked the repository, which is a great place to start. Hopefully the antiquated web site didn't divert you from IntelliJ (which we actually use) to Eclipse (which we left ages ago, after deriving great value from it).

We've already internally discussed internally an "it" mechanism like you suggested. I don't think it can be done with a zero-argument macro, since macros must return a single phrase (presumably a variable-use, in this case). Even if you supplement it with a prefix function like "it§" (the prefix function runs when the parser reaches where the § is in the method name), the current architecture again only allows a pass-fail, plus adjustments to the parsing information that the current fiber is handed by the compiler, and which the compiler extracts again after it runs. Without rearchitecting those parts, perhaps a custom lexer has the right flexibility. It's allowed to return multiple interpretations of runs of tokens, so maybe a new kind of token could carry information about which variable is intended, producing a separate one-element token sequence for each variable that's in scope. The compiler would have to be able to examine the token, in kind of the same way that the "…$" and "…#" method-name-parts look at the type of the literal token to determine if it's the right kind. Or maybe we really should introduce a special mechanism for macro to produce multiple values in rare cases.

A type-based approach would be similar, using "the_", like the integer to locate the intended variable.

We have a development environment underway, but stalled due to the realities of life and "real jobs"... despite the team using Avail for our real work project. We expect to throw some time at it later this year, or early next year. The tool will be called Anvil. We've already taken some steps to separate development-time metadata from the runtime aspects of functions and methods, loading them from a repository only when needed. That metadata will contain information needed for autosuggestion and autocompletion, syntax coloring/styling, background syntax error detection, automatic indentation, hyperlinking, hover-help, hover-to-show-subexpression-decomposition, and anything else we can add. I haven't tried Gherkin or Projector, but we intend Anvil to be web-based, even though developers might run their own servers locally.

I've attached a tiny mockup of the hover-to-decompose idea.
junk.html.zip

Also, if you're working out early sketches of ideas, or just exploring and need help, or want to talk about where to focus effort, or anything like that, feel free to email us at availlang.org, preceded by the word team and the usual email separator.

Thanks for the warm welcome! Todd mentioned your client projects, best of luck! And since there was no website when I got here at first, I didn't even know Eclipse used to be a thing 😁

For ”it", I had a slightly outside the box idea I want to try before going the custom lexer route, where it isn't technically the variable, but rather define methods like _it, It_, _it_, _it_it_ and so on, combined with some sort of compile time ambient data structure of the most recently used variables and return values, then lookup candidate methods by name and ultimately synthesizing a new method call that the normal parsers can handle. No idea how much compile time data is available outside the compiler though, so I do not assume it's even feasible, but I bet it'll be a fun experiment. It would probably be very limited, but in rare use cases that might me a good thing! I'll let you know how it goes (if I ever get started).

I also noticed the kanban board here with basic details and plans for Anvil, and I'm eager to take a closer look when I dive into the code some day.

For ideas about how the compiler makes information available to macros, have a look at P_BootstrapVariableUseMacro.kt, starting at line 103. This is the primitive method that takes a raw token like foo and looks up a variable in the current parsing scope, creating a variable use phrase from it, which is just a read of the variable foo at runtime. There may be many “current” scopes for the current position in the source, scattered over separate fibers exploring possible parse theories, each with potentially different ideas about whether some preceding source was a declaration or not. So the fiber has to carry that information about which variables are in scope in its universe. Declaration macros augment the copy that the fiber has. The prefix functions near the “[“ and “]” tokens of a block coordinate to add and remove a layer of scope. They’re primitive functions only for bootstrapping reasons. See P_BootstrapPrefixStartOfBlock.kt and P_BootstrapPrefixEndOfBlockBody.kt.

Control Structures.avail does the same sort of thing on line 656 for the macro "For each…from_to_by_§do_". This allows expressions like:

For each x from 1 to 10 by 1 do [Print: “x^2” ++ "\n";];

It looks like the macro has two bodies, but the first one is the prefix function, which gets invoked when the parser reaches the position corresponding to §. It introduces the loop variable name (captured where the occurred) into the scope, so that it can be mentioned inside the subsequent loop body (the loop being parsed). The second function is the actual body of the macro, which transforms the zero-argument block phrase that it parsed (the last macro argument, for the “_” after the “do” token) into one that takes the loop value (I.e., inserting the argument declaration that the prefix function created earlier). Macros are fun!

Re-reading your comment, the things like _it_it_ probably won’t work. The lexers map a character stream to tokens. The parser maps streams (technically directed graphs in the event of lexing ambiguity) of tokens into phrases, almost all of which look like method/macro sends. Macros convert phrases into other phrases. Macro prefix functions are a way to prepare/check/cull the parse state as described in the earlier comment.

I’m guessing that you intend "_it_it_" to have arbitrary sequences of tokens in its three _ slots, but parsed internally-complete phrases will be expected. If you use "«…!»it«…!»it«…!»", you can make it work, sort of, by having the compiler extract tuples of tokens, but I think that will be a dead end — there’s currently no mechanism to re-parse them into phrases.

We’re working on introducing an eval mechanism, but it’s unclear if we could apply it easily to a tuple of tokens. Eval will have to operate on a string that gets dynamically lexed into a graph of lazily-produced tokens, which are consumed by the parser. Technically, it operates on an in-memory module, so imports for the eval can be controlled.

I think the solution will be a lexer that recognizes “it” (a filter function to detect ¢i, and a body that consumes the ¢i and the ¢t if there are no word-like characters after). The lexer has access to the current parse state (I believe), so it can simply produce a set of tuples of tokens. The elements of the set are alternative lexes. Each tuple has size one – it's set up this way to allow a lexer to resolve an ambiguity by scanning ahead a bit, say distinguishing apostrophes inside contractions versus single-quoting something, so "can't and won't" and "can'fish' for money" could be distinguished. The tokens in the one-element tuples would be the names of the variables that are in scope. The parser will continue along each element of the set, so you'll almost certainly need to narrow the variables by priority based on recency of usage, or recency of definition, or perhaps overlap of types.

To track recency of usage, you’ll have to write custom implementations (in Avail) of:

  • "…", (variable use)
  • "…:=_;", (assignment)
    and possibly
  • "…:_†;", (variable declaration)
  • "…::=_;", (constant declaration)
  • "…:†:=;", (initializing variable declaration)

If that's the approach you take, Lexers.avail should provide lots of examples, although you may need to consult the "For each…from_to_by_§do_" macro to see how the parse state is accessed. Be careful to keep all lexing/parsing side-effects localized to the content of that fiber variable, otherwise the concurrency of the compiler will surprise you. In a bad way. Printing to the console for debugging is fine, however.

One more tip: Placing a tilde ("~") after "it" will make it parse case-insensitively. That also works after a "«foo_bar_baz»~" guillemet group, effectively distributing the tilde over the alphabetic tokens of the group. So that would behave exactly the same as "«foo~_bar~_baz~»".

New issues #201 and possibly #202 may be of interest to you. We've hit our own use cases for #201 in the recent past, so it would be directly useful to us to prioritize it.