u/WalkerCodeRanger
WalkerCodeRanger
WalkerCodeRanger
If you want feedback on the compiler I suggest https://www.reddit.com/r/Compilers/ This Reddit is focused on language design.
WalkerCodeRanger
You seem to be ignoring several other important distinctions:
- structs/classes etc aren't product types whose fields are named. They are types whose fields are unorderd.
- Tuples are unnamed/structural types. Record types are nominal types.
- Encapsulation: tuples expose all their fields. Record types may not
C# actually supports tuple types with named fields. The named fields can be mixed with purely positional members. But they remain unnamed/structural types. That is fully distinct from classes.
Usually, if you are declaring a nominal type, then it is reasonable to name all the members because that nominal type will be reused. It would be rare that you wouldn't have a good name to give a field. Many languages support a way of declaring nominal types that can also be destructured by position like tuples. C# uses the record keyword for those.
WalkerCodeRanger
Check out NodaTime for .NET
WalkerCodeRanger
Good reminder about the XZ exploit.
The NuGet package manager doesn't seem to have nearly as many problems with these things despite it distributing nearly binary files. I think there are two reasons:
- The standard library is large. This eliminates the existence of packages like left pad in NPM. It also means that packages have far fewer transitive dependencies. I've recently switched from .NET to Java, and the package dependency situation in Java is insane. Of course there will be an exploit of a system like that.
- The package server policies are tighter. By default, you can't just pull a package. You can hide a package, but that just removes it from the list of options to add. All projects that reference the existing package continue to work. You would need to contact the package org and provide evidence of patent or copyright infringement to get a package truly pulled. That is the right policy and totally removes the NPM left pad fiasco.
WalkerCodeRanger
Yes, that is a real problem. You can use things like signatures, hashes, and authentication to confirm that an uploaded package is coming from the actual project maintainer. However, that doesn't stop someone from creating a new package and putting malicious content in it. Nor does it stop a package maintainer who has previously been above board from adding malicious content. I suspect this is one of the reasons that all Rust crates are distributed as source code.
Note that for very large codebases it is still quite possible to hide malicious code in them. It just makes it traceable and theoretically checkable if the package is distributed as code or the builds are reproducible. I would point out that the .NET package manager NuGet distributes packages as .NET IL (not as bad as assembly, but not source code either). They seem to be doing ok. Ultimately, one must vet and trust the packages one is using.
Options: * Don't let people upload binary packages. Require that the package be distributed as source code even if it is C. That would require some kind of standardized C build system so you could download and compile a package even if it contains C * Require some kind of reproducible builds even for C. That would allow someone to verify the commit referenced in the package actually compiles to the build. (This will be difficult given the variety of C toolchains.)
I believe the Zig compiler supports compiling C code in addition to Zig. Perhaps that is partially because of these reasons. You might check into what they are doing.
WalkerCodeRanger
Exalted has roll penalties for wounds
WalkerCodeRanger
You have narrowed down what you are looking for more than the title suggests, so I am not sure if you will count some of these.
I am working on a language Azoth, with what in the literature are called reference capabilities. This is something like a relaxed borrow checker for GC languages that gives the same fearless concurrency guarantees. I think that might be an example. As an example of the innovation this leads to, the combination of reference capabilities with reference and value types has led me to the creation of a new hybrid category of types. Where the initial instance of a type acts as an affine value type, but other instances are reference types. The distinction of when you have a value vs a reference is controlled by the reference capability.
Another example is structured concurrency. While various libraries and languages have been adopting elements of it, we haven't seen a language built around it. I think it is the kind of paradigm that will give most of its benefits in a language built for it, where all code follows the paradigm.
Of course, the real answer is probably yes something we aren't even thinking of now. We still live in the dark ages of computer programming.
WalkerCodeRanger
What's an artifact-centric programming language? I haven't heard that term either.
WalkerCodeRanger
Common law marriage is supposed to require the parties involved to agree that they are married. If both partners say they were not married and just cohabitating then there was no common law marriage. Were these situations where one partner claimed there was a common law marriage and the other didn't?
WalkerCodeRanger
I know. But I still think that the lack of open source early on was the primary factor that made people outside Microsoft not build languages for it. Perhaps we'll see more languages for it in time, but I suspect its association with Microsoft and a lot of people not realizing it is truly open source will continue to hinder language development on the .NET runtime.
He claims that reified generics is the reason languages aren't developed on .NET runtime. That doesn't make sense since one could just do type erasure the same way languages on the JVM do if a language needed that.
WalkerCodeRanger
One thing he is wrong about is support for multiple languages on .NET. The .NET runtime supports multiple languages just as well as JVM and actually has support for things like value types that some languages need. Both JVM and .NET suffer from too much leakage of the runtime into languages. For example, that Scala uses Option[T] but can't enforce that references should not be null. The reason there arn't more languages for .NET and there more for JVM is because the open source nature of it.
WalkerCodeRanger
The conflict with member access is a real problem. Also, in many languages, it would be hard to tell when the condition ends. So you'll need some kind of terminator on the condition unless it must be on one line (or use a line continuation character).
I've come up with something similar to your proposal. Many have argued that -- is a bad operator and people should just use -= 1. So imagine using that as a block end. In a language where the indent convention was two spaces this could work very well. Your example would become:
``` if (condition_1) action1 if condition_2 action2 -- else
action3
```
They would be allowed to be combined to terminate multiple blocks. For example ``` if (condition_1) if (condition_2) action1
action2
``
The----` here is two operators and terminates both if statements
WalkerCodeRanger
Each person is different. What worked for me was to work on it for ~8 hours each Sunday. I found the large, uninterrupted block of time worked better. Sunday was good because I was putting my language "first" since I was rested from Saturday and effectively started working on my language at the start of my week. Sometimes my interest in the work would carry over into the week, but that was strictly as I felt like it. And I felt good because I always knew I would get to work on the language next Sunday. But it is hard to accept the slow pace of progress that comes with only working 8hrs/week on a project.
WalkerCodeRanger
You won't find any central list because people see it as too subjective and because no one is going to take the effort to summarize across languages. But you can find some information from specific language designers about what they see as flaws in their own language. For example, Sharp Regrets: Top 10 Worst C# Features
WalkerCodeRanger
One reason people don't do the least upper bound is that it is very easy for the inferred type to be too general. For example, Java had an issue where its equivalent of let numbers = [ 1, 2, 1.1] would be inferred to be a list of object. If there is a supertype of all types in Grace (e.g. Any), be careful about when you infer the type list of any.
WalkerCodeRanger
I agree their brokerage is good. The offering and then taking away of other services has been a real black mark against them though. It is fine if they don't want to offer other banking stuff, but once they are offering it, they need to be committed to it.
WalkerCodeRanger
The convention in math is to put the operator on the next line. I find languages that force the operator to be on the same line before the newline to be unacceptable.
WalkerCodeRanger
Joe Duffy’s "The Error Model" post that is referenced at the start makes a clear distinction between recoverable and unrecoverable errors. The author is being a little loose about that and assuming you will know which are which. When it talks about fallible functions are "annotated at the call side", it is talking about recoverable errors. For Rust, that would be errors indicated by Result. Panics are for unrecoverable errors and those don't get annotated at the call side.
WalkerCodeRanger
Pony (https://www.ponylang.io/) It may be too obscure and too small of a dev community. However, it is designed for concurrency and has reference capabilities which are like Rust's safety but different because there is GC. I believe it does use exceptions though. (I don't think exceptions are bad if the language supports them properly. It is just that most languages don't)
If it were further along, I would say the language I am designing, Azoth. But it isn't ready for anyone to use yet.
WalkerCodeRanger
C# has had records since C# 9 (Nov 2019). You have been able to simulate something close to Java sealed classes using private protected constructors since C# 7.2 (Nov 2017). There is an active proposal for Closed Hierarchies to add a direct equivalent of sealed classes and interfaces including exhaustiveness checking on pattern matching switches on them.
WalkerCodeRanger
In what sense does Java have algebraic data types that C# doesn't? C# has quite good pattern matching. Virtul threads are a good feature, but I think most devs would prefer the ease of async/await to the code that it takes to use virtual threads in Java.
WalkerCodeRanger
On suggestion I've given before is creat a dyanmically typed language with a gradual type system with two important caveats: 1. There is a compiler switch to throw that requires all code to be statically checked. 2. The public API of all packages published to the public package repository must always be fully statically typed.
The second is critical because it ensure that anyone trying to write statically typed code in the language can do so rather than the situation in most gradually typed languages where all the libraries you need to use don't have static types.
This setup would allow for the writing of the code by the acemdenics in a dynamically typed scripting language and then types could be interoduced and the code refactored and then when it was mature enough full static typing enforced. Of course, whether that kind of refactoring will actually be done is another question.
WalkerCodeRanger
I think both are valuable and I do think that variant types were largely lost in that linage of languages. Remember that Casey deals mostly with low-level languages where they are more likely to be valuable. See for example how Rust has made vary good use of them. Having a closed set of variants is very valuable when you have it because you can safely do an exhaustive match on them. That is something languages ought to provide in addition to open set of variants from virtual methods.
WalkerCodeRanger
Since you ask, there aren't any great books, but I do think Programming Linguists by David Gelernter is worth a ready if you can find a copy.
Check out Fortress