My favourite FizzBuzz is in Haskell, I found it in this talk by Kevlin Henney[0], and looks like this:
fizzes = cycle ["", "", "Fizz"]
buzzes = cycle ["", "", "", "", "Buzzes"]
words = zipWith (++) fizzes buzzes
numbers = map show [1..]
fizzbuzz = zipWith max words numbers
Henney explains in detail in the video, but it makes use of lazy evaluation to create an infinite list of FizzBuzzes, and also uses no if statements. I find it intellectually exciting, but make no claims on readability
Most of the languages ideas I have aren't focused around syntax these days, rather about automating some tedious part of programming. Two that have stuck with me for a few years now:
1.) A language for plumbing. Basically, this is a mini-language for defining data structures and how they're shipped around different devices and processed. Think of protobufs or Apache Avro, but also including functionality like conditionals & flow control, rich collection operations like map/filter/fold, account & device management libraries, and most importantly, an Actor-based syntax (somewhat like Erlang) where entities like "The user's iPhone" or "The user's smartwatch" or "the database" just exist like process handles, and you can send messages to and from any of them. It'd then compile down into idiomatic Swift/Kotlin/Java/C/SQL to run on appropriate machine, so that your UI code just includes a library and you don't need to rewrite all your data plumbing, serialization, and business logic for each client platform.
2.) A language where you literally can use machine learning like if-statements. Basically it'd have functionality to dump out a feature vector (an array-of-structs), visualize it in a Jupiter notebook, label it (or send it off to Mechanical Turk for labeling), and then feed the labeled data back into any of multiple classifier types for use in an if-statement. Once trained, the model and training data would be checked in as if they were source code, and could be attached to code and versioned the same way that an algorithm would be. You'd run your program in two modes: in training mode, the program executes as much of the code path it can until it gets to an untrained classifier, then dumps out the data for that and starts the labeling/training process to generate the trained model. In execution mode, it uses the generated models to actually make flow-control decisions.
Doubtful I'll ever have time to implement either one of these, but at least at the moment, they're somewhat timely and don't have convenient solutions. I think syntax is basically a solved problem, and don't really care about it.
I would build around a constrained high-level concept. Something like actors, perhaps. It would be assembly-like, command-oriented.
I would then build a visualization environment which shows what the actors are doing, possibly step-by-step. It would show them moving values between registers and buffers. It would show messages passing between actors. It would show new actors create and finished actors die and errors get dumped into the canvas.
Your concept as an end-user would be that you're programming these automatons. You could clearly visualize what's occurring and debug control-flow or algorithmic issues by stepping through their movements.
Maybe not a great idea in the long run, but if it was a weekend lang jam, that's what I'd do.
2. Apparently there's going to be a theme? So that might make whatever wacky language I've been mulling a bad fit. I'm rather curious about how that will play out
Another "crazy" idea: I'd like the compiler to reformat code to match strict style conventions.
Why? Sometimes there's no "right" style. Sometimes novices need training wheels. In the long run, style doesn't matter, but in big projects code is easier to read when style is consistent. It's also easier to onboard when code follows industry-standard styles.
Would it be better when a language gently pushes everyone to the same style?
This has been a part of Go culture from the beginning. You avoid style conflicts because you just run everything through 'gofmt' before checking it in.
It's slowly catching on in other languages, eg. Clang now has clang-format and IntelliJ can auto-reformat your code according to a rule config you set before each check-in.
This is almost always a subjective opinion. I've worked on many projects where people reformat large portions of the codebase to make it "easier to read", and in the end they waste a bunch of time, make using `git blame` a pain, and subjectively either make no difference in code readability or make the code harder for half the team to read.
> I'd like the compiler to reformat code...
Why is this the compiler's job? Most people aren't reading code after it's been compiled. In most of the languages I've worked with, this is handled by a formatter + styleguide/config that either runs in the IDE on save or on a git hook, or both.
> Ever start a new job with a bulk of code you didn't write? Worse, ever take over code written by novices who ignore common conventions?
Yes, I have seen lots of this in scientific computing. However, things like too many/not enough spaces, line widths, etc, are never a huge hindrance for me.
What does make code "hard to read" are things like bad and inconsistent variable/function/class names, bad inheritance practices, bad file organization, and not adhering to common language idioms. That stuff is rarely, if ever, caught by linters.
That’s an idea I’ve been playing around with for my personal language. If I do decide to release it, I have a feeling there will be common style rules that will be required for any ‘library’ code (it would be like if C++ files had to meet google style guides to be posted to some central collection repo). I think the compiler could implement the conversion, but it could require a programmer supplied ‘translation’ file (like including Unicode to ASCII substitutions, or required macro unrolling to some language core set of language features). That would allow for anyone to keep there code formatted in the most logical way for them, but would allow for a common format for distribution. I would also think going the other way, from public style to private should be a possibility.
I don’t know if I will ever actually put my personal language out for release, but I’ve had two acquaintances repeatedly tell me (along with several HN commenters) that I really should at least release some blog posts about the language. Currently it is just my daily driver for work related programming and it compiles to C++, C, or JavaScript.
The usage of `unless` strikes me as unmaintainable and "smart", not in a good way tbh. The types are all other the places, too. What is it even doing exactly? Appending a string to a null value..?
Appending a string to an undefined value, via array addition, which turns them into strings but doesn't turn null into 'null' or undefined into 'undefined'. It's a bit of a hack.
As is it's just doing the first 100 iterations of fizzbuzz as either a number or text depending on the fizzbuzz step but not printing or saving anything. If you wrap it in a console.log() it'll create a 100 element array of objects which are the answer for fizzbuzz[index+1] and log them.
All that said I've never been a fan of dynamically typed languages myself. Fast to make things in but difficult to reason about later.
I think there's a lot of opportunity in the 2d domain, in both directions.
You might have a picture represent a program, like Piet [1]. Or you might have a language specifically designed to show certain types of pictures, like TeX or Processing or more narrowly, PlantUML.
Another area to explore is the distributed space. Perhaps a language with Kubernetes capabilities as first-class objects.
I'd like a language that makes it easy to mock and dependency inject without doing anything special.
IE, if in my business logic, I write "new Foo()", I'd like to be able to write a unit test where I say something like, "whenever I wrote 'new Foo()' swap in this mock object instead."
Or, in a module that's an entry-point, I'd like to say, "whenever I wrote 'new Foo()' swap in this subclass instead."
I've spent so much time refactoring to make code mocking and dependency-injectable.
Take a look at newspeak (smalltalk-ish, it avoids global references enforcing each component to receive dependencies as arguments, i.e. it has DI builtin) and NesC (C with components, which are composed at build time).
Neither is popular but they're pretty interesting!
I'm not sure I've ever seen a more readable compact fizzbuzz than this version in coffeescript