from Hacker News

DreamBerd is a perfect programming language

by Davidbrcz on 6/4/23, 7:07 AM with 208 comments

  • by gusmd on 6/4/23, 6:17 PM

    The best gem in all of it is this:

    > You can make classes, but you can only ever make one instance of them. This shouldn't affect how most object-oriented programmers work.

    This describes my experience with most OOP code very well.

  • by ravi-delia on 6/4/23, 4:26 PM

    This is incredibly good. It maintains the breathlessly approving tone of a language readme the entire time, it has incredible comedic timing (a lesser shitpost would have revealed that of course the file extension was .db right at the start), and it has incredible internal consistency. For some reason it was the fact that it demonstrates how "files" work by rebinding a const const that sent me completely over the edge. Or maybe it was the regex describing valid regex labels
  • by qsantos on 6/4/23, 7:27 PM

      Using the word 'DreamBerd' in your project name implies that the DreamBerd Foundation does not own your project.
      
      However, not using the word 'DreamBerd' in your project implies that the DreamBerd Foundation does own your project. If you would like to keep ownership of your work, please always use the word 'DreamBerd' in it.
      
      Here are some examples:
      white_check_mark DreamBerdScript (not owned by the DreamBerd Foundation - you are free to use this name)
      x ECMAScript (owned by the DreamBerd Foundation - please consider renaming)
      x Rust Foundation (owned by the DreamBerd Foundation - please consider renaming)
    
    Maybe the author should actually take over the Rust Foundation.
  • by humbugtheman on 6/4/23, 5:05 PM

    Hello! Creator here. This is an open-source project so please do submit any issues or PRs.

    Please note: I will close any issues without unreproducible steps.

  • by gpderetta on 6/4/23, 9:30 PM

    > Technical info: Type annotations don't do anything, but they help some people to feel more comfortable.

    They stole the feature directly from python!

  • by stevage on 6/5/23, 1:27 AM

    >If you're unsure, that's ok. You can put a question mark at the end of a line instead. It prints debug info about that line to the console for you.

    Man, I love this idea. Imagine if in JavaScript, you could just add a `?` to a line to print out the value of all variables and expressions referenced. Or `?` on a line by itself to print out the value of all variables in scope.

    > DreamBerd has significant whitespace. Use spacing to specify the order of arithmetic operations.

    I might be mad, but this seems...almost...useful?

  • by tuchsen on 6/4/23, 4:09 PM

    This is great. Usually with the joke programming languages, you can get at least one person arguing that "x feature" really isn't all that bad, or could maybe be useful. DreamBerd beats them all in that regard. It is 100% terrible! I lost it at the lifetimes implementation.
  • by jantypas2 on 6/4/23, 9:03 PM

    And of course, let's adopt Rust's logic with our new "Borrow Nagger", or just "Everything Nagger". When it compiles your code, it analyzes it, sends it out to a Reddit group and collects the comments and displays them as warning and error messages. No one is saying they'll make any sense relative to code, but if you've used C++ and templates, you'll feel right at home. Abd of course, there's "syntax quality hightlighting", where we highlight your code in various colors based on what we think of the quality of it. Red = Really bad idea, Yellow, not good, but good for now, you'll refactor it later, green, good because you won't be at this job long anyway, and black on black or white on white if it's actually OK. (Per the comment on refactoring, there's probably a note on the pyramids 'Pharoh - yeah, this is a hack, but we were in a rush, we'll fix it later. Bandaids for now'
  • by pmontra on 6/4/23, 4:55 PM

      const var scores = [3, 2, 5]!
      scores[0.5] = 4
      print(scores) //[3, 2, 4, 5]!
    
    Genius! This trivially solves the problem of reading integer and floating point numbers from input and inserting them into a sorted array. Too bad there are no loops in this language.

    (Remember that arrays start from -1.)

  • by zeptonix on 6/4/23, 4:35 PM

    Delete

    To avoid confusion, the delete statement only works with primitive values like numbers, strings, and booleans.

    delete 3!

    print(2 + 1)! // Error: 3 has been deleted

    HAHAHAHAHA

  • by pledess on 6/4/23, 10:15 PM

    I feel that the array starting index should be adjustable at runtime via increment/decrement overloading for either the [ or ] character.

    var var meanings = [42]!

    print(meanings[-1])! //42

    [++! //temporarily change to 0-based indexing

    print(meanings[0])! //42

    print(meanings[-1--])! //42 (because of the --] pre-decrement)

  • by jantypas2 on 6/4/23, 4:50 PM

    Please no! Someone may try to actually use this in some corporate production model -- I can see the carnage now - the language, editors where you can write left to right, right to left, or even vertically with an exta cost plug-in, training courses at $1500/day -- the horror of it all! Don't forget the vertical camelcase variable names where letters appear, not only in both cases, but on two lines. You know of course, tehre's a special place for you when the mist clears. You'll either be stuck in the Bank of America customer care department for eternity, or, be stuck in the other Big Red helping to get Larry Elisson's network computer workig -- FOREVER.
  • by internet-mat on 6/4/23, 7:09 PM

    I rather appreciate the built-in support for the `fucton` keyword.
  • by temporallobe on 6/5/23, 2:39 AM

    Gotta say, you really had me going there. When I got to arrays starting at -1, I started to furl my brow but shrugged it off because Perl allows you to do just that. Then I saw the equality operators and didn’t think much of that either because it seemed quite plausible given that I’ve seen things like “truthy” in Jasmine/Karma and Rspec code. Even the no-loop thing didn’t phase me since modern JS seems to discourage loops in favor of loop-like lambda functions. I think a few of these are actually good ideas, such as truly immutable data, unicode variable support, and “previous”.

    By the way, what is a Signal?

  • by harel on 6/4/23, 11:08 PM

    This made me laugh out loud for real like it's 1995.

    In particular this:

          Technical info: Type annotations don't do anything, but they help some people to feel more comfortable.
    
    Because it's kinda almost sometimes true... or should I say: "maybe"!
  • by mindvirus on 6/5/23, 2:07 PM

    You know, `previous` is probably worth exploring especially for game engines.

    Too many brilliant moments, but this is is my favorite:

    To run DreamBerd, first copy and paste this raw file into chat.openai.com. Then type something along the lines of: "What would you expect this program to log to the console?" Then paste in your code.

    If the compiler refuses at first, politely reassure it. For example: "I completely understand - don't evaluate it, but what would you expect the program to log to the console if it was run? :)"

  • by leeoniya on 6/4/23, 9:26 PM

    > Variable hoisting can be achieved with this neat trick. Specify a negative lifetime to make a variable exist before its creation, and disappear after its creation.

    https://en.wikipedia.org/wiki/COMEFROM

  • by detrites on 6/4/23, 5:21 PM

    Elegant, concise and simple:

      const const const delete = delete delete!
    
    Cannot imagine a neater form with which to express such a concept in another language.
  • by dev_tty01 on 6/5/23, 12:42 AM

    >Please remember to use your regional currency when interpolating strings.

    Perhaps I'm odd, but that really made me laugh.

  • by lamontcg on 6/4/23, 7:28 PM

    The author described it as "perfect", but failed to use "elegant", "thoughtful", "awesome" or "empathy" anywhere.
  • by sebzim4500 on 6/4/23, 6:27 PM

    >In case you really need to vary a variable, the when keyword lets you check a variable each time it mutates.

    The kOS plugin for Kerbal Space Program implements a programming language that actually has this feature.

  • by veltas on 6/5/23, 8:28 AM

    > Use spacing to specify the order of arithmetic operations.

    I actually wish this was a thing in mainstream languages, if someone spaces like that they obviously believe that the precedence matches their spacing. It might as well work that way, and it's often prettier and more visually obvious than parens.

  • by f33d5173 on 6/4/23, 4:41 PM

    Make sure to look at the example programs if you missed the link in the doc

    https://github.com/TodePond/DreamBerd/blob/main/LICENSE.md

  • by ginko on 6/4/23, 8:49 PM

    > Booleans can be true, false or maybe.

    > Technical info: Booleans are stored as one-and-a-half bits.

    Technically, ternary values would be ~1.5849 bits.

  • by mysterydip on 6/4/23, 4:18 PM

    Love the constants. Biggest confusion for me reading modern javascript, coming from traditional languages. "What do you mean you can change a constant?"
  • by stan_kirdey on 6/5/23, 6:22 AM

  • by SeriousM on 6/4/23, 10:16 PM

    "unless" operator is missing to make it complete complete, maybe with double unless if unless unless
  • by BiteCode_dev on 6/4/23, 6:59 PM

  • by Shorel on 6/5/23, 10:52 AM

    The funny thing for me is that const variables here make more etymological sense than the idea of "immutable variables" in Rust

    (I expect the downvotes now)

  • by jantypas2 on 6/4/23, 5:01 PM

    A correction on another comment -- this is not a multithreaded language -- it's transthreaded-- a radically new concept where your code may or may not, run code in your thread, or someoen else's thread, without your knowledge. Errors in your code show up in their program, and their errors, in yours - see? Now bugs aren't your fault anymore! And don't forget the KvetchGPT option. It's doesn't so much as complain about your code as you go along. It's like pair programming with your manager but you can turn them ofF.
  • by freilanzer on 6/5/23, 8:12 AM

    > If you're unsure, that's ok. You can put a question mark at the end of a line instead. It prints debug info about that line to the console for you.

    > print("Hello world")?

    That is great, though.

  • by renonce on 6/5/23, 6:18 AM

    > Technical info: Booleans are stored as one-and-a-half bits.

    No you can’t store three choices in one-and-a-half bits. Two booleans would be 9 choices whereas 3 bits can store only 8 choices.

  • by Semaphor on 6/5/23, 2:49 AM

    I accidentally clicked on this (thought my pointer was on another monitor …). Am I glad I did. Originally I just skipped it because it sounded too clickbaity :D
  • by shevis on 6/4/23, 8:47 PM

    > Loops are a complicated relic of archaic programming languages. In DreamBerd, there are no loops.

    Flex

  • by sicariusnoctis on 6/5/23, 7:25 AM

    Ideally, arrays should start at 0.5 -- that is the best compromise.

    Or maybe start with 0.25, since starting with 0 is three times better than starting with 1.

  • by slim on 6/5/23, 5:33 AM

    This is so good, it could be used as a list of riddles for programmers.

    Dividing by zero returns undefined

    it took me a few minutes of thinking before finding why it's wrong

  • by jancsika on 6/4/23, 9:34 PM

    > Variable hoisting can be achieved with this neat trick. Specify a negative lifetime to make a variable exist before its creation, and disappear after its creation.

    It'd be neat if you could also hoist a var up into the set of extant running runtimes.

    Oh, someone on earth already computed a table of rsqrt values. Let me try just try using that one...

  • by nirui on 6/5/23, 3:03 AM

    Although my overall liking, I still found the use of exclamation mark a bit troubling since it promotes some very odd attitude that might anger our future AI overlord.

    Maybe it's a good idea to add `please` statement so the our computers can choose to execute our humble plead whenever they feel generous?

  • by jantypas2 on 6/5/23, 11:58 AM

    Per the whoe whietspace idea -- techniaclly not a feature, just a policy statement. "This language has chosen manditory tabs at three spaces. It's not that this is better than anything else out there, but we gave you all a choice and you couldn't make up your minds, so as your mother would say, this is what it's going to be! Be happy we let you have this!" Also, on style, all code must be in capital letters -- comments are in mixed or lower case. That way you can easily tell wehre actual code is. Every line, and we mean EVERY line must have a comment. If you don't add one, WE WILL. Granted, it may not mean anything but no one reads them anyway?
  • by divan on 6/4/23, 8:10 PM

    So many promising ideas for Dart 4.0 to adopt :)
  • by jantypas2 on 6/4/23, 9:17 PM

    And now that I think about it, other than negative lifetimes, where variables reappear in code after a defined time because you might need them again, I propsoe the hidden segments feature -- with this feature, you can write code, and hide the block (something like an invisible #define) so when your coworker comes along and tries to "help" by changing your code that you told them SHOULD NOT be changed because it actually works now, when you run the code with the --no-manager flag, the code compiles the way YOU want it.
  • by MrLeap on 6/5/23, 6:16 AM

    There's a ton of really good ideas here. Defined lifecycles? Fun! That when keyword? I like it more than the += and -= syntax for event handling in C#!
  • by threeseed on 6/4/23, 8:37 PM

    It really is missing some functional programming paradigms.

    Something that makes (a) you appear smarter than other developers and (b) your code so complex it is unmaintainable.

  • by dmytrish on 6/4/23, 9:23 PM

    How many billion lines of code does it compile per second?
  • by quickthrower2 on 6/5/23, 1:49 AM

    The when feature looks genuinely useful. Shame on you! But in another language an event listening on variable change privative would be pretty cool.

    In JS you could then replace

    [x,setX] = useState(0);

    with

    x = 0;

  • by sorokod on 6/6/23, 1:45 PM

    "you can use any letters from the word function"

    the examples miss the perfectly cromulent 'unction'

  • by guenthert on 6/4/23, 10:07 PM

    > All indents must be 3 spaces long.

    That's what a former colleague, who shall remain unnamed, suggested as well.

  • by throwaway290 on 6/5/23, 9:30 AM

    Except for copilot section that equates open source with LLM-ingestible it's quite funny
  • by ajuc on 6/5/23, 7:32 AM

    Ok, this got me.

    > Please remember to use your regional currency when interpolating strings.

  • by stan_kirdey on 6/5/23, 6:26 AM

    It does give vibes of a new language that was developed in a bloated enterprise, only during the 10 minute intervals of brainstorming meetings scheduled bi-weekly on 3PM, Monday, Tuesday and Wednesday.
  • by 1attice on 6/4/23, 7:49 PM

    Please send for help. I have rubbed off my face with the palms of my hands.
  • by armchairhacker on 6/5/23, 3:39 AM

    DreamBerd's features in real-world languages I've heard of or used, I may have missed some in Perl, Ruby, PHP, and others:

    - Exclamation marks: behave like semicolons in most language (extras are allowed). In some languages like Ruby and Lisps, convention is to put exclamation marks at the end of mutating functions, and question marks at the end of predicates

    - Declarations: C++ has constant variables and pointers, like `const int * const x`. JavaScript has `const` which lets you mutate the variable, and TypeScript has separate `const` and `readonly`.

    - Naming: Lisps let you put punctuation in names, and see https://codegolf.stackexchange.com/questions/28786/write-a-p...

    - Arrays: Lua and R have 1-based indexing and R coerces float indices to integers, though JavaScript's interpretation is arguably even worse (https://stackoverflow.com/a/6649444)

    - When: Unless you count setters and reflection magic, (un)fortunately the only example is the joke language INTERCAL

    - Lifetime: These aren't anything like Rust's lifetimes

    - Installer: Some languages used to have bad installations but I believe this is mostly fixed now. But difficult project configuration is still a thing (nodejs bundlers, CMake, Gradle), as-is create-foo-app

    - Loops: Loops don't technically exist in pure functional languages like Haskell (though `forM_` is basically a loop), and other functional languages like ML and Scheme usually discourage loops. Instead there is recursion

    - Boolean: Applies to any language with implicit `null` and `undefined`. I'm sure JavaScript and even TypeScript devs have encountered actual bugs caused by a bool which was neither `true` nor `false`. Even languages with explicit null you'll occasionally see `Option<bool>`

    - Arithmetic: I've never seen this feature, which is actually kind of sad because I actually kind of like it (not enough to give `+` priority over `*` though).

    - Indents: No languages, but I've had my IDE suggest 3 idents when it got screwed up (e.g. newline and there is a space after my cursor)

    - Equality: Taken from JavaScript. Some languages like C++ and Java also have `==` which you don't always want

    - Function: I know there are languages which let you declare keywords with shorthand but I can't remember which ones, only certain command completions (e.g. `npm i` for `npm install`). I do know there are languages which let you omit syntax like HTML closing tags (which comes later) and languages which have the same syntax with extra keywords for legacy reasons (SQL)

    - Dividing by Zero: Is literally undefined behavior for integers in some languages like C, and literally undefined in actual math. Otherwise, in every language I'm familiar with it either returns NaN or infinity (for floats) or throws an exception

    - Strings: Lua and JavaScript let you use single and double quotes, Python lets you use triple quotes, many languages have quasi-quotes for interpolated strings, and some languages let you use arbitrary delimiters like Racket (https://beautifulracket.com/explainer/stringlike-types.html#...)

    - String interpolation: Most languages use ${}, Swift uses \(), some use just {} or #{}

    - Types: C, Haskell, Java, and JavaScript treat strings as an array of characters (even though UTF-8 strings technically aren't), and Scheme and Haskell have arbitrary-precision numbers as the default. Python and TypeScript type annotations don't always work and aren't fully checked, as are Typed Racket's but Typed Racket is getting better at this

    - Regular expressions to narrow string values: Not arbitrary regular expressions, but TypeScript's template literal types are close (https://www.typescriptlang.org/docs/handbook/2/template-lite...). Different languages and libraries name their regular expression type Regex, RegExp, and Regexp

    - Previous and next: None. Though after does exist in a way (`defer` in some langauges)

    - File structure: None, except Java requires one class per file, and most languages enforce that file structure matches package structure although some don't (e.g. TypeScript)

    - Export: None, most languages let you control exports with either `export`, visibility modifiers, or separate header / implementation files, though some don't let you control exports at all and only "suggest" with underscores (e.g. Python). Rust even lets you set visibility to certain crates, which is a bit like DreamBerd's `export`, except only limited to super-crates because you must ensure that your symbol is visible in the create it's defined

    - Class: Almost every language has classes, though some languages like Rust and Haskell have typeclasses which are different than OOP classes. The exceptions like C have "ad-hoc" classes for large projects, and ML has modules which are like classes but explicit (although OCaml has classes too!) Every language lets you create multiple instances of classes, but singletons and the factory pattern are very common in Java and also sometimes C++.

    - Now: `Date.now()` is literally defined, in most languages, and nearly every language will let you get the current time in some way (even if behind a monad)

    - Delete: `delete` and its equivalent let you delete quite a lot. In R you can delete local variables and then they will no longer be defined; you can delete keywords because they're actually functions which use R's weird evaluation rules; and you can access environments of other functions and delete their local variables, causing the function to break with "`x` not found". See this (https://stat.ethz.ch/R-manual/R-devel/library/base/html/rm.h...), which even has "remove everything in the global scope" as an example

    - Overloading: Name shadowing is possible in most languages, and Rust lets you shadow variables directly like in the example. Personally I like this though, because 99% of the time when I redefine a variable with the same name, I intend to no longer use the old variable.

    - CSS also has the `!important` rule which lets you prioritize overloads, and with nested selectors almost resembles DreamBerd's `!` prioritization.

    - Signals: In JavaScript and they are quite confusing, The split function version (`getFoo()` / `setFoo(newValue)`) is in React useState and Solid.js, and the `value` setter with implicit getter (`foo.value` or `foo` in JSX, `foo.value = newValue`) is in preact. I believe the single function version (`foo()` / `foo(newValue)`) is in some library but I'm not sure which, I do know `setValue` can take a function with the previous value.

    - AI: Automatic semicolon insertion is in JavaScript, and automatic closer insertion is in HTML. Most modern languages convert automatic insertion into syntax errors with quick fixes

    - Copilot: If you write a more esoteric language like Coq, Copilot won't really understand your code either. Though it will understand the syntax and common parts, only suggestions will be worse than usual

    - Ownership: The Rust foundation had a fiasco with their trademark proposal, though they've apologized and hopefully it's not going to be an issue in the next proposal

    - Compiling: Most languages can compile most programs. However C++'s parsing is literally undecidable (https://blog.reverberate.org/2013/08/parsing-c-is-literally-...), as is TypeScript's type system (https://github.com/microsoft/TypeScript/issues/14833).

  • by keyle on 6/5/23, 1:12 AM

    I love the compiling section. What an efficient way to handle a compiler.
  • by tbt on 6/4/23, 4:35 PM

    Regexression
  • by eternityforest on 6/6/23, 6:53 AM

    This is the best new language since poop!
  • by dawidloubser on 6/7/23, 10:40 AM

    This is hilariously brilliant. Thank you for almost killing a fellow engineer through laughter.
  • by jpease on 6/5/23, 3:01 AM

    I always exclaim “bang” at the end of every line of code I write, so feels natural to me. Emeril has his bam, so why not?
  • by nuancebydefault on 6/4/23, 7:33 PM

    I find DreamBerd to have the perfect antidote to all the constexpr/const fetish in that other, non-perfect language.
  • by wkjagt on 6/5/23, 10:57 AM

    This is wonderful. I love the tests also.
  • by 11235813213455 on 6/4/23, 7:35 PM

        scores[0.5] = 4
        print(scores) //[3, 2, 4, 5]!
    
    should be [3, 4, 2, 5] imo, between 0 and 1
  • by revskill on 6/4/23, 4:45 PM

    Is this to blame complexity of Rust ?
  • by b33j0r on 6/5/23, 12:19 AM

    I’m converted! Well, I’m const var convinced, not quite const const const.
  • by therouwboat on 6/5/23, 9:29 AM

    This is like a horror story, I'm afraid to see what comes next. :o
  • by jheriko on 6/4/23, 6:46 PM

    could have made a language faster than C in 0.1x the amount of time
  • by rootw0rm on 6/4/23, 5:02 PM

    Oh wow, this is awesome
  • by nxpnsv on 6/4/23, 5:02 PM

    Lu makes awesome stuff, do check out todepond on youtube
  • by Alifatisk on 6/4/23, 7:39 PM

    Great repo, had a good laugh through the whole readme!
  • by genevra on 6/5/23, 12:27 AM

    this is hilarious