1. 14

    Quora has always felt like a site that desperately wants Stack Exchange-level prestige but is sabotaged by the much sketchier vibe it consistently gives off. Along with the OP’s closed-platform we-own-your-content issues, there’s also things like:

    • Forcing users to sign up and go through an onboarding process before they can read answers (their recent breach should remind us that this kind of “growth hacking” is not just obnoxious but irresponsible)
    • A Yahoo Answers-like “no question is too dumb” ethos (if you’ve gotten their daily digest emails after being forced to sign up, you probably know what I’m talking about)
    • Power users very obviously using the site as a means to build their brands, personal and otherwise. You don’t get the sense that anyone answering questions there is doing so out of the kindness of their hearts.

    All of which combine to create a pretty unappealing platform to have any part in. I understand that Quora is a VC-funded startup, and that a VC-funded startup needs to show growth if it wants to continue existing, but it’s a good cautionary tale of how investor demand for growth is often at odds with building a platform that people actually want to use.

    1. 6

      Quora has always felt like a site that desperately wants Stack Exchange-level prestige but is sabotaged by the much sketchier vibe it consistently gives off

      This is so accurate.

      it’s a good cautionary tale of how investor demand for growth is often at odds with building a platform that people actually want to use

      I’ll go a step further and say that the ideas are diametrically opposed; I see no room for coexistence.

      1. 5

        I’ll go a step further and say that the ideas are diametrically opposed; I see no room for coexistence.

        Oh I completely agree, just forgot that this is a site where we can speak these heresies out loud ;)

    1. 52

      This is the collateral damage of making browsers so complex. If megacorps can’t justify the costs required for maintenance and improvement, we essentially cede the platform to those with the deepest pockets.

      1. 16

        Yeah, I think you are making a super important point so I’ll try to reiterate it:

        • Open standards succeed when many people/organizations can easily implement the standard due to its simplicity and obviousness.
        • Open standards fail when too few people/organizations can make a complete implementation; they “collapse” under their own weight.

        This is not backed up by data, rather it’s my opinion or a synthesis from bits of anecdotal evidence. In this case, the laundry list of features now required to make a web browser is pretty intractable. As others have said, it’s reaching the level of complexity of an OS.

        1. 8

          This is the collateral damage of making browsers so complex.

          In this case, the laundry list of features now required to make a web browser is pretty intractable. As others have said, it’s reaching the level of complexity of an OS.

          Yup and yup.

          I understand the emergency on the danger of having one megacorp controling a set of standards, but this is a monstrous set of standards that, imo, needs to die. Something simpler and lighter must replace it, and I’m not much into putting effort, by “doing my part,” to saving the current one. I refuse to believe that something simpler isn’t possible.

          1. 8

            I’m starting to share this position. The web is dead, long live the Internet.

            1. 3

              There’s always gopher. It’s not that hard to write a gopher client.

              1. 2

                Another solution might be to more clearly define essential parts of the standard and extra parts, with sane graceful degradation. The goal being to encourage web developers and companies to be less apt to require every flashy new (extra) feature, because not all browsers would to choose to implement all the extras.

                1. 1

                  This wouldn’t stop Google from implementing Google features that require everyone to use Chrome, and then everyone would just use Chrome. I don’t think this would be any different than the status quo.

                2. 1

                  Something simpler and lighter must replace it, and I’m not much into putting effort, by “doing my part,” to saving the current one.

                  Just be careful that that “simpler and lighter” thing isn’t something like AMP that causes even more lock-in than we have now.

                3. 1

                  While I agree with your analysis, we do have several FOSS operating systems. Admittedly, much Linux development is funded by corporations. Nonetheless, there are multiple existence proofs that free software communities can deliver software with complexity on the order of operating systems. I’m not aware of any browsers produced that way, though. I suppose Firefox would be the nearest thing.

              1. 13

                At the end I was looking for Python but it wasn’t even listed. :(

                Python is…

                • syntax light and readable
                • integer overflow-proof unless you have a number larger than the memory of your entire machine
                • not intended for creating metalanguages

                It’s only downside (in my opinion and limited experience) is that it usually will be slower than something comparable in a compiled language.

                1. 5

                  For me, the One Thing missing from python is a rigorous static typechecker. I miss that a lot when writing python code. That said, I do generally enjoy working in the language.

                  1. 1

                    I share the feelings. I’d add that the common functions that you might expect like map/filter/sort/… have sometimes weird names or syntax and reminds me PHP…

                    1. 1

                      I never understood this complaint/desire to add static typing to languages that are completely antithetical to the idea. Not every feature that exists in other languages should be added to every language (that leads to C++, Rust and PHP). Python is a dynamic language and it doesn’t make sense to bolt rigorous static typing on top, and it’s never going to be completely sound, because of its inherent dynamic nature. Why not use a language with a sound strict typing system, like OCaml or Haskell or Elm or what have you?

                      1. 3

                        Actually, I’d even be happier if Python didn’t include lambdas, functools and such. Having no support for functional programming would be way less frustrating than having half-assed support for functional programming, especially given that the community frowns upon their use anyway!

                        1. 1

                          I strongly prefer OCaml, Haskell, Elm, etc. But those languages don’t have anywhere near the community buy-in as Python, so there’s much more friction in using them for a project (especially a collaborative one).

                        2. 1

                          Did you checkout mypy and the typing module? I had the same feeling, and am super happy with both.

                        3. 3

                          It’s only downside

                          It has many other downsides.

                          • Bananas for data types; no facilities for arrays (without extensions like numpy)
                          • Crap “error” handling: Dynamic unwind is the last thing we want for error handling, but
                          • 1990’s module system aka PYTHONPATH means everyone invents their own plugin system. Hooray for virtualenv, you’ve just traded one problem for two.
                          • Zero legacy support. Python applications are expected to either be sealed (and risk platform bugs, of which there have been many) or be rewritten (often substantially) every time there’s a new release. Hopefully this is changing – Python3 has settled down considerably, but I need another ten years.

                          I could go on. Really, Python is one of the worst successful languages I’ve ever seen or used. and I’m so glad other languages are eating its lunch (go, rust, cobol) – even though I don’t particularly rate those languages (although admittedly for other reasons).

                          1. 1

                            Bananas for data types; no facilities for arrays (without extensions like numpy)

                            I don’t really think it’s a big deal to need extensions for data types, if it wasn’t for Python’s “batteries included” mantra. It’s more like “a few very specific batteries of varying quality are included”.

                            Crap “error” handling: Dynamic unwind is the last thing we want for error handling

                            Could you unpack that a bit? I’m genuinely interested to know what is wrong with its exception handling and what alternatives are better.

                            1990’s module system aka PYTHONPATH means everyone invents their own plugin system. Hooray for virtualenv, you’ve just traded one problem for two.

                            Yeah, modules in Python are a bit fiddly.

                            Zero legacy support.

                            I can imagine that’s annoying when working on an old application, but I do think improvements need to happen, and sometimes the best way forward is to do an overhaul instead of lugging around broken stuff forever. In this, Python is a bit of a victim of its own success; the reason it was so hard to switch to Python 3 was mostly in the 3rd party libraries. This is tricky to get right (but it can be worse; look at PHP with its ancient legacy cruft sticking around and continually breaking very large things on each major version), and I really wonder how the new languages like Go and Rust fare with legacy support. They haven’t been around for as long as Python.

                            1. 2

                              Bananas for data types; no facilities for arrays (without extensions like numpy)

                              I don’t really think it’s a big deal to need extensions for data types, if it wasn’t for Python’s “batteries included” mantra. It’s more like “a few very specific batteries of varying quality are included”.

                              A really useful data type is the “table”, but it’s extremely difficult to write one in Python, so nobody bothers. Everyone just writes:

                              for row in q.fetchall():
                              

                              all day, and think this is the best they can do. But “my database” knows what a table is. Its tables are pretty good. Why can’t I implement a table type that’s worth half that? Why can’t I even approach sqlite-level of functionality? If Python is so great, why is something that everyone uses every day nearly impossible to implement in Python?

                              Another really useful data type is a “date”. Dates are also hard to implement in Python, but this one people have tried. Unfortunately, the one most popular had a bug involving DST east of GMT creating a lot of weird problems for people. Dates have a continuous nature that the integer usually used to represent them doesn’t have, which also causes strangeness for people. Intervals are really similar to dates – you can add them, but intervals don’t have timezones. Dates do. This causes more bugs. And so on.

                              Getting batteries included with your golf cart is stupid because you’re still driving a golf cart.

                              Crap “error” handling: Dynamic unwind is the last thing we want for error handling

                              Could you unpack that a bit? I’m genuinely interested to know what is wrong with its exception handling and what alternatives are better.

                              Common Lisp has a “condition system” which is better.

                              To separate the language-specific element: Conditions can be implemented in Python trivially. Most of the issue with error handling is cultural, and people continue to argue between “exceptions” (e.g. longjmp, dynamic-unwind, nonlocal goto, etc), and “error codes” – like the issue is merely signalling exceptional state one way or another or something like that.

                              To see what happens when you think that the point of errors is to tell people about them, look at the innovation in this space you’re probably much more familiar with: So-called “railway-oriented programming” or A+ Promises. They’re the same thing. Stack unwinds, but we never rewind.

                              That’s the trick: We don’t just want to say “help, I can’t proceed any further”, we want to say “I can’t proceed any further unless…” – and that’s exactly what conditions give you.

                              If you want to imagine what this could have looked like in Python, imagine instead of an except IOError, e: you could say when IOError, e: do_something() and then do_something() could return so that whatever was trying to write to the disk (or whatever) could retry. You could implement this with functions and while loops, but that would never fix all the other libraries that are still wrong.

                              but it can be worse; look at PHP with its ancient legacy cruft sticking around and continually breaking very large things on each major version

                              Oh indeed. I’m aware things can always be worse. But if I’m going to fantasise about how things are going to be better, I’m going to shoot a hell of a lot higher than PHP.

                              1. 1

                                A really useful data type is the “table”, but it’s extremely difficult to write one in Python, so nobody bothers.

                                What exactly would you expect from a table type that’s better than the “for row in fetchall()” style functionality? The database engines I know about will literally return a list of tuples to the client. Sqlite seems to allow stepping through this list to return the tuple at the current point a la “cursors”. Or is it more the row-number/column-name type access you’re aiming at here? That’s pretty trivial to implement with “magic methods”. For some weird reason that’s not the default behaviour in psycopg2 but you can ask for a dictionary-like cursor when making the db connection.

                                Common Lisp has a “condition system” which is better.

                                Ah, I see what you mean now. The distinction is about continuable versus non-continuable conditions/exceptions. That reminds me, I’d like to make continuable exceptions easier to handle in CHICKEN, as currently they’re a bit awkward to deal with right now.

                                But if I’m going to fantasise about how things are going to be better, I’m going to shoot a hell of a lot higher than PHP.

                                Thankfully, most of us do :)

                                1. 1

                                  What exactly would you expect from a table type that’s better than the “for row in fetchall()” style functionality?

                                  Think about what you’re doing inside those for-loops and how similar many patterns you might have there. Some of the ones I see every day:

                                  • Reorder (or build a permutation array) the table by one, two, many compound columns. In k, all vector operators are extended to tables by having tables implemented as a list of columns; arrays all the same length.

                                  • Join/zip two tables together (exceptionally common). Gross in Python, but in k this is just ,

                                  • Determine if some table is inside another table.

                                  • Group some table rows by some columns.

                                  • Use a column as a rule on other columns. For example, if I want a table of switches, and one column to specify which switch to flip, in q this is

                                    @[t;t`rules;@[;;not];til count t]
                                    

                                    In Python, you need, if row-ordered something like:

                                    for x in t:
                                      x[x["rules"]] ^= x[x["rules"]]
                                    

                                    or if column-ordered:

                                    for i,x in enumerate(t["rules"]):
                                      t[x][i] ^= t[x][i]
                                    

                                    Neither is great, and I’ve seen worse contortions trying to rewrite it in SQL…

                                  • Deleting rows from a table (usually simulated with list.filter, but this conses a lot)

                                  • Upserting (often simulated with an index)

                                  And so on.

                                  The database engines I know about will literally return a list of tuples to the client

                                  One way to think about this: The “database engine” is just another programming language, and it’s another one that’s better than Python at tables. The challenge is to have tables in not a database engine.

                                  It’s funny, because as soon as you put tables in there, plus “a little bit more”, you have a “database engine”, but exactly how much “a little bit more” is, and what you get for it makes you wonder why you just didn’t do it in Python (or C or Rust or Go whatever) to begin with.

                                  Back in the day, the reason “the database” was separate was because a separate team managed it, but I feel like we’re past this now. Keeping tables out of languages isn’t some layer-violation, it’s a space of real problems people are working on every day that language designers are just ignoring for inertia reasons.

                                  Ah, I see what you mean now. The distinction is about continuable versus non-continuable conditions/exceptions.

                                  Well it’s one solution. I’m not closed to others, but it’s an obvious one that’s “better” by some definition. It’s worse by another (longer code) which might also be important: I put a fair amount of effort into fixing ECL’s file/IO “exceptions” to be restartable, but I don’t think anyone ever used them but me. Lisp is great, but people keep writing Java in it…

                                  I’m still thinking about how language can help with this.

                                  1. 2

                                    Think about what you’re doing inside those for-loops and how similar many patterns you might have there.

                                    Hm, that’s thought-provoking, thank you for that! I see what you mean now, never really considered it to be a huge problem, but these patterns do occur over and over.

                                    It’s funny, because as soon as you put tables in there, plus “a little bit more”, you have a “database engine”, but exactly how much “a little bit more” is, and what you get for it makes you wonder why you just didn’t do it in Python (or C or Rust or Go whatever) to begin with.

                                    In most cases I would argue you didn’t write the right query to return just the data you need in the right form. Nine times out of ten you see people writing horribly contorted code that’s dog slow in their programming language (often performing tons of extremely dumb queries) to massage data into shape, in a way that could be done much better and more efficiently with SQL (often with a single query instead of many). So even if you have the right tools people will abuse them.

                                    Back in the day, the reason “the database” was separate was because a separate team managed it, but I feel like we’re past this now.

                                    I would tend to disagree: the most important part (for me) about a database are the ACID properties offered by RDBMSes. It’s a separation of concerns; you don’t want your language to implement a storage engine, just like you don’t want your language to implement a raw file system; leave that to the OS kernel. You could do both in a library of course, but I’d much prefer a specialized separate tool to do it. Nevertheless, having good direct support for “tables” like you mention would be nice and a good and natural extension for dealing with result sets or tabular data that doesn’t need to go to an external database.

                                    I put a fair amount of effort into fixing ECL’s file/IO “exceptions” to be restartable, but I don’t think anyone ever used them but me.

                                    My hat’s off to you! We need more people to put effort into making existing good tools even better.

                                    1. 1

                                      In most cases I would argue you didn’t write the right query to return just the data you need in the right form. Nine times out of ten you see people writing horribly contorted code that’s dog slow in their programming language (often performing tons of extremely dumb queries) to massage data into shape, in a way that could be done much better and more efficiently with SQL (often with a single query instead of many). So even if you have the right tools people will abuse them.

                                      Yes. That happens very often. But I want to stress that tables don’t just live in the database.

                                      I have an ad server that can either retrieve ads from its local database, or from a remote server (using HTTP). The publisher (client) requests ads from me, and I’ll basically be an aggregator. If the publisher asks for 10 ads, and the advertiser gives me 3, I might ask for 7 from another advertiser and glue them together.

                                      The ad response is a table - each row representing a different ad, and each column representing some attribute (like the title, description, click-URL). I’m doing asof join (basically a merge-sort) to glue these together since I know the client may only take the first few ads so everyone who does this puts the higher-value ads at the top.

                                      I’m given search keywords, so I do a query on this table – it’s a virtual table really, since it spans multiple databases (local and remote) but you can see this is clearly a table lookup made difficult by committee.

                                      Knowing that, look at the schema Yahoo uses (starts around page 87). Do you see that table? How about when Google does it? Do you see the table now?

                                      the most important part (for me) about a database are the ACID properties offered by RDBMSes

                                      As soon as I discovered logging, I realised I never needed ACID Again. I rarely use an ACID database these days, and my application design has become a lot simpler as a result.

                                      I remember I noticed that many business applications want their database to remember all the changes. And who made them. So many CRUD applications will in addition to all the insert/delete/update operations, duplicate those into an “audit” table of some kind. There may be even some business processes for recovering/rollback/cherry-picking values from that table.

                                      However another way you can do this is to imagine you have a single “changes” table. Inserts to it are cheap! it’s just file append! Then all of your queries go to materialised views (re)built from those changes. In a catastrophic situation it’s trivial to replay the log and get the views back. Or change the schema and replay so you get your data right. No migrations.

                                      It’s like patch theory for databases.

                                      Here you can see we have atomicity when we want it (simply block queries to the new views while you’re building them), consistency (all the new views are built together), integrity (duh), and durability. In fact, this approach is so easy, you’re likely to get it right the first time. Putting b-trees on disks on the other hand is what all the “database engines” do, and to get acceptable performance means handling a lot of edge cases. That makes a lot of code- places for bugs to hide.

                                      It’s a separation of concerns; you don’t want your language to implement a storage engine

                                      I’m not so sure. Being able to pickle/map disk-objects to values is incredibly valuable so why not a table?

                                      k/q supports serialising all data types (including lambdas, btw) so they can be sent over the network or written to the disk. On the disk, a table can become a directory where each column is a separate file. mmap() brings them into memory and their layout is similar enough to their purely-in-memory version that few operations need to know the difference. This feels like an extreme version of what I used to get out of hibernation/pickling, and yet it’s so simple! And look at all I get!

                          2. 1

                            Agreed, but I’d say the main downside (beside not amazing performance, even with PyPi) is the lack of meta-programming.

                            1. 1

                              There’s some support for metaprogramming in the form of metaclasses, and you can do lots of magic with magic methods, iterators and context managers. There are even hooks that you can call when a class instantiates from an abstract base class. It simply isn’t part of the culture to do lots of metaprogramming, as magic is frowned upon as not being the “one obvious way to do it”. But there are projects that rely heavily on this stuff. For example, the lxml builder uses magic methods a lot, and Django uses model introspection to autogenerate database migrations.

                              I respect the attitude of Python culture of insisting on simple code (and to be fair, Python code tends to be very readable by default), but it’s not my favourite language. Python is relentlessly imperative and the functional style is really frowned upon, it has no macros (the existing metaprogramming is too clumsy to express certain things) and whitespace indentation makes working with the REPL a total pain in the neck.

                              1. 2

                                I completely forgot about metaclasses, thanks for mentioning it. I actually learnt the basics of FP with Python 1.5 and the lambda/map/filter/reduce which at the time was already “ok, but don’t use it”. I continued to use it sporadically but found that list comprehension actually solved a lot of the use cases where I was using filter/map/reduce (although reduce in list comprehension is a bit of a headache). It’s weird, because I wouldn’t say Python is that imperative from a feature standpoint given that you can pass around functions, methods and classes (and now, even type descriptions), but seems to be, as you pointed it out, more culturally imperative. I wonder why that is, do you know happen to know the reasons behind this attitude/perception?

                                1. 2

                                  It seems Guido believes functional programming is hard to understand. Furthermore, it doesn’t fit his idea of Python, see this old Slashdot post (search for “functional programming”).

                            2. 1

                              The need of a fast, static typed Python with metaprogramming is what drove me to Nim.

                            1. 8

                              I switched to Visual Studio Code with Neovim backend yesterday. Neovim provides all the Ext functionality so you can :s/foo/bar to your heart’s content. It’s finally Good Enough to operate as a Vim without having to spend months tuning your .vimrc. I have been using Vim for 5+ years and wrote all my Go code in it.

                              I think this is what the future of Vim actually is for the majority of people: Neovim providing a backend for their preferred IDE. Interacting in a terminal is incredibly antiquated, even if it’s the sort of thing you are super used to. You can spend your time actually understanding and learning Vim, not trying to make Vim do what you think is reasonable/behaves like your previous editor of choice.

                              1. 5

                                Despite being somewhat of a diehard vim fan, 99% of my ‘vim’ usage these days is via emulators - either in VS, VSCode or Firefox.

                                For me the true value of vim is modal editing (and the associated muscle memory); the plugin ecosystem etc is fine (and at one point I spent a lot of time honing my plugin config) but there’s very little I miss.

                                1. 2

                                  My experience is the same. I don’t even have gVIm installed on my workstation anymore, but I love love working with the vim extensions in VS, Code, and Firefox.

                                2. 3

                                  Little off-topic, but what do you use to do that integration?

                                  1. 3

                                    The VSCode Vim plugin will do it out of the box, just check “Enable NeoVim”

                                  2. 2

                                    Maybe some day an interface to neovim will appear for Emacs, that would be a nice thing to happen. Perhaps I could start writing it, if I have a chance to learn elisp. Emacs as the extensible front end, with a proper modal backend. In fact the front end could be something better than Emacs, an scheme implementation would be amazing, in order to preserve separation of interests and provide users with a lightweight but infinitely extensible editing environment. If someone with adecuate skills for this (I don’t have them at the moment, so I will have to invest some time learning) is willing to start a with me such project, I would be more than honored to do so, if no interest is shown, eventually I would do it on my own.

                                    1. 2

                                      Check out Oni!

                                      1. 1

                                        Thanks for the recommendation, but I’m not interested in bringing the web to the desktop with the Electron framework, as exciting as it may be for many programmers I think it is still a bad idea. Personally, I think we don’t need tenths of MB in programs’ binaries in order to do text editing, and Javascript isn’t a coherent nor a well defined language to justify its expansion on servers and home computers, I think there are better alternatives to this. Nevertheless, if you like it and it solves your problems, then that’s all that matters in the end.

                                        1. 1

                                          I don’t actually use it - I use plain neovim in my terminal. I agree with you on the criticisms of electron - it’s just the only program of its kind that I’ve found.

                                          1. 2

                                            Sorry If I assumed something incorrect. Some of the ideas in Oni seem interesting, and would be a worthwhile effort to have a look at the source code.

                                  1. 14

                                    I do something like this as well, with the added layer of crazy that my dotfiles are a nix package which is installed and then linked into place.

                                    But really, all I want is unprivileged union mounts that work.

                                    1. 7

                                      But really, all I want is unprivileged union mounts that work.

                                      Plan 9, where art thou?

                                      I seriously don’t understand why Unix hasn’t evolved to be more like Plan 9 over the last few decades. It’s so clearly the right direction!

                                      1. 5

                                        Hey, do you have like a 10-second primer on plan 9? I always see people talking about it but have no idea how it differs from Unix.

                                        1. 7

                                          It’s sometimes said that in Unix, everything is a file. In Plan 9, everything is a filesystem, and they can be transparently or opaquely mounted on top of one another to customise the environment for each process.

                                          For example, where Unix has a special API for making network connections and configuring them, Plan9 has a particular filesystem path: write a description of the connection you want to make, read back a new path. Open that path, and the resulting file-descriptor is your TCP socket. If you want to forward your connections via another computer, you don’t need a special port-forwarding API or a VPN, you can just mount the remote computer’s network-connection filesystem over the top of your own, and everything that makes a network connection from then on will be talking to the TCP stack on the remote computer.

                                          1. 2

                                            I think Redox’ “Everything is a URL” is a nice improvement on Pan 9’s idea.

                                            1. 1

                                              Very interesting. Thanks!

                                            2. 1

                                              That’s a great question!

                                              I guess the big thing about Plan 9 is that it really tried to make everything a file. So using the network was just opening files, writing to the GUI was just writing to files &c. Really, the differences from Unix are mostly a result of that goal, e.g. in Plan 9 any user can create his own namespace of files & directories from other files & directories.

                                              The longer version would go into detail about how that actually worked (short version: really well).

                                          2. 4

                                            Do you have your Nix/dotfiles code somewhere?

                                            1. 3

                                              A more radical approach would be using rewritefs.

                                              1. 2

                                                I use home-manager, and mine looks as simple as:

                                                      home.file = {
                                                        ".stylish-haskell.yaml".source = ../stylish-haskell.yaml;
                                                        ".spacemacs".source = ../spacemacs;
                                                        ".ghci".text = ''
                                                          :set prompt "λ> "
                                                        '';
                                                      };
                                                
                                                1. 1

                                                  Me too! Some more stuff I do to manage simple scripts/aliases:

                                                  let
                                                    script = text: {
                                                      text = ''
                                                        #!/usr/bin/env bash
                                                        ${text}
                                                      '';
                                                      executable = true;
                                                    };
                                                  in {
                                                    # ...
                                                      home.file = {
                                                        "bin/gd" = script ''git diff "$@"'';
                                                        "bin/gds" = script ''git diff --staged "$@"'';
                                                        "bin/gf" = script ''git fetch --all "$@"'';
                                                        "bin/glg" = script ''git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr %cd) %C(cyan)%an%Creset' --date=format:'%d.%m' --abbrev-commit "$@"'';
                                                        "bin/gl" = script ''glg --all "$@"'';
                                                        "bin/gs" = script ''git status "$@"'';
                                                        # Show git branches in ~ "most recently used" order
                                                        "bin/git-bs" = script ''git branch --sort=-committerdate "$@"'';
                                                      };
                                                    # ...
                                                  };
                                                  

                                                  What I especially like about home-manager, is that it allows me to try and gradually migrate stuff to Nix, but I still can do e.g. nix-env -iA nixpkgs.umlet for quick additions/tests, and still have an escape hatch of sudo apt-get install ... if something is not available (or broken for me) in nixpkgs.

                                                  1. 1

                                                    You don’t need that script function. viz.:

                                                          programs.bash = {
                                                            ...
                                                            shellAliases = {
                                                              copy = "xclip -i -selection clipboard";
                                                              g = "git";
                                                              e = "emacs -nw";
                                                              ee = "emacs -nw $(fzf)";
                                                            };
                                                          };
                                                    
                                                          programs.git = {
                                                            ...
                                                            aliases = {
                                                              co = "checkout";
                                                              ci = "commit";
                                                              s = "status";
                                                              pr = "pull --rebase";
                                                              l = "log --graph --pretty='%Cred%h%Creset - %C(bold blue)<%an>%Creset %s%C(yellow)%d%Creset %Cgreen(%cr)' --abbrev-commit --date=relative";
                                                            };
                                                          };
                                                    
                                                  2. 1

                                                    I remember finding home-manager and was unsure if it worked or was testing on a not-NixOS system, so I kept using my Rube Goldberg setup :/

                                                    1. 1

                                                      I can confirm that home-manager works on OSX. The home.nix file I linked to above is used both on my Thinkpad running NixOS and my Macbook running macOS (via nix-darwin).

                                                      1. 1

                                                        I’m using it succesfully on Ubuntu 16.04.

                                                    2. 1

                                                      Oh, hey, I’ve been meaning to do that. Would you be willing to share your config?

                                                      1. 4

                                                        Here’s my nix expression which, in true FP style, is completely inscrutable:

                                                        { stdenvNoCC, stow, src ? ./. }:
                                                          
                                                        stdenvNoCC.mkDerivation {
                                                          inherit src;
                                                          name = "common-configs";
                                                          propagatedBuildInputs = [ stow ];
                                                          propagatedUserEnvPkgs = [ stow ];
                                                          buildPhase = ''
                                                            wd=$(pwd)
                                                            mkdir $wd/live
                                                            find . -maxdepth 1 -mindepth 1 -type d | \
                                                              grep -v 'work\|scripts\|nix' | \
                                                              while read d; do
                                                                stow --dir=$wd --target=$wd/live --stow $(basename $d)
                                                            done
                                                            echo $out > $wd/live/.config/store-address
                                                          '';
                                                          installPhase = ''
                                                            mkdir -p $out/etc/profile.d $out/cfg
                                                            cp -Lr . $out/cfg
                                                            mv $out/cfg/live $out/live
                                                            cat <<'EOF' >$out/etc/profile.d/stow-configs.sh
                                                            export PARALLEL_SHELL=/bin/sh
                                                            [ -e "$HOME/.config/store-address" ] && stow --dir=$(cat $HOME/.config/store-address) --target=$HOME --delete live
                                                            stow --dir=$(dirname $(realpath $HOME/.nix-profile/live)) --target=$HOME --stow live
                                                            # need to make sure systemd is using the latest unit files
                                                            systemctl --user daemon-reload
                                                            test -f $HOME/.nix-profile/live/.Xresources && xrdb -merge $HOME/.nix-profile/live/.Xresources
                                                            EOF
                                                          '';
                                                        }
                                                        

                                                        The src argument is a directory arranged like “programname/.dotfile”.

                                                        And this is called from a script I call nix-up:

                                                        #!/bin/sh
                                                        nix-channel --update
                                                        test -f "$HOME/lib/$(hostname).nix" &&
                                                        	nix-env --no-build-output --keep-going \
                                                        		--remove-all --install --file "$HOME/lib/$(hostname).nix"
                                                        if test -f "$HOME/.nix-profile/etc/profile.d/stow-configs.sh"; then
                                                        	echo swapping configs...
                                                        	. "$HOME/.nix-profile/etc/profile.d/stow-configs.sh"
                                                        fi
                                                        

                                                        That $(hostname).nix file has a list of packages and hooks the overlay that contains the above expression.

                                                        1. 1

                                                          Thanks! I’m excited to set it up.

                                                    1. 8

                                                      I’m going away for the weekend, we planned a trip to Holland with a couple of friends. I don’t thing much productive things will happen, at least not in the classical sense. But I feel I really need this. Lately I get the impression my mind is always busy, and I need some time to relax and recharge my emotional batteries.

                                                      The one thing I took with my is my trusty Kobo mini with ‘Writing An Interpreter In Go’ by Thorsten Ball. But I’m not completely sure I’ll get to it.

                                                      1. 5

                                                        Don’t try. Take the time for yourself!

                                                        1. 4

                                                          When I’m in Holland I love to go biking around in the polder landscapes. For example in Amsterdam the path that goes from Amstelpark south through Ouderkerk aan de Amstel and then something like this route (or whatever, it’s all good). It’s so quick to get out into beautiful surroundings. Mm, I miss Holland…

                                                          1. 2

                                                            I’m all the way down in Limburg, it’s very nice and quiet here. Lots of places to discover and while it’s cold at night, the weather is perfect for a walk during the day. I only went to Amsterdam twice, it’s definitely on my list to visit again!

                                                        1. 14

                                                          This is a great article, and I thoroughly agree with the substance. One thing that bothered me was that in a few cases, the article uses male pronouns to talk about hypothetical candidates. E.g.:

                                                          if I see that a person lights-up when he’s talking about programming (e.g. some cool stuff he has built over the summer/weekend) - he’s probably going to be a good developer in 2-3 years.

                                                          (emphasis mine)

                                                          @bndr, this is not to shame you or call you out specifically. In fact, I think this demonstrates how hard it can be to undo cultural norms: you use a non-gendered term (“a person”) in the same sentence. Another example from later on:

                                                          they may end up liking that domain even more than they do their current one. This is self-explanatory, as the intern doesn’t have many experiences, he may suddenly find a passion for something different.

                                                          (again, emphasis mine)

                                                          1. 7

                                                            Hey @mpcsh! Thanks for mentioning this, I do write “he” most of the times subconsciously , I will try to improve on this in the future!

                                                            1. 1

                                                              Good on you. I was worried about posting this given all the hostility and divisiveness in the world. Thank you for being open and honest :)

                                                            2. 0

                                                              Why does this bother you?

                                                              1. 1

                                                                Because I think language is important, and being inclusive is the right thing to do. Why do you ask?

                                                                1. 1

                                                                  Thanks for the explanation. If varyibg sets of pronouns are used, would that fulfill your inclusivity objective?

                                                                  1. 1

                                                                    What do you mean by “varying sets”? All that needs to be done is to change each occurrence of he/him/his to they/them/theirs.

                                                                    1. 1

                                                                      Well, I’ve often seen people just just multiple personas when giving examples. “When the programmer tries her method” mixed in with “When a developer publishes his library”, and so on. Provided both show up, that should be agreeable too no?

                                                                      1. 3

                                                                        They / them are the most appropriate pronouns for addressing a subject whose identity is undetermined, such as a hypothetical intern. Handily, these same words are perfectly good to use for any specific individual too.

                                                                        1. 0

                                                                          Meh. That seems like more effort on the part of the author, and while at best it’s the same as using neutral pronouns everywhere, it excludes people who don’t use he/him/his or she/her/hers. Using they/them/theirs is about as all-inclusive as English can afford, and people are already used to using they/them/theirs when talking about people in the abstract or hypothetical.

                                                              1. 2

                                                                On my personal time, I’m working on shipping a personal website to gather several blog posts I’ve scattered around in Medium recently.

                                                                I want to discover some static website generator as I’ve never used one before, trying to avoid Wordpress like the plague.

                                                                I’m also planning to deploy it through a docker-based method I’ve standardized around recently, that gives me auto-ssl and configures nginx proxy automatically.

                                                                1. 3

                                                                  Check out Gutenberg!

                                                                  1. 1

                                                                    Really cool static generator! I might probably go for it in the end.

                                                                    Thanks a lot!

                                                                1. 1

                                                                  To me, the beauty of the bullet journal is that there’s no right or wrong way to do it. My personal system isn’t anywhere near the original, but it works for me. The videos and other resources are nothing but a starting point. I don’t see why the idea of bullet journaling and the system discussed in the post are at odds at all.

                                                                  1. 3

                                                                    There’s nothing wrong with bullet journaling, but there’s a productivity flaw for it, I’ve seen so many people spending too much time on beautifying their journal, or make it more minimalism, or… keep it clean, in short, it’s very easy to be distracted by the unnecessary things instead of the note/to-do list itself when you go with bullet journal.

                                                                    1. 2

                                                                      Is that a productivity flaw or just a hobby that you don’t share? There’s nothing wrong with spending time on making a journal pretty. Minimalism might be king to you, but plenty of people find relaxation and catharsis in beautifying their journals. Perhaps being “distracted by the unnecessary things” is just the way you look at your own journal / todo list; perhaps others don’t find it distracting, but enhancing.

                                                                      1. 1

                                                                        If using a tool becomes a task of its own, it’s not helping you manage your tasks.

                                                                        1. 1

                                                                          Hobby != task. This varies person to person. For the record, I don’t beautify my bullet journal - I keep it minimal, with a different set of symbols & different use patterns than the “original”. It works for me.

                                                                          What about those who want to spend time on prettifying it? That’s not a “task of its own”, that’s a hobby. On what authority would you tell that person that their beautified bullet journal is “not helping [them] manage [their] tasks”?

                                                                          1. 1

                                                                            A task is anything you spend time on. Hobbies are something you spend time on. Therefore, a hobby is a task. No inherent negative connotation there.

                                                                            Now: what’s the point of an organizational system if you focus on the form over the function? Is the urge to beautify helping the user do what they need to do? If not, it’s a distraction. As a result, I would not recommend it to most people.

                                                                            On what authority? I have no authority; I have only reason & experience. Just like anyone else on the planet.

                                                                            1. 1

                                                                              You concede you have no authority, yet you’re prescribing actions to people that you don’t share experiences with. Perhaps organizational systems have different purposes to different people. Perhaps the things you value in an organizational system aren’t necessarily the things everyone (or even most people) value in an organizational system.

                                                                  1. 8

                                                                    I’ve got a Nintendo Switch and Breath Of the Wild coming in the mail tomorrow. I’ll also be spending time with my family.

                                                                    Not many other plans outside of that.

                                                                    1. 1

                                                                      BoTW is a fucking amazing game. You’ll have a blast.

                                                                      My girlfriend has been watching me play, she legitimately gets excited just watching and always wants me to play. You could definitely make some family time out of it!

                                                                      1. 1

                                                                        I bought BoTW in December of last year. Through light play sessions, plus some longer ones, I’m about to finish the game.

                                                                        Of course I could have finished it earlier but I just didn’t want it to end. Nowadays I’ve almost run out of things to do in the game.

                                                                        It’s that good.

                                                                      1. 6

                                                                        Is it not a little ironic that this is a medium site?

                                                                        1. 8

                                                                          Staying in a cabin in the Michigan backwoods. Weather is calling for a few rainy days, so likely I’ll be playing old SNES games on my Raspberry Pi :)

                                                                          1. 2

                                                                            Oh man that sounds so cozy. Extremely envious. Enjoy!!

                                                                          1. 13

                                                                            As a programmer with plenty of C experience I have two problems with this article. The first is that venn diagram. It implies that skilled programmers, for some measure of “skilled”, are not writing unsafe code. I thought everyone took it for granted that even the most skilled programmers will write segfaults. Certainly, even the most skilled programmers have shipped segfaults in the past.

                                                                            I also take issue with the description of the experience of Rust as being “fighting the borrow checker”. Bear in mind here that while I enjoy Rust, I’m by no means an evangelist; bear in mind also that I’m also coming at this from a formal languages / programming language design standpoint. I think it’s common experience to have to go through several rounds of revision before passing the Rust compiler. What isn’t common, and what I don’t understand, is why people see that as fighting the compiler. To me, this is the mark of a fantastic compiler: the compiler is there to help me write correct code. When rustc yells at me 7 ways ‘till Sunday, I know I need to rethink my code. It’s taught me more than a few things about systems programming.

                                                                            1. 4

                                                                              Any example of a situation in which creating commits like this helps?

                                                                              1. 3

                                                                                Let’s say you have some complicated history pattern with merges and so on. Lots of different developers doing lots of different things. After a bunch of merges and merge conflict resolutions you have a history of sorts, but you want to clean it up. This allows you to make a single commit where the end result is the tree matches the complex history you’d like to throw away.

                                                                                Very useful for keeping dev history clean.

                                                                                1. 1

                                                                                  Ah, that makes sense. So like a squashed merge, but without the merge. I guess it’s what git merge --squash --strategy=theirs would do if that merge strategy existed.

                                                                                  1. 1

                                                                                    Well, now that I think about it, wouldn’t saying –strategy=theirs be specifying just how conflicts are handled? My tool is saying, forget about conflicts, merging, everything, take the entire tree from the other commit wholesale. Don’t even try and merge things together.

                                                                                    1. 1

                                                                                      No, that’s what --strategy=recursive -X theirs does. The existing “ours” strategy just throws away the other commit and takes the tree from the current one. A fictional “theirs” strategy would do the same with the other tree.

                                                                                      Merge strategies and their options are pretty confusing.

                                                                                  2. 1

                                                                                    Wait… you use it to delete history? But… having that history around is the reason I use git?

                                                                                    1. 1

                                                                                      The last thing I want to do when fighting a production fire at 3am is be sorting through 12 merges of commits that look like:

                                                                                      • add feature
                                                                                      • whoops
                                                                                      • small fix
                                                                                      • review comments
                                                                                      • doh maybe this time.

                                                                                      squash that crap together! What commit broke the build is infinitely harder to figure out when the problem is in some chain of merges titled “whoops”

                                                                                      I decidedly prefer having my git history serve as a neatly curated form of documentation about the evolution of the codebase, not chaos of immutable trial and error

                                                                                      1. 2

                                                                                        I constantly bring this up in pull requests when I see shitty commit histories like that. Squash your damn commits! If you’ve already pushed a branch, create a new one with a new name, pick your commits on top of it, rebase -i and squash them into succinct relevant feature sets (or try to get as close as you can).

                                                                                        I realize this is once that’s already gone and it’s too late (history with a ton of “squishme: interum commit” bullshit in there) and that’s the purpose of tools like yours, but teaching people good code hygiene is pretty important too. :-P

                                                                                        1. 1

                                                                                          So I agree with you on this approach, but I think I’m still not grasping what your tool accomplishes. Couldn’t the situation you’re outlining here be accomplished by squashing?

                                                                                          1. 1

                                                                                            Yeah that last comment was really more of a discussion about why you might want to clean up git history. That’s a poor example for this tool.

                                                                                            This tool is useful when there’s multiple merges along two divergent branches of history and you want to make a commit that essentially contains the entire diff from your commit down to the merge-base of another commit combined with the diff from the merge-base back up to that other commit.

                                                                                            1. 1

                                                                                              Hmm, I guess I just can’t picture in what kind of situation that would happen. Could you explain the example chronologically?

                                                                                              1. 1

                                                                                                I think @jtolds is on significantly more complicated code bases than I’ve worked on. There was an earlier post about Octopus commits:

                                                                                                https://www.destroyallsoftware.com/blog/2017/the-biggest-and-weirdest-commits-in-linux-kernel-git-history

                                                                                                and here is a visual for what that would look like:

                                                                                                https://imgur.com/gallery/oiWeZmm

                                                                                  1. 8

                                                                                    What’s the use case here? Why marry these technologies? (I’m not criticizing; just confused)

                                                                                    1. 6

                                                                                      This is my one week at home between the end of my third year at UChicago and the start of my internship at Braintree. I’m spending a lot of time on my health: running to keep my body fit, snuggling with my puppo to keep my mind fit.

                                                                                      I’ve written a blog post about the basics of PLT. I have at least two more posts coming out this week that have been kicking around for a while. Stay tuned!

                                                                                      I’ve also spent time developing a hugo theme that suits my needs. I’m pretty happy with how it turned out! You can see it in action on my personal site.

                                                                                      I have a fun project in the works; it’s an interpreter for a silly language that was part of an incredible final-lecture game-day hackathon in my recent programming languages class. It can’t quite be made public yet, but I’m definitely going to write something up and share it as soon as possible.

                                                                                      I’m also culling through my dotfiles in anticipation of my coming internship. I recently spent a lot of time slimming them down to the extreme, just throwing out entire modules, in the name of minimalism. It’s been great. I want to continue slimming down and making my environment more visually consistent, as well as more focused. I’m endlessly frustrated by my shell: bash, zsh + oh-my-zsh, and fish all have their own quirks that bother me to no end. Per this commit in my dotfiles, I’m currently on “Revert “Revert “Revert “Revert “Revert “Revert “Move back to fish!”””””””. And that’s just the actual git reverts. If anyone has any suggestions for a clean, modern, minimal shell environment, I would really love to talk to you!

                                                                                      1. 2

                                                                                        I’m pretty happy with my current ZSH shell config. It uses antibody, so the config is pretty small with everything being pulled in from plugins (and I split the bits I did want from my old config out to plugins to make them reusable) and it’s not using any of the big frameworks like Oh My Zsh, or Prezto, so it’s fast compared to what I had before. If you’re interested, you can find it here.

                                                                                        1. 1

                                                                                          Hey, so I finally got around to taking a look and I really like your setup. Can you elaborate a bit on some of your custom plugins? I can’t find any descriptions for these:

                                                                                          haegin/zsh-magic-history
                                                                                          haegin/zsh-magic-completion
                                                                                          haegin/zsh-fzf
                                                                                          haegin/zsh-asdf
                                                                                          haegin/zsh-rationalise-dot
                                                                                          
                                                                                          1. 1

                                                                                            Sure thing. I’ll work on adding some readmes to those repos over the next day or so.

                                                                                            The shortest version is that they’re the bits of my shell config that I couldn’t find in existing plugins, but that’s probably not useful, so here’s a summary of each:

                                                                                            zsh-fzf - fzf is a fuzzy finder I use. This just sets up the plugin. zsh-asdf - asdf is a programming language version manager with plugins for different languages. This sets it up in the shell. zsh-rationalise-dot - this plugin sets zsh up so when you type more than 2 dots (..) in a row, each dot after the second adds /... zsh-magic-history - sets up history settings that work across multiple shells, so you don’t need to open a new shell to access history from other shells. zsh-magic-completion - this just copies completion settings from the repo I originally copied my config from (https://git.madduck.net/etc/zsh.git). I can’t remember what exactly I found myself missing when I didn’t have this, but I copied it over pretty quickly and haven’t taken the time to go through it to work out if I want to change anything else.

                                                                                            1. 1

                                                                                              Thanks, that helps a lot!!

                                                                                          2. 1

                                                                                            Ooooh, this is really tantalizing. I like this a lot. Thank you very much for the link!!

                                                                                        1. 6

                                                                                          I literally was so happy to see this post because (a) I’m glad to see this information being more widespread and (b) it’s exactly what I learned in my recent PL class.

                                                                                          You might imagine my surprise that it turned out to be my recent PL class… Hi Mark! (It’s Charles)

                                                                                          1. 4

                                                                                            Haha, hey Charles! CS221 for life :)

                                                                                            P.S. any interest in hacking on a monadic SNAPE? DM me if so!

                                                                                          1. 4

                                                                                            Minor adjustment: what was written here is mostly an interpreter. It’s probably worth noting the idea of a compiler targeting some other language (possibly a machine language). The idea of comparative linguistics and translation is important to introduce in any intro to PLT writeup.

                                                                                            1. 2

                                                                                              Good call. When actually writing interpreters (for example, the majority of my PL class), the two terms often get conflated.

                                                                                            1. 22

                                                                                              just hope you don’t have to do any string manipulation :)

                                                                                              1. 13

                                                                                                This. I have a good amount of experience writing C code and maintaining larger C applications, and C can be a real pain to deal with. Not to mention that it exposes a whole host of nasty security vulnerabilities. Finally, it seems a bit too low-level for these kinds of applications. I’m very confused by the choice of C here.

                                                                                                1. 3

                                                                                                  I’m guessing it’s because C is the main API for SQLite? I do I agree that C is an interesting choice here, maybe something more like Lua?

                                                                                                2. 4

                                                                                                  I agree. Writing secure C is hard. Sure, you can pledge your way out of it, but that doesn’t help if sensitive data is stolen. But what would be a reasonable alternative? Rust is probably too complex a language for the taste of OpenBSDers. Go?

                                                                                                  1. 2

                                                                                                    you can pledge your way out of it,

                                                                                                    You can’t. Their kernel and firmware still processes network-facing data. It might still do damage. How much is an unknown until the setup gets the kind of rigorous pentesting we see on Windows, Chrome, the SFI schemes, and recently x86 CPU’s. It does have a nice security by obscurity benefit on top of methods that provably increase work for attackers.

                                                                                                  2. 1

                                                                                                    There’s no string manipulation in HTTP servers, right?

                                                                                                    Right?

                                                                                                  1. 10

                                                                                                    By this point, you might be thinking that the obvious solution is to just disable push notifications entirely.

                                                                                                    After a few days, I realized that my brain had become so accustomed to my phone telling me what I needed to attend to, that I felt lost when I didn’t have those cues.

                                                                                                    How long did you try this for? I’ve completely disabled push notifications on my computer for a few months, and I think over time I’ve ended up compulsively opening email/slack/etc. less. What was important was not just removing the notifications, but other visual cues (for example, having my dock always visible on macOS, which would display little red icons). On the other hand, I think I would have little success if I tried to do this on my phone, so I don’t. I view my phone as less of a working tool anyways, so I’m okay with this. Most importantly, when I’m trying to focus I can reasonably restrict my access to my phone, but less so with my computer.

                                                                                                    I’ve personally struggled more with the idea that Something Very Important could have happened since I last checked in. The set of things that trigger this are much smaller, but they exist enough to be a problem at least every few days. For example, when I’m anticipating a results of an exam that I don’t think went particularly well, I tend to open email and check every time my mind drifts. I don’t think consuming content purely in digest form would fix this. Perhaps aggressive filtering would work, but I haven’t tried this and am generally suspicious of “productivity/mindfulness solutions” that require lots of active effort.

                                                                                                    1. 2

                                                                                                      I only tried it for about five days. Perhaps a longer experiment is in order. I’ve also done a lot of visual decluttering on my computer, e.g. removing my bar, notifications, etc.

                                                                                                      1. 3

                                                                                                        I can attest that both a minimal computing environment and disabling notifications have helped me transition out of a time when I was feeling similar to how you’ve described.

                                                                                                        1. 3

                                                                                                          This is really reassuring to hear, thank you :)