Earlier quoted context omitted.
Let's say further that you already know Zig exists, and aren't going to use it for reasons that anyone writing a C/Rust/D/C++ program already knows. At least give Nim a try.
The difference here is that there aren't C programmers who don't know about Rust, and since they're writing C, they have reasons they aren't using it. The same is not true of Zig. Some of the reasons not to be using Rust may be applicable (no specification comes to mind), others may not be. I do agree that, on an even playing field, Nim should be considered when any of Rust, D, C++, or Go, are on the table. This is l…
Algebraic Data Types for C99
221–230 of 233 posts
Re: Algebraic Data Types for C99
#222Earlier quoted context omitted.
> "anything goes" languages such as LISP have struggled to gain widespread adoption: with no philosophy every programmer becomes an island unto themselves. There are already two misconceptions. First: "Lisp has no programming philosophies" and styles. Not every program starts by zero. Since Lisp exists since the end 1950s, it has seen quite a lot in programming styles over the years and it may contain traces of sever…
First: "Lisp has no programming philosophies" and styles You misquoted me. I said no philosophy , singular. In the programming language context, a philosophy is a convention or a standard. Just as many standards implies that there is no standard, many philosophies implies no philosophy. Everything else you said is evidence for my premise. Hire 3 different programmers, one from each of the communities, and you might a…
That makes no sense.
> Hire 3 different programmers, one from each of the communities, and you might as well have 3 different programming languages.
Maybe not. They build on the same foundation, a language with a large standard, which is largely unchanged since three decades. A language which can be incrementally extended, without invalidating the rest. A language where extensions can be embedded, without invalidating the rest of the language or its tools. Many projects use SBCL (now itself 25 years old and only incrementally grown) and a bunch of core libraries for it.
> That’s not a standard. That’s not a philosophy. That’s anything goes!
Most languages support widely different software development practices. Take JavaScript: it includes imperative, object-oriented and functional elements (similar to Lisp). It has huge amounts of competing frameworks (many more than any Lisp), where many of them have been superseded and many of them are built on a multitude of other libraries. The developer can pick and choose. Each projects will be different from other projects, depending on which libraries and programming frameworks it uses - and which of those the developer re-invents.
Any half-way powerful language (C++ -> templates, Ruby -> meta objects, Java -> objects & byte code & reflection & class loader, Smalltalk -> meta objects, Rust -> macros, C++ -> language interpreters, Java -> external configuration languages, C -> macro processor, ...) has ways to adapt the language to a certain style & domain.
Any large Java framework defines new standards, new configuration mechanisms, new ways to use new Java features (lambdas, streams, ...). See the large list of features added to the Java language over time: https://en.wikipedia.org/wiki/Java_version_history For many of them there were competing proposals. Each Java code base will use some subset/superset of these features, depending on what is needed and what the personal preferences are. And then the Java architect in the project will not be satisfied and will invent yet another configuration system, this time not using XML or JSON for the syntax, but develop a new embedded scripting language for the JVM and integrate that with his software. I have seen Java architects which eventually didn't understand their own configuration system any more.
If you think a language like Common Lisp is special here, then in reality it is not. It's just slightly different in that it has extensibility as one of its philosophies and provides defined interfaces for that. There is one macro mechanism, which is powerful enough, that for decades it has not been replaced. Every syntactic extension mechanism will use this macro system, which is documented, stable and widely used.
Re: Algebraic Data Types for C99
#223Earlier quoted context omitted.
> [Algebraic Data Types are] such a basic mental model of how humans think and solve problems I think that's actually wrong for "Sum types". Product types, sure. The idea of storing a bunch of fields in a single thing matches the way we've been organizing information since we started writing things down. But I genuinely don't think I've seen an attempt at a sum/union/enumerant/whatever syntax in a programming languag…
> But I genuinely don't think I've seen an attempt at a sum/union/enumerant/whatever syntax in a programming language that wasn't horrifyingly confusing. Syntaxes like: `A | B(Int) | C(String)`. That means A, B, or C. > Where by extension: class-based inheritance is actually pretty simple to understand. The classic "IS-A" relationship isn't as simple as "fields in a struct", but it's not hard to understand This value…
Inheritance addresses similar issues by delegating the responsibility, something that is easy to understand. Does it have downsides? Sure. But I'm not sold that ADT has the advantage here at all.
Re: Algebraic Data Types for C99
#224Earlier quoted context omitted.
My view of Go went from being annoyed to "they picked their tradeoffs carefully and consciously and then leaned into them hard to squeeze every ounce of upside out of them" and while it's still not really my preferred aesthetic I now have a lot of respect for the design as a design process. Meanwhile, getting addicted to scheme many years ago is a lot of why I still mostly write perl, I need 'my' (i.e. expression/blo…
Despite what I may have made it seem, I actually quite like Go as a language, I just wouldn't call it elegant or pretty (though certainly not as ugly as some other languages out there), but it's very pragmatic. It's been a long time since I've written any Perl, but I can say I don't care for it as much as I do Lisps in general.
It barely feels like the same language as sysadmin scripts are written in, it just happens to share a compiler and a VM.
... and it doesn't exactly even share syntax since perl supports libraries defining their own keywords, e.g. while I won't be surprised if somebody makes it a feature of the VM eventually, our async/await is currently provided by https://metacpan.org/pod/Future::AsyncAwait and as you can see at https://metacpan.org/pod/Future::AsyncAwait#WITH-OTHER-MODUL... there's quite a few other useful ones out there.
Of course, many people complain vociferously about the idea that you have to use *libraries* to get syntax, but as somebody who still loves scheme I regard the ability to build the language up towards the problem to that extent to be a feature.
My first ever cpan release was making continuations pass back out to perl as a subroutine reference from Guile so I could write linear top level logic in scheme and use continuation capturing to sit that atop an event driven I/O stack - axisofeval.blogspot.com's lispx (https://github.com/lispx/lispx/) provides an fexpr based lisp that does similar for JS.
(trying to think of a good example of perl code of mine that shows an example of this is annoying me because I don't have any public code right now that's new enough for me to not have already decided I don't like it anymore ;)
Re: Algebraic Data Types for C99
#225 datatype(
BinaryTree,
(Leaf, int),
(Node, BinaryTree *, int, BinaryTree *)
);
No names for the struct fields, so you need to rely on the position.And then used:
int sum(const BinaryTree *tree) {
match(*tree) {
of(Leaf, x) return *x;
of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
}
// Invalid input (no such variant).
return -1;
}
Where lhs, x, rhs magically match the types defined above. What a nonsense design!Re: Algebraic Data Types for C99
#226One of the crimes of modern imperative programming languages is not having ADTs (except maybe Rust) built-in. It is such a basic mental model of how humans think and solve problems. But instead we got inheritance and enums which are practically very primitive.
> [Algebraic Data Types are] such a basic mental model of how humans think and solve problems I think that's actually wrong for "Sum types". Product types, sure. The idea of storing a bunch of fields in a single thing matches the way we've been organizing information since we started writing things down. But I genuinely don't think I've seen an attempt at a sum/union/enumerant/whatever syntax in a programming languag…
data Bool = True | FalseRe: Algebraic Data Types for C99
#227Earlier quoted context omitted.
> "anything goes" languages such as LISP have struggled to gain widespread adoption: with no philosophy every programmer becomes an island unto themselves. There are already two misconceptions. First: "Lisp has no programming philosophies" and styles. Not every program starts by zero. Since Lisp exists since the end 1950s, it has seen quite a lot in programming styles over the years and it may contain traces of sever…
First: "Lisp has no programming philosophies" and styles You misquoted me. I said no philosophy , singular. In the programming language context, a philosophy is a convention or a standard. Just as many standards implies that there is no standard, many philosophies implies no philosophy. Everything else you said is evidence for my premise. Hire 3 different programmers, one from each of the communities, and you might a…
Most of the Common Lisp code that is accessible via public repositories conforms to conventions and is understandable.
Lisp programmers are highly motivated toward encouraging collaboration, since there aren't that many people in Lisp where you can afford to be turning people away toward projects that are easier to get into.
Also, you can easily hire 3 developers and get 3 different languages in, oh, Java or JavaScript. One person is doing Kotlin, another one Scala, ...
Three C++ programmers in the same room could also not understand each other. The greybeard speaking only C++98 with a bit of 2003 doesn't grok the words coming out of the C++20 girl's mouth and so it goes.
Re: Algebraic Data Types for C99
#228Earlier quoted context omitted.
This often comes up when writing a function which returns a wrapper over a generic type (like Option ). If your Option type is T | null, then there's no way to distinguish between a null returned by the function or a null that is part of T. As a concrete example, consider a map with a method get(key: K) -> Option . How do you tell the difference between a missing key and a key which contains `null` as a value?
This is trivial to model by making your type `T | null | Missing`.
Re: Algebraic Data Types for C99
#229Earlier quoted context omitted.
This often comes up when writing a function which returns a wrapper over a generic type (like Option ). If your Option type is T | null, then there's no way to distinguish between a null returned by the function or a null that is part of T. As a concrete example, consider a map with a method get(key: K) -> Option . How do you tell the difference between a missing key and a key which contains `null` as a value?
`T | null` is equivalent to T. You can assign null to `T`> It's like saying `string | "foo"` it is simply `string` due to subtyping.