Threads for hc

  1. 1

    Not a game developer myself, but have friends who are and it sounds like Unity is taking hits from competing engineers, also because evidently Unity tends to have long standing big bugs, making especially 2D focused people go to Godot and other open source engines.

    At least that’s what I’m hearing about, being on the the outside. Wondering if that’s just anecdotes by friends or whether Unity does in fact have a rough time. Any game devs here sharing similar or opposing views? Also how do asset stores for into all of these?

    Also I guess together with exporting to wasm, I wonder whether that’s a good trend for more niche operating systems that are being used at a desktop. After all that’s at least something that could theoretically be portes or one could add targets for.

    1. 1

      i used unity for 6 or 7 years, before moving away from gamedev

      they definitely do leave bugs and unpolished features around. rather than improving an existing component, they’ll often add a new one. so, you’ll have 2 or 3 different ways of doing UI, for example they kept the same out-of-date version of mono for almost the entire time i used the engine

      that said, i think it would have been a mistake to use anything other than unity for just about any new game (unreal may be a better choice for a FPS or similar. lighting and character controllers seem better with less setup)

      the component model (which they also have 2 versions of now, lol), not-awful scripting language (C#), asset store, building for just about every relevant platform, and editor scripting make it flexible and save a ton of work

      it can be frustrating day-to-day, but i think the risk of showstopping bugs/missing features is (was) lower than the others

      1. 1

        Cool to get a different view. Said game devs actually switched from Unity to Godot for the component stuff it seems. I don’t remember exactly if they use C# or their scripting language, but says that it was fine. But yeah the big thing for them was certainly being able to get hands dirty fixing issues they had with the engine.

        I think they do just assets in house but asset store appears to be Unity’s biggest feature so I have one more question. How are things in the asset store in terms of compatibility, between versions, but also platforms and personal projects. Is that something that can be an issue or is that a more rare thing?

        Just curious what the life of a game dev really is regarding day to day tasks.

    1. 4

      i’ve written tools with a --wet-run flag :)

      (co-worker made me change it to --dry-run=false)

      i think the destructive mode should be harder to type

      1. 5

        --in-anger!

      1. 3

        i threw tutorial 3 through image diff, and it’s literally the same picture

        i feel like i’m at a wine tasting event

        (https://cantunsee.space/static/media/T22.cee961a1.png, https://cantunsee.space/static/media/T21.51a7913d.png)

        1. 7

          The left chat bubble juts to the right quite a bit, past the text it should be enveloping equally on all sides. You might want to adjust the contrast on your monitor.

          1. 3

            it was contrast

            anything above ~5% on the slider in osx, and the left text doesn’t have a bubble around it at all

            (forgot i increased it when trying to use my laptop outside. everything looks dull and grey now that it’s back to normal, until my eyes adjust)

          1. 3

            Reminds me a lot of intense improv experiences. The mild-meld in those are surreal.

          1. 6

            Definitely one of the better books I’ve read on programming. Much recommended. The chapter with Fran Allen made me realize that what we find so natural now in terms of how languages are designed (even very low level languages), really is just an accident of history, and that maybe we aren’t doing it right.

            There’s this overemphasis on reusable software where you never get to open up the box and see what’s inside the box. It’s nice to have these black boxes but, almost always, if you can look inside the box you can improve it and make it work better once you know what’s inside the box. Instead people make these closed wrappers around everything and present the closure to the programmers of the world, and the programmers of the world aren’t allowed to diddle with that. —Donald Knuth

            I like this quote (from the blog post). I know he’s talking about something else, but it made me think of Julia’s multiple dispatch (I don’t use that language, just saw a talk on that particular aspect), and Rust’s trait system. At least for the trait system, it feels like you can put in little places in the code where you allow the users of the code to define their own exact behavior that suit their needs. To me, despite having the strictest type system I’ve ever worked with, it feels much more open than say JavaScript or even Python because of this.

            1. 2

              something else, but it made me think of Julia’s multiple dispatch (I don’t use that language, just saw a talk on that particular aspect), and Rust’s trait system

              I don’t think they can match Literate programming which is a white box. Fun fact - the writers of this book written using literate style garnered a 2014 oscar for technical excellence.

              1. 1

                this is the first time i’ve seen literate programming with out-of-order code blocks meaning, it’s more than just swapping the comments and the code

                thanks for pointing to that book!

            1. 1

              re: conway’s law

              i think you can work around this to some extent:

              • have more components than people (an order of magnitude or so?)
              • avoid “utils” and other catch-all dumping grounds
              • have your components be searchable

              you’re still going to get libraries/tools/etc. that follow org structure, but you can get a lot outside of that structure too, and that’ll be more reusable

              1. 2

                Why work around it? Isn’t the purpose of Conway’s Law to accept the inevitable rather than fight it?

                FWIW I’ve worked in an environment that follows your suggestions and it still followed Conway’s Law.

                1. 1

                  Yes. This goes beyond software, too. The way to exploit Conway’s law is to shape the organisation after the system you desire to build. This implies things like smaller, cross-functional teams* with greater responsibility (in order to get less coupling between system components). That way you maximise communication efficiency.

                  * Lean people would advocate that the team should be co-located too. The idealist in me still clings to the Microsoft research that showed org chart distance mattered orders of magnitude more than physical distance.

              1. 21

                I feel such a deep sense of catharsis seeing someone write out a takedown of that unbelievably terrible talk that people keep linking to.

                Copy a program from one computer to another.

                ah so here where the author says nobody does this any more, I agree that nobody does it very much but argue that it’s not actually that hard (in Go, not sure on other stacks but should be easy in Rust?) and totally worth your time to do. I work at a game company and sometimes when people need small tools to do something, I just write a 30-40 line Go program in a single file, compile it to a binary and literally DM it to them on Slack a few minutes later. I do this every now and then, usually to make a one-off .exe file that I can give to a QA person to generate a given API request that they can fill with command-line variables, or download/upload a file or file tree, or perform some form of file transformation, data abstraction, or templated file generation. One of our engineers was having problems with a low-level websocket client written in C running on a PlayStation and I made a websocket server for him in Go that could test his specific websocket protocol implementation problem in about 30 minutes and DM’d it to him on Slack. (of course, it turned out the problem was one of our own doing.) Very little ceremony, lots of utility. Making little binaries and sending them to people on Slack is wonderful and people should do it more.

                we basically have to go back to the days of the C64 and PC/XT to find self-contained programs that didn’t require installation

                That’s sortof a choice that people are making though. A friend of mine, a game designer, decided to stop using Maya and start using Blender instead because Blender is so small and self-contained, she can put it on a thumbdrive. She puts a whole 3D modeling kit onto a thumbdrive and then puts it in her pocket and uses it at home, at grad school, and at work. And she even readily admits that it’s not as good of a modeling program than Maya! But her games are small and she doesn’t need all of Maya’s features (and doesn’t have a license for it at home), so it’s more ergonomic for her to just stick Blender on a thumbdrive. She’s not a professional 3D modeler, and I doubt this workflow would work for someone that is a dedicated environment or character artist, but it works for her workflow as a designer.

                Godot also has a similar setup; you just download it and run it. The engine and the editor together are just an executable. It’s fantastic.

                AppImage on Linux is a similar thing. I do all of my image editing in Krita, which is packaged as an AppImage so looks to me like it’s just an executable file. (yeah, not as good as Photoshop, duh, but convenient and free and I’m not a professional artist so don’t really need the things that Photoshop has that krita lacks.) Overall, the situation here is much better than both Blow and the author are claiming, although it is still far behind where it really could (and should) be. MacOS has .app files that behave the same way. It’s really only Windows that lacks such packaging facility to my knowledge.

                I’m not exactly sure I follow Blow’s train of thought here - perhaps he reasons too much like a game developer and I don’t.

                honestly I don’t think he does. 90% of the gamedevs I know think that Blow is a has-been jerk, but I don’t and have never worked in AAA so I’m certain that the gamedevs I know are not a representative sample; my gamedev world is admittedly very tiny. It really seems to me like people outside of games think that Jonathan Blow is a paragon of gamedev because he told them he is, and people in games mostly roll their eyes at him.

                1. 6

                  Blow is a has-been jerk, but I don’t and have never worked in AAA

                  There are so many different kinds of subcultures within gaming. If you look at the games like Braid and The Witness, I think they are more interesting than the average game. Does that mean they are the best games ever? No, and it depends who you ask, of course!

                  One reason that I like Blow, is that he seems to be one of the most prominent accomplished devs who isn’t just going with the flow. No flow with Blow. Like, that new programming language that disregards any PLT research of the last 50 years: I probably won’t use it, but I am happy he is out there, experimenting.

                  I don’t think people would realize, to the same degree, that yes, you can write your own game engine, if he wasn’t using his prominence like this. I value clean engineering, so I think that message is way more important than the message of Unity which is probably something like “you can get a pretty game in no-time with us”. I don’t want “pretty”! I want innovation.

                  I don’t understand why you mention AAA, since Blow is not a AAA dev, and it doesn’t make sense to compare him to one. What did you mean?

                  1. 6

                    I’m more interested in innovations in gameplay than I am in the engines running games. I don’t care whether the innovative game uses Unity or Fusion or Game Maker. I’m not playing a game for its clean engineering.

                    1. 7

                      I don’t understand why you mention AAA, since Blow is not a AAA dev, and it doesn’t make sense to compare him to one. What did you mean?

                      ah I just mean that if you asked AAA game devs they might like him. I don’t know many AAA game devs.

                      Unity has never made the promise that they’re pushing the performance of games, but that they are pushing the medium to be accessible to a larger set of creators. I’m not arguing that there are no benefits to writing your own engine, but that innovations in game engines and innovations in games are two completely different things. Besides, have any developers other than Jonathan Blow created great games with his game engines? Hmm.

                      You can make an innovative game without innovating in the engine. A LOT of people just want to make a game with existing concepts of controls and rendering, but with different art assets, different stories, different levels, different themes, etc. The reality is that if you look at the set of people who want to make games, the vast majority of them are not in it with the goal of making a game that is pushing some technical envelope, but because they want to push some creative or expressive envelope. A lot of people simply want to make a game that tells a story that they haven’t seen told in a game before. I’m one of two professional programmers in my game design MFA program and not a single one of the ten other designers in my program cares at all about making games that are innovating in the game engine space or expresses an interest in learning about pushing things technically, because existing game engines and technologies already provide a design space that is so enormous that we have barely begun to explore it. Honestly most of them care much more about innovations in either narrative structure, spatial structure (i.e. level design), or aesthetics. Very few people care much about innovations in mechanics, and none care about making technical innovations. Technical innovations in games is just one area of design exploration out of many.

                      also Braid is boring to play and deeply problematic on a thematic level, I’m sorry. Limbo and INSIDE are ten times the experience Braid is if you want an indie platformer with an interesting narrative context. Starseed Pilgrim, Rain World, Thomas Was Alone, and Celeste all stand out as having more to say in that space to me, too. The Witness has a large number of puzzles but so do those books of sudoku puzzles you can buy at an airport book store. Who cares. Those books admit they’re all variations on the same puzzle, and the line-drawing puzzles are also all in the category of constraint-fitting puzzles. Those puzzles don’t even have any state in them. It’s just “find the correct line”. Wow. Amazing.

                      Mind you, I don’t think The Witness is without merit; I’ve logged 38 hours on it and think it’s one of the most beautifully rendered environments I’ve explored in games. But the real innovation of The Witness, and the reason that game designers talk about it, is that he hired an architect to help design the environment, and the environments are incredible. The fact that The Witness is written in its own engine is not a thing that game designers talk about or care about. Do players actually care? I doubt it. One wonders how much in the game could not be created in Unity or Unreal. The color puzzles would probably be impossible without having control of the render pipeline, but that’s a tiny portion of the game (and imho they’re some of the least interesting puzzles in the game). The first-person puzzle game that everyone actually cares about is Return of the Obra Dinn, a game that -also- has interesting rendering stuff going on that the game dev writes about a lot. The difference is that Lucas Pope is not a huge condescending jerk about it. Manifold Garden, Proteus, Stanley Parable, Antichamber, and Superliminal are all doing things as interesting or more interesting than The Witness in that space. So really, the idea that Blow is some sort of singular genius doing things that aren’t being done in game design is not actually true. There are loads of great game designers out there.

                      The thing I’m not trying to get at here is that Jonathan Blow is a terrible designer that makes terrible games, because I don’t think that he is. Braid is imho mediocre to bad, and The Witness is quite good. What I find so aggravating is that in this space and in other programming spaces, programmers all too often portray Jonathan Blow as being The Definitive Game Designer, when in game design spaces, that’s not at all the case, and I am exhausted of seeing programming communities fail to recognize other people making other innovations in games, many of which are much more profound and sublime than what Blow is doing.

                      1. 4

                        deeply problematic on a thematic level, I’m sorry.

                        How so? I saw it as unsympathetic to the player character— a nice departure from what I thought was gonna be “nice guy” bullshit.

                        And to the point on innovation in engines not mattering, look at factorio. The devs have said that the game wouldn’t be possible on unity or unreal, it would just be too slow. When I play factorio and there’s no slowdown on my massive, multiple location factory, I think that’s pretty cool.

                        1. 6

                          to the point on innovation in engines not mattering

                          I am literally not making that argument and I said as much up front:

                          I’m not arguing that there are no benefits to writing your own engine

                          My argument is not “no innovations in game engines are interesting”, my argument is that “the engine is not the only site of innovation”.

                          Despite Blow’s intentions, I don’t think that Braid is at all unsympathetic to the player character. I think the game is deeply sympathetic to the player character. You don’t give him that cutesy tousled hair or put him in that nice little suit if you’re not depicting him sympathetically. You don’t go through pains to show his perspective if you’re not depicting him sympathetically. You don’t put all of that outrageously bad writing into the game if you’re not being sympathetic to that character. You don’t make that character the center of the entire narrative if you’re not sympathetic to that character. At the end you find out he’s done a bad thing, but really, if you were at all paying attention to the story unfolding, the fact that it’s a story of an abusive partner rationalizing their abuse is clear the entire time. How much time is spent on the perspective of the other party? Any story that centers the thoughts and experience of the abuser, while relegating the thoughts and the experiences of the abused party to a status so minor as to be ornamental, is sympathetic to the abuser, regardless of whether or not the creator intends it as such.

                          see here for a longer viewpoint on this: https://boingboing.net/2015/07/30/the-other-side-of-braid.html

                          Why did it take so long for your protagonist to come to this revelation? It’s as if the whole game is constructed around trying to find ways to exonerate Tim’s wrongdoing. Look at all the stuff he’s done, and how smart he is! It’s the most common argument made for successful artists and thinkers who have done bad things throughout history. The game’s true hand is only revealed, and only barely, at the end.

                          1. 3

                            My argument is not “no innovations in game engines are interesting”, my argument is that “the engine is not the only site of innovation”.

                            Right, what’s all this then?

                            The fact that The Witness is written in its own engine is not a thing that game designers talk about or care about. Do players actually care? I doubt it.

                            My point is that in the case of factorio, players do care. And game designers should look at factorio and how great everything works and think “what could I do that’s innovative if I can make everything work fast?”

                            You don’t go through pains to show his perspective if you’re not depicting him sympathetically.

                            Sorry, what? This doesn’t follow in the slightest. Do you think American Psycho is sympathetic to Bateman?

                            Any story that centers the thoughts and experience of the abuser, while relegating the thoughts and the experiences of the abused party to a status so minor as to be ornamental, is sympathetic to the abuser, regardless of whether or not the creator intends it as such.

                            I disagree, insofar as a text isn’t “sympathetic” to anything, ever. It’s certainly possible to misread Braid in that way, but what would you prefer? A big, flashing red all caps impact font “YOU ARE A BAD GUY, DON’T DO THIS IRL” message at the start of the game?

                            I’m not going to read that review as the only good review of braid has already been produced: https://www.youtube.com/watch?v=xSXofLK5hFQ.

                            1. 7

                              “I don’t think The Witness being in a custom engine is a thing that matters to people who play The Witness” is not saying “no innovations in engines are interesting or observable to players”. To equate the two is ridiculous. To extrapolate this to Factorio is even an even more ludicrous act of moving the goalpost.

                              Do you think American Psycho is sympathetic to Bateman?

                              Haven’t seen it so I wouldn’t weigh in on that one.

                              if you’re just straight up admitting to refusing to engage the materials supporting my arguments, you’re openly acting in bad faith.

                          2. 3

                            look at factorio. The devs have said that the game wouldn’t be possible on unity or unreal, it would just be too slow

                            they do say that, but i’m not really sure i believe it

                            you’d probably have to make some tweaks. but cities: skylines is written in unity, and it has a similar problem of simulating a lot of stuff. i was looking at the decompiled code for it, and they wrote a lot of their own data structures instead of using the default C# ones, for performance reasons

                            (it’d also be easier now with unity’s burst compiler. but that didn’t exist when they started)

                        2. 3

                          I value clean engineering, so I think that message is way more important than the message of Unity which is probably something like “you can get a pretty game in no-time with us”. I don’t want “pretty”! I want innovation.

                          Why is a binary built up here?

                          1. 1

                            You’re right, I shouldn’t be building it. I just find that one big problem is that everyone is expecting so much from graphics nowadays. It’s not necessarily either-or, but usually if you want people to deemphasize something, something else has to go. Does that make sense?

                            1. 2

                              I just find that one big problem is that everyone is expecting so much from graphics nowadays.

                              You’re entitled to your preferences, but what does that have to do with the broader population? Tastes change. I’m pretty sure chess, checkers, Go, and Shogi players around the world are lamenting how more folks these days are interested in League of Legends than their games.

                              It’s not necessarily either-or, but usually if you want people to deemphasize something, something else has to go. Does that make sense?

                              It makes sense, but carries quite a lot of assumptions, namely that there is some finite resource that is “zero sum”, I’m guessing time/dev+design effort (though not sure) and that innovation and speed are directly opposed. Now with this model, one point of “effort” spent on innovation is a point of “effort” not spent on speed. That feels overly prescriptive to me. There probably is a region in this state space at which an incremental addition to “speed” compromises “innovation”, but plenty of regions throughout the state space where the tradeoff is not nearly that clear cut.

                        3. 3

                          ah so here where the author says nobody does this any more

                          This is done over a billion times a day, apt, rpm, docker, whls, etc.

                        1. 9

                          is this guy shitting on children for not learning semantic html that barely existed at the time? 😂

                          HTML isn’t about look and feel. It is about structure.

                          real “fun at parties” energy here

                          (i like semantic html, and think it’s important. but also painting is fun, and you can use html/css for that, too)

                          1. 1

                            so, Box with weak references

                            thoughts on using a PRNG instead of a counter?

                            free could zero the counter, and call the allocator’s free, rather than keeping it around (with tiny chance of catastrophic false positive)

                            1. 2

                              Havent considered that! Thats a fascinating idea. It’s probably not as fast as a simple increment, but it allows us to free memory back to the OS more eagerly, and be better than crashing if we ever max out the generations.

                              This could be an option a lot of users like. It could even use less space (32b gens instead of 48b).

                              I’m going to explore this a bit more and get back to you. If it pans out, what would you like to call it and how would you like to be credited?

                              (Also, Box implies heap, these neednt be only heap)

                              1. 1

                                You are doing an incredible job implementing, documenting and community building. I’ve read everything now and I’ve learned a lot. Looking forward to using Vale :)

                            1. 8

                              I honestly don’t expect to choose C++ over C for any project again. C99 has proven itself to be much more useful for my general projects.

                              I guess these projects don’t deal with strings a lot…

                              The defer keyword. […] That’s the premise behind smart pointers, RAII, and similar features. Zig’s method blows all of those out of the water.

                              How does manual scope based destruction “blow out of the water” the automatic one (RAII)?!?

                              In Rust, C++ and D (when you use std.typecons.scoped), you literally cannot forget the defer free(something), because it’s implicit.

                              1. 4

                                i think there’s merit in having defer instead of RAII, but it only covers a third of RAII (the part where you don’t have to drop at every exit point)

                                if you had a second feature, where the compiler made sure every variable was moved before its scope ended, that’d get you the second part of RAII. the memory safety part. the most important part.

                                the third part is basically generics/traits. there’s a common “drop” interface. i think it’s reasonable to skip that part if you’re going for something small and c-like (and there’s some added flexibility with pool allocators and such, if you want a drop with a params)

                                1. 3

                                  I personally dislike having to define a class for everything that needs to be cleaned up. To be honest, I wonder if my ideal would perhaps be a hybrid of zig and rust, where its manual, but automatically checked.

                                  1. 1

                                    You can already do this in Rust, by using the #[must_use] attribute, and defining a free(self) method (or whatever) instead of implementing Drop. You do have to define a struct, though. But that’s necessary, anyways, in order to not expose memory unsafety to the caller.

                                    1. 4

                                      Or you can have a struct that holds a lambda and you literally have defer :) So defer is, in a way, a special case of RAII.

                                      e.g. https://docs.rs/scopeguard/

                                1. 4

                                  rolling the negative operator into the numeric literal syntax would make me feel a lot better about removing it. it’s still annoying that it collides with binary subtraction, but it’d reduce the scope of that annoyance

                                  logical not, i’d also want some other language features to make up for it. like unless and until

                                  1. 5

                                    it’s still annoying that it collides with binary subtraction

                                    Just require spaces between the operator and the operand. I don’t understand why people don’t do that in the first place.

                                    1. 2

                                      rolling the negative operator into the numeric literal syntax would make me feel a lot better about removing it

                                      Ooops. Yes. I forgot to write that down. That was implied. :-(

                                      EDIT: Updated article.

                                    1. 2

                                      seems like a good idea for posts with a low number of votes/views, where the signal that it’s unwanted is much less clear

                                      more total votes/views should shorten/remove the grace period, though. if a bunch of people see it, you can be much more confident in its rating

                                      1. 1

                                        more total votes/views should shorten/remove the grace period, though. if a bunch of people see it, you can be much more confident in its rating

                                        yeah, the idea isn’t really fleshed out, but this would be something one could do.

                                      1. 18
                                        (๑•ᴗ•)⊃━~━☆゚cd ∆
                                        (๑•ᴗ•)⊃━~/∆━☆゚
                                        
                                        1. 2

                                          isn’t JAMStack literally every website? is that the joke? does the j stand for vanilla.js?

                                          js on the client, because that’s all it can run*. APIs on the backend, because that’s what we call things on the backend. and markup, because that’s how to tell the browser to render things?

                                          (*until wasm catches on)

                                          1. 3

                                            My understanding of jamstack is that it is relatively focused. The key attributes are:

                                            • Static pages (so no server required, other than a file system server like s3)
                                            • JavaScript to add some functionality, but not to drive the whole site (so not an SPA)
                                            • APIs on the back end (so again, no rendering by a server, whether of partial HTML or something not an API like turbo links)

                                            This site does a good job of outlining the specifics:

                                            https://jamstack.wtf/

                                            1. 1

                                              This is part of why I wrote the post, because the acronym can cause confusion but it depends on a static site generator (i.e. Jekyll, Hugo, Gatsby, etc.) that uses the markup to build and deploy a site.

                                            1. 1

                                              Is there much of a case for VLIW over SIMT/SIMD? (SIMT is the model most/all modern GPUs use, which is basically SIMD, but with conditionals that mask parts of the register/instruction, rather than the entire instruction)

                                              My basic thinking is that if you have SIMD, conditional masking, and swizzling, you’re going to be able to express the same things VLIW can in a lot less instruction width. And SIMT is data-dependent, which is going to be more useful than index-dependent instructions of VLIW

                                              Basically, I don’t see the case for having ~32 different instructions executing in lockstep, rather than 32 copies of one (conditional) instruction. It seems like it’s optimizing for something rare. But maybe my creativity has been damaged by putting problems into a shape that GPUs enjoy

                                              1. 2

                                                It is more a question between VLIW and superscalar out-of-order architectures (and not between SMT and VLIW), and there the latter ones clearly win. On a fundamental level, they are faster because they have more information at runtime than the compiler has at compile time.

                                              1. 8

                                                tangentially related, here’s a cool tarot deck based on shaders: https://patriciogonzalezvivo.github.io/PixelSpiritDeck/

                                                1. 2

                                                  I own that! It’s wonderful.

                                                1. 6

                                                  This is one of the warts in rust that contributed to me writing way less rust code

                                                  It was very frustrating to have the compiler reject programs that were obviously correct, and then have to model how the compiler was approximating borrow-correctness, and come up with an alternative solution that satisfied it

                                                  Makes me excited to get back into rust at some point in the future :)

                                                  1. 6

                                                    It has elaborate sytnax[sic]. Rules that are supposed to promote correctness, but merely create opportunity for error.

                                                    It would help if you could give an example. Are you talking about the MISRA-C rules? Or random rules? What? What are the rules concerning? etc. This information is so general that it can’t be countered or even grokked properly.

                                                    It has considerable redundancy.

                                                    Again, what do you mean by ‘redundancy’? Are you talking about function reuse? Reuse of if/for/while constructs? What?

                                                    It’s strongly typed, with a bewildering variety of types to keep straight. More errors.

                                                    I don’t understand this. C has three or four groups of types at best. void*/ptrdiff_t, integer, float, char*. You can convert more-or-less freely within these groups. You should take care while converting from one group to the other (For example, if converting from float to int, use lrint and friends and check for fetestexcept, etc.). This depends on knowing what you want out of the type and knowing what the type needs from you. As a rule of thumb, use size_t for iteration and indexing, if you need to return a size or an error, use ssize_t. For working with characters, your unicode library should give you a type for dealing with them and ways of converting safely between char* and whatever that type is.

                                                    As an infix language, it encourages nested parentheses. Sometimes to a ludicrous extent. They must be counted and balanced.

                                                    So does every other infix language, and so does Lisp, which isn’t infix. I feel though, that this comes down to knowing your language. Haskell, which has clever methods (like $) of forgoing parentheses, is much more difficult to follow as someone who isn’t really very familiar with it. But I’m not going to complain about Haskell having that, because it’s a feature of the language that (if I were writing Haskell code) I must learn to work with it effectively. Likewise, if you use C, you need to know, even if it is very rough knowledge, operator precedence.

                                                    It’s never clear how efficiently source will be translated into machine language. Constructs are often chosen because the programmer knows they’re efficient. Subroutine calls are expensive.

                                                    Modern Intel architectures make this pretty easy: Avoid branches, keep mind of the cache. See http://nothings.org/computer/lexing.html for an example of complex computing without branches.

                                                    Because of the elaborate compiler, object libraries must be maintained, distributed and linked. The only documentation usually addresses this (apparantly difficult) procedure.

                                                    Ehh? For a start, most other languages that are contemporary with C, do this. Most other languages that maintain compatibility with C, do this. Personally it feels more complex to have to bundle an entire runtime system with your library’s object files (See: Ada), than just distributing the libraries. But ok.

                                                    Code is scattered in a vast heirarchy[sic] of files. You can’t find a definition unless you already know where it is.

                                                    Both cscope and grep exists. Use them.

                                                    Code is indented to indicate nesting. As code is edited and processed, this cue is often lost or incorrect.

                                                    Does Rust/Ada/Lisp/Pascal/Python not all do this? Wait. Are you comparing C and FORTH? I think a lot of this now makes sense.

                                                    There’s no documentation. Except for the ubiquitous comments. These interrupt the code, further reducing density, but rarely conveying useful insight.

                                                    You can use C with Doxygen or whatever. The library’s README or related documentation should cover using it. C lacks a good documentation system but really, so does a lot of the contemporaries. And at the end of the day, it’s not really the documentation system that exists but how the programmer uses it. You can write abysmal documentation in a language with an amazing documentation system.

                                                    Constants, particularly fields within a word, are named. Even if used, the name rarely provides enough information about the function. And requires continual cross-reference to the definition.

                                                    What’s the alternative here? Of course you need to know what a constant stands for to understand how it’s used. If I throw you the definition of F=MA, unless you’ve taken enough high-school physics to know that ‘F stands for Force, etc etc.’, ‘M stands for Mass which means […]’, ‘A stands for Acceleration which is […]’, then you’re going to be scuppered by the definition. This is a knowledge-transfer problem, a fundamental problem of grokking things, not a defect of any single programming language or dialect.

                                                    Preoccupation with contingencies. In a sense it’s admirable to consider all possibilities. But the ones that never occur are never even tested. For example, the only need for software reset is to recover from software problems.

                                                    Are they not? Is this not true for every language? Humans write tests, humans are fallible and might ignore your amazing tool to tell them how much code they’ve written tests for. If you make a tool that forces them to get 100% code coverage, they’ll just write the code to deal with less eventualities, so there is less code to test, which leads to shoddier code! It’s the same quandary with documentation. That’s not going into the fact that it’s a fallacy to test all of your code anyway (Although I agree you should aim for 100% coverage, ideally).

                                                    Names are short with a full semantic load.

                                                    It’s kind of funny that you talk about having to jump everywhere for definitions in C. Forth makes that worse because instead of being able to abstract things away, you have to essentially understand the entire codebase. Everything deals with the stack, and each forth word does not signal how much of the stack it deals with. Thus to understand one definition you have to understand how all definitions beneath that use the stack, this goes on until you are at the primitives that forth has given you. Forth seems actively hostile to abstraction. There are two facts of life: A) Any non-trivial program will have a large amount of words. B) Any given programmer can come up with a definition of a word that does not match the one in your mental model.

                                                    C has syntax to deal with that. It has comments, interfaces, types, and named parameters. I agree that maybe there are much better tools for the job, but here is where Forth does worse than C (No types to tell you that “carry” is an integer and not a double. No named parameters so there is no “carry”, and you don’t necessarily have the same definition of “add” that the original programmer did), and carries much of the same complaints that you listed earlier in the article!

                                                    Another difficulty is the mindset that code must be portable across platforms and compatible with earlier versions of hardware/software. This is nice, but the cost is incredible. Microsoft has based a whole industry on such compatibility.

                                                    Write to POSIX, and it’s supported everywhere. I’m not sure what you want the alternative to be here. Do you want software to not be compatible with different operating systems? Or different processor architectures? What?

                                                    1. 9

                                                      Sorry if you were mislead otherwise, but this wasn’t written by me - it was written by Charles “Chuck” H. Moore of Forth fame. A while ago, too.

                                                      1. 5

                                                        I think a lot of that article makes more sense if you consider embedded programming, where they don’t have POSIX and such (or even documented opcodes), which I hear FORTH is popular with

                                                        Console/handheld game development is an interesting case for non-portable code, too. You can write a game for a single platform, and get a better result by not trying to make it compatible with others. Or maybe target two or three, and ignore the infinite other possible machines you could make it compatible with

                                                        Those are also cases where maintenance is less of an issue. I haven’t written more than a trivial amount of FORTH, but I would not want to maintain it over a long period, because it looks like hell to refactor/rearchitect it after its written.

                                                        It looks like its strong suit is programs that you can write once, and throw out and write again when the hardware or the problem changes

                                                        I think the author is arguing that all/most programs are that kind. I don’t agree with that, but it’ll be good to have their voice in my head when I go to write some code that’s more general than it needs to be

                                                        1. 1

                                                          Forth makes that worse because instead of being able to abstract things away, you have to essentially understand the entire codebase. Everything deals with the stack, and each forth word does not signal how much of the stack it deals with. Thus to understand one definition you have to understand how all definitions beneath that use the stack, this goes on until you are at the primitives that forth has given you. Forth seems actively hostile to abstraction

                                                          I’ve often felt (without much familiarity with the language, admittedly)that forth’s ergonomics would be greatly improved by having words declare their stack effects as “function signatures” and have them checked. at the least I’d like to see a forth-like language that explored that idea, possibly with types as well. though maybe that goes fundamentally against the code-as-data model?

                                                          1. 3

                                                            In the factor variant of forth does some static checking.

                                                            1. 2

                                                              One of the tenets of learning Factor is to take the mantra “Factor is not Forth” to heart.

                                                              1. 2

                                                                They missed a trick by not calling it FINF instead.

                                                                1. 1

                                                                  No offense meant :) I admire factor from a distance.

                                                              2. 2

                                                                “Checking” them would be complicated (and pointless). They are however declared with stack comments in good code, i.e. : SQUARE ( n -- n) DUP * ;

                                                                1. 1

                                                                  why would it be pointless? if i could declare

                                                                  * : num num -> num
                                                                  dup: 'a -> 'a 'a
                                                                  square: num num -> num
                                                                  

                                                                  that could be automatically checked for consistency and type safety without reducing the expressiveness or ease of use of the language.

                                                                  1. 2

                                                                    You have to add all the code to know when you’re doing a type check, you need to have code to handle all the different cases that are being analysed (including varargs), you need to be able to keep track of words that are already valid and called from a parent word lest you compute the safety every time (cache) - not sure how rdrop would work in this kind of type checked system either, since an rdrop isn’t a return at all - plus words that perform i/o being special cases…

                                                                    Worst of all, you have to add types. Just sounds like a lot of complexity for what could be gained by writing short, simple to follow definitions.

                                                            1. 3

                                                              After using Unity for ~9 years, I’ve come to a different conclusion on performance: When you’re further from the metal, you don’t get to stop thinking about the machine, but you do need to grab a 3 meter long screwdeiver sometimes

                                                              I think this is what Jonathan Blow was talking about when he said you’d have to rewrite many of Unity’s systems if you wanted to make The Witness in it. You still need to understand how the hardware works if you want to have any hope of making your code fast, but you’re going to need to work around/replace parts of the higher-level engine/language, and sometimes that’s more work (or more annoying work. I think Blow has low tolerance for that kind of code) than doing everything in a lower level environment

                                                              I’m very pro-Unity for most games. You’ll get to a prototype way faster, and the pain of making a few rube-goldberg machines to get it running fast enough is usually far less than writing a whole engine. If you want to be Id and work on bleeding edge rendering tech, it’s not going to be a good choice. But almost anything short of that, the code and time saved is worth the gross hacks