I don't have any direct experience with Menhir because I haven't tried to write a compiler in OCaml yet. It does seem to be one of the better parser generators and is frequently recommended. Skimming the docs, its seems to be lacking in these areas:
* Concrete syntax trees (as you pointed out)
* LR(1) will probably still be more restrictive than I want
* Unicode support (defaults to ocamllex, requires custom code to use ulex)
* Intransitive Operator Precedence isn't supported (though it does have regular precedence levels and associativity)
* While it looks to have better error handling than most LR parser generators, I suspect it still isn't where I'd want it to be.
I suspect there are other issues, but I don't want to go any further beyond my knowledge base than I already have. I've been thinking about writing on this topic more, if I do, then I might address this more.
With regard to operator precedence, my position may be closer to yours than you think. In the post I linked to about intransitive operator precedence (https://blog.adamant-lang.org/2019/operator-precedence/) I describe what I want. Basically, I think basic order of operations like `*` before `+` and associativity are important. But in more complicated cases you should be forced to put in parentheses. Exactly where that line is drawn can be debated. What I want is a way of handling operator precedence that is more complicated under the hood, but should be more natural for the programmer as it will respect basic precedence, but not leave you guessing about confusing expressions. i.e. `a/b/c` could be illegal and require parentheses even though `a+b/c` doesn't.
I think our positions are pretty close, I'm just coming around to the idea that any operator precedence at all is of dubious value.
It's nice to write `a + b * c` and have it parsed the "right" way, but I've become fairly comfortable with the idea of getting rid of that. To always require parentheses. I don't think writing `a + (b * c)` is that terrible. `a + b == c` is a little more annoying as `(a + b) == c`.
Where I think the worst cases are is addition/subtraction, since those are so primitive -- subtraction can be thought of as addition of a negation, and in that form it is directly associative with addition. Indexing into arrays with constructs like `x[a + b - 1]` is incredibly common, and here almost any parenthesization makes it look like it has meaning -- if you see code that says `x[(a + b) - 1]`, is that a different intent than `x[a + (b - 1)]`? It feels different to me; `x[(start + offset) - 1]` is an adjustment, but `x[start + (first_comma - 1)]` is finding the location before an offset.
On associativity I think this gets even worse; if you have to parenthesize `a + b + c` then it feels like the language is getting in your way, just by force of habit. Nobody blinks at the idea of deciding between `a b + c +` vs. `a b c + +` in a stack language, so maybe people would just get used to typing `a + (b + c)` and it would just fade into the background.
This is all kind of rambly; my general feeling about computer languages is what I said above -- the harder it is for a machine to parse, the harder it is for a person to read; but some idioms are just so ingrained that it's hard to even recognize that you're making assumptions about associativity; and I venture there's a significant class of programmers who don't know what associativity is in any formal sense but routinely use the property because it's so ingrained in how we are taught to calculate.
Check out https://www.folioinvesting.com They allow you to create your own "index funds" as well as select from a list of existing folios. Flat monthly fee.
Thanks for the good info about the DT project. I want to say that even though I'm not personally a fan of TypeScript I really appreciate the work of you and everyone else who has contributed to the DT project. I know from my previous work on OSS how much work that can be.
My only experience using DT was through Nuget so I didn't realize you had the semver postfix. I suspect that like me most .NET devs will go to Nuget first, so I personally would place a high priority on getting semver in Nuget, but I understand that there are lots of other important things too.
My suggestion would to make including a semver part of your quality requirements so that at least you have a record of what version they were working against when they made the type definitions.
I hadn't realized the interdependent library testing/validation. You really are in a pickle about git branching/tagging and not being able to have separate repos. Problem is, the side by side definitions for different versions makes it difficult to merge fixes across versions (as compared to say a different branch for each version of the library). I think this is something that needs to be thought about long and hard. Could you use git submodules or subtrees to do what you need? Perhaps have each library in its own repo but then have a repo that pulls them together and has the interdependecy testing? That way most contributors could work in the repo for the project they care about and only a few contributors would worry about the combined one?
Thanks for sharing your experience with TypeScript and what is good about it. It's just not possible for me to address everything bad & good about a language in one blog post, so I have to focus on what's relevant to the point I am trying to make (in this case why I don't personally think TypeScript is the answer to JavaScript).
I absolutely agree that meshing with the JS ecosystem is of critical importance and Dart just doesn't have that the way TypeScript or CoffeeScript does.
I'm on the Dart team and I can honestly say that we're working very hard on this.
We simply have a harder problem to solve than TypeScript (different features and semantics, working with the VM as well as compiling to JavaScript), so it's taking longer, but we're aiming for nothing short of awesome and seamless interop.
We already have dart:js, a low-level JS-interop library that works in dart2js and with the Dart VM. Admittedly it's a bit cumbersome for developers to use, but it provides the building blocks that we can use to make TypeScript-like Dart interfaces for JavaScript libraries, and to export Dart libraries to JavaScript.
It's great to hear about a project like DefinitelyTyped, because once we have the support in place, we're going to need something very much like it in Dart.
It's not just about staying at a particular version. It is about being able to find the version that matches what you are using. I recently started an new project using bootstrap and had to downgrade to v3.0.3 due to some incompatibilities. I have no idea how I would go about finding the matching type definitions from definitely typed. Their version numbers don't match bootstrap's (http://www.nuget.org/packages/bootstrap.TypeScript.Definitel...).
Also, how will the Definitely Type project be able to handle a fix to the definitions of an old version that doesn't apply to the current version?
Like jstclair I appreciate their hard work, but I think they really need to change their approach soon to avoid a lot of pain down the road.
There is a project that converts Typescript to Closure type annotations. If you do this, and put Closure Compiler in your continuous build/test phase, it will can catch when there is a mismatch between the caller and the library, not in all cases, but it helps.
Sorry you feel I am wasting your time. I am actually working up to the point of what I think would be better. The purpose of writing about the inadequacies of the existing tools is to provide a justification for creating an alternative.
I also want to gauge interest in creating another alternative to see whether it would be worth my time and effort.
One of the reasons why you think TypeScript isn't the answer is "TypeScript doesn’t fix anything in JavaScript". You seem to fall into the trap of saying "Don't use JavaScript or anything that's like JavaScript" when in real life projects both are popular and effective. It's easy to laugh at the == operator but people don't use it, etc.
Actually, I don't start with the premise that static typing is bad. I actually prefer static typing and if I was designing a language from the ground up it would probably be statically typed. In my day job I work largely in C# and JavaScript and much prefer C# (though it could be better). Unfortunately, we have an dynamically typed foundation (in JavaScript) to work from which makes it very difficult. None the less, dynamically typed prototype based languages can be powerful and have their advantages.
I actually really like Haskell though I have never had the chance to do a project in it. I appreciate the strong type inference and its flexibility in static typing. I occasionally find myself frustrated my C#'s limitations around complex typing. Like that there is nothing close to existential types and you can't create more complex generic type constraints.
Scala seems cool in what little I have read about it. I really respect Martin Odersky who designed it. I'd like to learn more about it, until I do I can't speak much to it.
> The problem with JavaScript is not that it is a dynamically typed prototype based object-oriented language without classes. That is actually JavaScript’s strength.
the above suggests disliking static typing as a premise.
At dox (http://www.usedox.com) our stack is basically haskell/yesod in back typescript/angular up front. sure there are annoying limitations of typescript relative to haskell but compared to any of the AltJSs that we've looked at or used (coffee script, elm, fay, roy, purescript, dart, actual javascript) it has far and away the best combination of safety and ease of integration with javascript libraries.
We love coffee script's syntax but the type safety of TS has become a must-have that we can't live without.
Typescript, once you start adding annotations, does actually combat some of the bigger warts in JS. specifically erroring on wat-ops like 1 + "" vs 1 - "" or [] - "".
Such things are so subjective, but the sources I read usually only list the first three. I'm not opposed to learning about ClojureScript, but I have to make choices about where to spend my time. At this point, I think I need to focus on addressing JS Linters and what I think an answer would look like. When I write those up, I'd love to hear feedback from someone who knows ClojureScript about how closely (or not) it matches what I would be looking for.
I don't have any direct experience with Menhir because I haven't tried to write a compiler in OCaml yet. It does seem to be one of the better parser generators and is frequently recommended. Skimming the docs, its seems to be lacking in these areas:
I suspect there are other issues, but I don't want to go any further beyond my knowledge base than I already have. I've been thinking about writing on this topic more, if I do, then I might address this more.