1. 6

    Starting work on a 2d game engine, like LÖVE. The difference is that the scripting language is JavaScript.

    I’m using Microsoft’s ChakraCore as the JS engine. I did some experimenting over the weekend and their API is quite intuitive to use.

    1. 2

      The tag should be C++, not C.

      1. 2

        Do you know how I can edit the tags? Or do the mods have to? Couldn’t find the option :(

        1. 1

          Apparently you click suggest

      1. 2

        Sadly it seems to happen if you make your own functions too, so it possibly happens with any case where the compiler thinks that that buffer won’t be used anymore.

        I see that the article provides a solution at the end. But it seems to me a warning should be made by the compiler, instead of having to adapt all functions to prevent this from happening. Or be able to disable this specific optimization.

        1. 1

          Yeah, after some reading it seems to be due to dead store optimization.

          If the memory is not accessed after you store something there (i.e., memset), the compiler will reorder the instructions and the dead store is removed.

          There was some interesting discussion on GCC’s bugzilla about this. Is that a bug or not? I think it is.

          After some Googling I found the explicit_bzero function that @kristapsdz mentioned, but the glibc version. The trick it uses is to add asm volatile ("" ::: "memory") after the memset call. That prevents any stores prior to that point to be reordered.

        1. 8

          Wow great to see this! I remarked after one of the chapters in craftinginterpreters that I didn’t find a lot of literature on bytecode VMs.

          There are a lot of books on compilers, but not as much for interpreters (i.e. the bytecode compiler + dynamic runtime combo that many languages use).

          There are the Lua papers, a few blog posts about Python, some papers about the predecessor to OCaml, and craftinginterpreters, but not much else I could find. I found this book recently, but it’s not specifically about the compiler / VM:

          http://patshaughnessy.net/ruby-under-a-microscope

          Anyway I am glad to see another addition to this small space! :)

          I’m hoping to find some time to really push into my compiler / VM project this winter: http://www.oilshell.org/blog/2018/03/04.html .

          Basically the idea is that Python has a “dumb” compiler and a very rich runtime. (This fact has been impressed upon me by hacking on its source code!). I want to make it have more of a smart compiler and small/dumb runtime.

          1. 5

            There’s also Nils M Holm’s books: http://t3x.org/

            1. 2

              That’s just pure gold :O

              1. 1

                Which parts discuss bytecode interpreters? I see a lot of different things there, including native code compilers, but no bytecode interpreters.

                1. 3

                  One of the features of the T3X compiler is a portable bytecode interpreter. Here’s the source, I think you’ll like it: https://www.t3x.org/t3x/t.t.html

              2. 4

                There are a lot of books on compilers, but not as much for interpreters (i.e. the bytecode compiler + dynamic runtime combo that many languages use).

                Not a book, but you still might find this paper interesting: Engineering Definitional Interpreters:

                Abstract: A definitional interpreter should be clear and easy to write, but it may run 4–10 times slower than a well-crafted bytecode interpreter. In a case study focused on implementation choices, we explore ways of making definitional interpreters faster without expending much programming effort. We implement, in OCaml, interpreters based on three semantics for a simple subset of Lua. We compile the OCaml to x86 native code, and we systematically investigate hundreds of combinations of algorithms and data structures. In this experimental context, our fastest interpreters are based on natural semantics; good algorithms and data structures make them 2–3 times faster than interpreters. Our best interpreter, created using only modest effort, runs only times slower than a mature bytecode interpreter implemented in C.

                1. 3

                  Wow thanks! This is exactly the kind of thing I’m looking for.

                  For example, even the first sentence is somewhat new to me. Has anyone else made a claim about how much slower a tree interpreter (I assume that’s what they mean by definitional) is than a bytecode interpreter? I’ve never seen that.

                  I know that both Ruby and R switched from tree interpreters to bytecode VMs in the last 5-8 years or so, but I don’t recall what kind of speedup they got. That’s something to research (and would make a good blog post).

                  Anyway I will be reading this and following citations :-) I did find a nice paper on the design of bytecode VM instructions. Right now choosing instructions seems to be in the category of “folklore”. For example, there are plenty of explanations of Python’s bytecode, but no explanations of WHY they are as such. I think it was basically ad hoc evolution.

                  1. 1

                    I did find a nice paper on the design of bytecode VM instructions.

                    Would mind sharing what that paper is? I’d love to read more about how to do this properly.

                    1. 3

                      I’m pretty sure this is the one I was thinking of:

                      ABSTRACT MACHINES FOR PROGRAMMING LANGUAGE IMPLEMENTATION

                      http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.68.234

                      We present an extensive, annotated bibliography of the abstract machines designed for each of the main programming paradigms (imperative, object oriented, functional, logic and concurrent). We conclude that whilst a large number of efficient abstract machines have been designed for particular language implementations, relatively little work has been done to design abstract machines in a systematic fashion.

                      A good term to search for is “abstract machine” (rather than bytecode interpreter). The OCaml paper is called the “ZINC Abstract Machine” and it’s quite good.

                      There is a bunch of literature on stuff like the SECD machine, which is an abstract machine for Lisp, and which you can find real implementations for.

                      There seems to be less literature on stack / register bytecode interpreters. The Lua papers seem to be the best read in that area.

                      This guy is asking a similar question: https://stackoverflow.com/questions/1142848/bytecode-design

                      1. 1

                        This is great, thank you for sharing!

              1. 1

                The sexist behavior of those guys at Sun was just disgusting. It’s good she wrote about this.

                But at the first beer bust I went to, two of the sales guys were standing around rating the women…only they called them “units.

                Bob Coe once told me he did not have to interview the candidates for his Administrative Assistant position. I should simply ask each candidate to link her hands behind her head with her elbows pointing forward and walk toward the wall. If her elbows were the first part of her anatomy to touch the wall, she was eliminated from candidacy. All applicants whose breasts touched first, he would interview

                1. 2

                  it really is beyond the pale of what I would consider possible in a professional work environment.

                  1. 2

                    I’m really glad she kept with it after the blowback she got!

                    I wonder why we don’t hear these “horror stories” as much from HR folks (who presumably have far more visibility of them than engineers!) as often, but I suppose that it’s probably a much bigger career risk to call out this stuff publicly when your job description is basically to deal with all of it and make sure it doesn’t become a legal or PR issue.

                    1. 1

                      One may wonder how Bob Coe would have found assistants if this was a 100% encouragement or direct order. Good thing we moved from boys-will-be-boys to disgusting, otherwise someone could really use this as a guideline in recruitment!

                    1. 6

                      I posted a similar question some time ago on Reddit, and one of the recommendations was “Practical Foundations for Programming Languages” by Robert Harper. I actually ended up purchasing it.

                      I’ve been going through it on my free time and I quite enjoy the writing.

                      1. 1

                        Great to see this! Are you planning to send a PR so this gets merged into upstream?

                        1. 4

                          It is already merged into upstream, thanks! :-)

                          1. 1

                            Yeah they were very responsive when I was upstreaming Fuchsia compatibility.

                        1. 12

                          I thought it would actually be about std::optional, not workspace issues that have nothing to do with the problem at hand.

                          TL;DR: keep your toolchain up to date if you want to use recent language features.

                          1. 3

                            yeah. I suspect better article naming would be better at not leaving people feel like they kept on expecting the article to go somewhere it didn’t.

                            1. 9

                              I think it’s funny because the reader’s experience parallels the author’s experience of wanting to get someplace.

                              1. 4

                                Somebody gets me! :)

                              2. 2

                                Sorry folks :(. But std::optional works as one expects - you can write functions to accept std::optional and you just check early on if it evaluates to true and just return empty as needed, so you can chain functions neatly.

                                Now, if only we could have pattern matching …

                                1. 3

                                  I think the consensus of languages with options and pattern matching is “don’t use pattern matching, use combinators”.

                                  1. 4

                                    Hmm as a full-time Haskeller “don’t use pattern matching” is news to me. Do you mean “don’t use pattern matching for fundamental vocabulary types like Maybe or Either? In which case it’s a reasonable guideline. For types representing your business domain, pattern matching is perfectly good practice. IMHO exhaustiveness checking of pattern matching is an indispensable feature for modelling your domain with types.

                                    1. 1

                                      Do you mean “don’t use pattern matching for fundamental vocabulary types like Maybe or Either?

                                      Yes.

                                    2. 3

                                      Consensus, really? I’m a big fan of combinators, but I’ll still match on option types sometimes if I think it looks clearer.

                                      1. 2

                                        Ooh, this is interesting to me - can you expand on this (or point me to some writeups)? Thanks!

                                    3. 2

                                      Agreed. I read all the way down and nothing significant about std::optional.

                                      I thought it was going to be some sort of piece about how using std::optional could lead to yak shaving or something :(

                                  1. 2

                                    Always a little wary when this is the first line:

                                    At Microsoft, the core of our vision is “Any Developer, Any App, Any Platform”
                                    

                                    Orlly?

                                    But I’m interested…

                                    1. 4

                                      Maybe “all platforms” means all versions of Windows, most OS X, and latest Debian stable.

                                      1. 6

                                        To be fair, that puts them miles ahead of almost everybody else working on platforms these days :(

                                        All the action right now seems to be on “JS tool of the week” and “build for Android and iOS with one codebase”

                                      2. 3

                                        I sincerely don’t understand this hate against Microsoft.

                                        Yeah sure, Ballmer days sucked and they really screwed up. But since Natya picked up the role, there seems to have been quite a shift in the company’s mindset. Plus all the OS things they’ve been doing in the past few years.

                                        1. 1

                                          That’s a description of what they want to extend and eventually extinguish.

                                          1. 1

                                            That view is a little out of date, don’t you think? What have they tried to extinguish recently?

                                        1. 5

                                          This is a nice effort, but one wonders why the author doesn’t want to use vmstat(8).

                                          Side note: The author doesn’t seem to be too familiar with OpenBSD and its conventions. The man page was written in man(7), which is deprecated in favor of mdoc(7) on OpenBSD

                                          1. 4

                                            Thanks very much for your pointing out to use mdoc!

                                            Compared to vmstat(8), my simple toy has following differences:
                                            (1) Add displaying swap space;
                                            (2) Only consider active pages as “used” memory, others are all counted as “free” memory.IMHO, for the end user who doesn’t care the guts of Operating System, maybe this method is more plausible?

                                            All in all, I just write a small tool for fun, and thanks very much again for giving pertinent advice!

                                            1. 2

                                              Agreed. Sometimes you don’t really care about everything vmstat offers. free is dirty neat :)

                                              • TIL about mdoc
                                              1. 1

                                                P.S. After some testing, I modify the calculating free method just now: use free pages as “free” memory, then others are considered as “used” memory.

                                              2. 3

                                                Thanks for educating me about the distinction: https://github.com/blinkkin/blinkkin.github.com/wiki/man-vs-mdoc

                                                1. 4

                                                  I’d suggest Practical UNIX Manuals for introductionary reading for mdoc, too: https://manpages.bsd.lv/mdoc.html

                                              1. 9

                                                Not sure I agree with the article. Sure, I’ve seen that kind of code before and it is mildly annoying, but most of the code I’ve seen uses proper structs or classes. It seems that people who like LISP always try to find “problems” in the language that make people not want to adopt it.

                                                I actually think that the problem with LISP (i.e., Common Lisp) is that it is a language that stopped in time. As examples:

                                                • There’s no reasonable package manager (I know of quicklisp, but it is not nearly as convenient as Rust’s Cargo, for example).
                                                • No friendly language documentation. Hyperspec is complete, but it is in no way pleasant to use. I know there are efforts to improve it, but it would have to get at least close to Go/Rust documentation quality to attract people. Lack of examples is also a deal breaker.
                                                • No centralised community. Pretty much everybody ends up reinventing the wheel, possibly due to the lack of a good package manager and docs.

                                                Clojure is arguably successful, but it comes with the “cost” of being bound to the Java VM – which pretty much requires a PhD to properly tune.

                                                1. 2

                                                  Hyperspec is complete, but it is in no way pleasant to use.

                                                  Funny, I find myself missing the Hyperspec every single day (I now write mostly Clojure). It remains the standard against which I judge most other documentation. (And I’m not sure what you mean when you say it doesn’t have examples; the Hyperspec page for defstruct has over a dozen separate examples of different uses.)

                                                  Yes, it’s unfortunate that there is no realistic way to change or grow the language, but as far as documenting what does exist in the standard the Hyperspec does a great job.

                                                1. 8

                                                  What sort of new problems doesn’t increasing Ruby’s performance 3x open up for Ruby? As a non-Rubyist, Ruby is so slow a 3x improvement is still too slow, to me.

                                                  1. 16

                                                    That’s fair, but Ruby’s performance is on par with Python’s (or better in at least some benchmarks, actually), which is plenty good enough for many, many people. So for those using Ruby, that’d still be an incredibly welcome improvement.

                                                    That said, I’m curious when you last tried Ruby. It’s definitely still an order of magnitude slower than most compiled languages, no question, but the new GC that landed around 2.2, and the bytecode based VM that landed around 1.9 or so, have made a huge, very noticable difference in places I’ve used Ruby. It’s been enough that I’ve kept reaching for it over e.g. Go in quite a few instances.

                                                    1. 3

                                                      Ok, but that’s not really answering my question. Is this performance push just to get some benchmark numbers higher or is it opening new opportunities for Ruby? Certainly people aren’t going to be replacing their big data jobs with Ruby with a meager 3x improvement. People aren’t going to be writing video games in pure Ruby or doing high frequency trading.

                                                      1. 9

                                                        Is this performance push just to get some benchmark numbers higher or is it opening new opportunities for Ruby?

                                                        Performance concerns aren’t even at the top of my list of “why I wouldn’t write new software in Ruby”; I’m more concerned with long-term maintainability due to the dynamicity making static analysis more or less a lost cause.

                                                        In the interview he talks a bit about the possibility of gathering type data from running code, but without breaking existing code I’m having a hard time imagining a solution that would be reliable.

                                                        1. 5

                                                          I’m also skeptical. Ruby users, for a while, seemed to revel in meta-programming and run-time code generation, which greatly hinders static analysis.

                                                        2. 6

                                                          Well, I think that a 3x improvement would at least help push the bar for “Ruby is too slow for me, I’ll rewrite it in X-compile-language” further away.

                                                          1. 5

                                                            That’s what I was trying to convey also. Ruby’s strength is that it’s a very expressive language, but its speed at one point made it an effective no-go for classes of work. (Hell, I remember writing a site in Django instead of Rails for performance reasons.) The speed improvements so far have really just kept it relevant, to be honest, by getting it back to and somewhat exceeding Python; a further 3x would mean I could start looking at it over things like C# for what I might call mildly performance demanding stuff (e.g. maybe daemons with nontrivial but not excessive workloads).

                                                      2. 8

                                                        The upcoming support for guilds is much more exciting in terms of addressing new problems than single-threaded execution improvements, IMHO.

                                                        A less humble opinion of mine is that guilds are too little, too late, and still too primitive to have a transformative effect on Ruby and its ecosystem. I think too many devs (like me) are now accustomed to more advanced/higher-level concurrency abstractions, and guilds feel like a slightly safer way of revisiting the mid-90’s.

                                                        1. 2

                                                          It’s used a whole lot in web dev so 3x faster will make a lot of websites faster.

                                                          1. 1

                                                            I think it just helps people who have already invested in Ruby justify their continued investment. I wouldn’t expect a ton of new users at this point unless they develop another “rails”.

                                                            1. 1

                                                              What are your favorite languages?

                                                              1. 2

                                                                I try to spend as much time in Ocaml as I can, currently.

                                                                1. 1

                                                                  Wow…I’ve never heard of anyone using that. :)

                                                                  Taking a look now - it does look pretty cool.

                                                            1. 6

                                                              Will continue reading through “Designing Data-Intensive Applications”. Really enjoying the book so far, specially the way the author lays out the trade-offs of different systems.

                                                              Managed to do good progress with my reading last week.

                                                              1. 5

                                                                Another “quirks” question: did you find any unexpected quirks of Go that made writing this emulator harder or easier?

                                                                1. 5

                                                                  In this particular case, it feels like the code isn’t too far from what C code would be: here are some basic data structures and here are some functions that operate on them, mostly on the bit level. No fancy concurrency models nor exciting constructs. I think given the fact that this is an inherently low level program, most nicieties from Go weren’t immediately needed.

                                                                  I did use some inner functions/closures and hash maps, but could’ve just as well done without them. The bottom line is that the language didn’t get in the way, but I didn’t feel like it was enourmously helpful, other than making it easier to declare dependencies and handling the build process for me.

                                                                  1. 4

                                                                    Did you run into any issues with gc pauses? That’s one of the things people worry about building latency sensitive applications in go.

                                                                    1. 3

                                                                      Not the OP, but I would assume this kind of application generates very little garbage in normal operation.

                                                                      1. 2

                                                                        The gc pauses are so miniscule now, for the latest releases of Go, that there should be no latency issues even for realtime use. And it’s always possible to allocate a blob of memory at the start of the program and just use that, to avoid gc in the first place.

                                                                        1. 2

                                                                          The garbage collector hasn’t been an issue either. Out of the box, I had to add artificial delays to slow things down and maintain the frame rate, so I haven’t done much performance tuning/profiling. I am interested in scenarios where this would be critical though.

                                                                          1. 1

                                                                            Go’s GC pauses are sub-millisecond so it’s not an issue.

                                                                        2. 3

                                                                          Interested in this as well. I’ve toying with the idea of writing a CHIP-8 emulator in Go and would love to hear about how is the experience of writing emulators.

                                                                          1. 3

                                                                            I did exactly this as a project to learn Go! I used channels in order to control the clock speed and the timer frequency and it ended up being a really nice solution. The only real hangup I had was fighting with the compiler with respect to types and casting, but having type checking overall was a good thing.

                                                                        1. 6

                                                                          I’ll continue experimenting with the “12 week year” idea: setting a small number of goals and working towards them for 12 weeks. Selecting just a few goals and devising strategies to accomplish them is pretty darn useful. It feels really good when you get to the end of the week and can see the progress you made.

                                                                          One of my goals is to read the “Designing Data-intensive applications” book in this period. I’ll keep up with my daily read during this week.

                                                                          1. 3

                                                                            I’m not totally sold on the idea that “unsigned for value range” is an anti pattern. Sure, in the example the author presents (std::string::find), it definitely is. But now with std::optional in C++ 17, it seems perfectly fine to use an unsigned value for range.

                                                                            std::string:find could simply return a std::optional<size_t>, for example.

                                                                            Does anyone see a problem with this approach that I do not? Not considering backwards compatibility.

                                                                            1. 2

                                                                              To me the first obvious drawback of optional<size_t> is that it doubles the size requirements. On 64bit machine this will typically grow from sizeof(size_t) == 8 to sizeof(std::optional<size_t>) == 16.