1.  

    My blog is primarily about Clojure https://yogthos.net/

    1. 4

      From 2016, but based on https://github.com/nextjournal it looks like they still use clojurescript. Would be great to see a 2018 followup.

      Also @Yogthos what are your thoughts on https://github.com/yogthos/clojure-error-message-catalog 2 years later? Is it still useful/necessary? Did it see traction/adoption? Is it being phased-out by upstream efforts?

      1. 4

        I got the inspiration for the error message catalog from Elm and it’s mostly a stop gap measure to help with most common gotchas. I don’t have the impression that it got a lot of adoption over the past couple of years which might indicate that most people aren’t struggling too much with the error message (or perhaps it just wasn’t discoverable enough). It also looks like Clojure 1.10 will have significantly improved error messages out of the box, and spec allows for tools like expound that produce human readable errors. I’m hopeful that the errors catalog won’t be necessary going forward.

      1. 3

        The link is to a very useless spam quora question. The email provider does exist (see wikipedia: https://en.wikipedia.org/wiki/Tutanota), but there’s no indication it’s particularly a Gmail alternative rather than just another mail provider.

        1. 2

          The link provides a good rationale for how the company operates and what their goals are. Their product is open source, and can be self-hosted, which is quite a bit more than just being another email provider in my opinion.

        1. 1

          Page not found :-(

          1. 2

            Looks like the site structure changed, here’s the new link.

          1. 7

            Worth noting that s-expressions avoid a lot of legibility problems discussed in the article. If we look at the first example under the “providing immediate feedback” section where traditional notation looks like:

            50.04 + 34.57 + 43.22 / 3
            

            this would be expressed as:

            (+ 50.04 34.57 (/ 43.22 3))
            

            which would be hard to confuse with:

            (/ (+ 50.04 34.57 43.22) 3)
            

            A lot of people seem to have the impression that s-expressions are harder to read than traditional syntax, but I find the opposite to be the case. With s-expressions you have simple and predictable rules that remove a lot of mental overhead around figuring out what the code is doing.

            1. 2

              Similarly just having the same precedence and associativity for everything would give you an easy-to-predict and easy-to-read syntax. This way you gain terseness, but you have to get used to the associativity of whatever mechanism you’re using, whereas s-expressions (or *shudder* XML, etc) are more portable, but require you to explicitly state the tree with more characters.

              For example, right associative:

              50.04 + 34.57 + 43.22 / 3
              

              And for the sum of everything over three, it would be:

              (50.04 + 34.57 + 43.22) / 3
              

              This is the style that APL/J/K and various languages inspired by them tend to use (they also add different precedence for certain operations that take another operation as one of their inputs, such as fold). Many people use such languages as an enhanced calculator (there are plotting utilities made for them, etc). For example, in K, where division is % and assignment is ::

              force: (6.67e-11*mymass*collidingmass)%radius*radius
              yearlybill: 12*rent+electric+internet
              

              Or with functions, where / is fold:

              force:{[m1;m2;radius](6.67e-11*m1*m2)%radius*radius}
              yearlybill:{[monthlyutilities]12*+/monthlyutilities}
              
              1. 1

                Then you get the situation that 1 * 2 + 3 and 3 + 1 * 2 mean different things, which is horrible, because people will always assume that they don’t.

                I don’t know why people have such a problem with a + b + c / 3 meaning a + b + (c / 3). It’s just something you have to get used to, it’s not really that difficult and there are much bigger problems that need solving. But if it’s really such a big deal, just make it a function \frac{a + b + c}{3} in LaTeX is good enough for mathematicians, so frac(a + b + c, 3) should be good enough for programmers.

                1. 1

                  Then you get the situation that 1 * 2 + 3 and 3 + 1 * 2 mean different things, which is horrible, because people will always assume that they don’t.

                  I don’t know why people have such a problem with 1 * 2 + 3 and 3 + 1 * 2 meaning different things. It’s just something you have to get used to when using a different language, it’s not really that difficult and there are much bigger problems that need solving.

                  1. 2

                    The universal rules of mathematical expressions create a strong precedent. People expect them to hold. They get confused when they don’t. Even if they are arbitrary.

                    I’m not aware of any language anywhere in all of programming or mathematics that uses different rules and has sustained any kind of popularity. Seems like a hard requirement to ever be successful in my experience.

                    1. 1

                      They aren’t “universal”. See my other comment. Sustained any kind of popularity is a vacuous statement Forth is used extensively in embedded applications. Your calculator uses a left to right operator precedence and yet you don’t struggle to translate from PEMDAS or whatever system you use.

                      1. 2

                        They are absolutely universal. All mathematicians agree on the order of operations here.

                        1. 2

                          Funny because every mathematician I’ve talked to, and listened to about order ambiguity agrees with me and says you should put parentheses to disambiguate.

                          The reality is that because it is cultural means it does not matter if you have a solution to the problem if not everyone is using it. In my opinion abandoning order of operations is much simpler and the order is arbitrary, needlessly convoluted, and does not afford for the expansion of operators. You can make things abundantly clear by using polish notation.

                          - / 2x 3y 1

                          Before you throw your arms up in frustration yes there are proofs done in this format, and they’re great.

                          1. 0

                            because it is cultural

                            Yeah but it isn’t cultural. It’s universal. as I’ve explained

                            1. 1

                              I suppose since it is universal that there are severe pedagogical deficiencies, which doesn’t surprise me terribly. Still would have been completely avoided with a simpler and clearer precedence system. It took me a while to realize that you were talking about strictly mathematicians whereas I was talking about all people. Apologies for my poor communication.

                    2. 1

                      “Order of operations” have been an arbitrary curse on mathematics since their creation, different cultures don’t actually agree, in addition it restricts the creation of new operators. I’m not particularly invested in left to right or right to left, but either would be much simpler than the random format we have now.

                      1. 2

                        Cultures that don’t use ÷ and × often don’t write sentences left-to-right and pages top-to-bottom. They might not even use arabic numerals.

                        I don’t see how it restricts the creation of new operators. Mathematicians seem to have no problem introducing new operators: ∧, ∨, →, ↔, dots, existing operators in circles and all sorts of silly new operators are used all over algebra without any real issue. If it’s not obvious from context, you put brackets in.

                        1. 1

                          What order precedence does modulus have? Is it the same as division or should it be done first, or last? If we had a order precedence that can accomodate new operators this question wouldn’t need to be asked and I wouldn’t have to use parentheses which lets be honest is a hack.

                          1. 1

                            Modulus isn’t a standard mathematical operator. But if you defined it, you could just say what its precedence is.

                    3. 1

                      wait are you using PEMDAS or BODMAS?

                      1. 1

                        Same thing. Brackets = parenthesis, multiplication and division are done at the same time and so their order is whatever sounds better when reading out the abbreviation. What synonym of exponent does ‘O’ stand for?

                        1. 1

                          Multiplication and division are not done at the same time. Orders I believe. http://www.math.harvard.edu/~knill/pedagogy/ambiguity/

                          1. 1

                            Multiplication and division are always done at the same time (with left-associativity - a÷b÷c = (a÷b)÷c in mathematics and this follows over into programming languages that use * and / to emulate × and ÷.

                            2x/3y-1 is not well-defined notation. It’s not mathematics, because mathematics doesn’t use a slash in the middle of some linear text for division (it uses a horizontal line or ÷ depending on the context, although really depending on the level, because I haven’t seen anyone use ÷ since primary school), and it’s not any programming language I’m aware of either. Randomly writing down some text then claiming it’s ambiguous is pretty silly.

                            2 × x ÷ 3 × y - 1 is completely unambiguous, on the other hand: (((2 × x) ÷ 3) × y) - 1. Try putting it into google, or asking someone what 2 × 9 ÷ 3 × 2 - 1 is. Their answer is 11.

                            Mathematicians almost never use ÷ anyway, we write (2 x) / (3 y) where the line is horizontal (not possible on this platform as far as I can tell). But the same rule applies to addition and subtraction: 2 + x - 3 + y - 1 is universally agreed to be (((2 + x) - 3) + y) - 1.

                            Programming languages usually approximate ÷ and × with / and * for the sake of ASCII, so the same rules apply as with those operators. I’m not sure I know of any programming language where you can multiply variables by juxtaposition.

                            I once saw a proposal that it should be based on whitespace: 1+x * 3+y would be (1 + x) * (3 + y), while 1 + x*3 + y would be 1 + x * 3 + y. I thought it was quite a cute proposal, if perhaps prone to error.

                            1. 2

                              Americans use a slash in the middle of linear text to mean division. You clearly didn’t even read the article. Just because you can do multiplication and division from left to right doesn’t mean that’s what people do.

                              1. 1

                                Americans use a slash in the middle of linear text to mean division.

                                Don’t think so.

                                You clearly didn’t even read the article.

                                The article has a bunch of monospace ASCII.

                                Just because you can do multiplication and division from left to right doesn’t mean that’s what people do.

                                It’s what literally everybody in the entire world does.

                1. 1

                  From what I see, there appear to be two distinct camps of Scala developers. The first camp consists of OO devs who are looking for a more modern Java, and the second camp consists of FP devs who are looking for a statically typed functional language on the JVM.

                  Nowadays Java is starting to address many of the gaps while Kotlin provides a much simpler alternative that focuses on the features that OO devs are looking for when considering Scala. I imagine that going forward Scala will become a hard sell for the OO crowd. Meanwhile, Scala is starting to have competition on the FP front from Eta which is a Haskell dialect that runs on the JVM and is able to leverage existing Haskell libraries.

                  The goal of simplifying the language with Dotty seems like a good idea, but it’s going to create a lot of friction for existing projects similarly to what we’re seeing happening with Python 3. I think that at this point Scala needs to clearly identify what specific problem it addresses that’s not addressed better by other languages.

                  1. 3

                    I think your assessment that Scala faces pressure from both Java/Kotlin as well as functional languages is spot on.

                    https://www.benfrederickson.com/ranking-programming-languages-by-github-users/ indicates that Scala lost 20% of its active users within a year, while Kotlin tripled its amount of active users, surpassing Scala by a large margin already.

                    The goal of simplifying the language with Dotty seems like a good idea […]

                    That’s not going to happen. The promises on conference slides do not reflect the reality.

                    There are already 6 or 7 new keywords, not speaking of other additions, and the cleanups do not depend on Scala 3 at all – in fact many of them have been implemented (and shipped behind a flag) for years already.

                  1. 2

                    As others have pointed out, email is a federated model that works just fine. Other federated services are no different in any practical way. The privacy issues with centralized services revolve around them actively working to mine your data. These companies are in the business of making money, and you are their product. This is the fundamental difference between using something like Twitter and Mastodon. Since commercial offerings are trying to monetize you, they have a lot of incentive to invade your privacy by demanding personal information, and to keep you engaged using their services.

                    The situation is very different with federated services. The code itself is open source allowing people to audit it, and fork it. If a service moves in a direction the community doesn’t like then they can fork the code, and set up new instances.

                    The federation model is open, meaning that you’re not tied to a specific service. Mastodon, Pleroma, and PeerTube all federate over ActivityPub. This also means that the model is designed for interoperability between services from ground up. Meanwhile, centralized commercial services that try to create walled gardens, and prevent you from moving data between them.

                    Access to the data for the services is democratized as well. The things you post on a public forum will obviously be public, however only the service provider has the ability to analyze it with commercial service. Federated services like Mastodon have no incentive from keeping the users from accessing the data. I think it’s a better situation where everybody has access to the data the service collects as opposed to just the providers themselves.

                    The scale advantage comes from the fact that you’re not stuck with a single provider. The system is inherently more robust, and not only in terms of technology. When you have a federation, it’s no longer possible to enforce a single set of rules for everybody. Twitter of Facebook get to choose what content you see, this allows them to sensor content and manipulate the network much more easily that you can with a distributed system.

                    1. 1

                      The privacy issues with centralized services revolve around them actively working to mine your data. These companies are in the business of making money, and you are their product.

                      This is a common error. Centralized doesn’t immediately equal evil or selling you out. It depends on how they’re set up. There’s companies that just sell you a service without trying to send your data to others. FastMail was a popular Gmail alternative whose users say it’s super-fast and stuff, too. MyKolab was a Swiss one I found for $5 a month with privacy policy. ProtonMail is a recent entry with crypto. HushMail is possibly the oldest of those. ZixCorp has similar services. The PGP company should probably be in this list.

                      That’s just email. There’s long been solutions doing similar things for chat, backups, mobiles, and so on. There’s just hardly anyone buying them. A few have been around a long time making money. Mostly selling to businesses, though. There is a market but won’t get you rich easily. One can build centralized, non-profit companies with charters protecting privacy. I’ve pushed this a long time. Also, put it in the EULA’s with EU-style penalties for privacy failures if users push for them. Maybe also in the hiring agreement for employees where they can refuse to work on surveillance or privacy-defeating features without termination. On top of that, one might build several of the same company in different countries as a public-benefit multi-national where they sort of check on each other but otherwise operate independently in their own market with tailored solutions.

                      There’s a lot of potential. There’s also companies taking care of their customers every day using tiny subsets of what I described. Often just owners or company culture that believes in it. People talking like all businesses are evil or have to sell out their customers do those businesses a disservice. Instead, we should try to see what protections we can build on top of those proven models in centralized form before telling people they have no choice but use decentralized stuff. I mean, we can have people developing both in parallel. I even encourage to mitigate impact of failures.

                      1. 2

                        Centralization might not immediately equal evil. But it eventually does. As things get bigger, they require more resources, at some non-linear rate.

                        So the only reason you can use those non-gmail services, the only way they can stay in business without “going evil” is to remain small enough that their requirements remain low. If they got as popular as gmail, they’d be trying to datamine our emails from grandma to sell us shit too.

                        There’s practically no examples of some large centralized thing not becoming evil. I don’t think this is solvable.

                        1. 2

                          Costco and Publix? Vanguard for investing?

                          1. 1

                            I’d say, instead, that centralization makes large-scale evil possible. Whether or not somebody steps up to the plate to take advantage of that possibility depends on how long the system exists, how big a scam they can run, and what social systems are in place to prevent it. If something is making a non-zero amount of money and exists for a few years, the likelihood that it’ll become a scam is pretty high.

                          2. 2

                            Centralization itself doesn’t equal selling you out, but the business model for current social media companies is what ultimately drives that. The way centralization plays into this is by locking you into the platform once you start using it. For me the biggest value of federation is that it removes central control from the platform. Anybody can run their own instance and manage it the way they see fit, and people can choose what instances they federate with.

                            I don’t really have any problem with businesses providing services, and as email shows it’s perfectly possible to do that on top of a federated model. My view is that this is a more robust model overall because it prevents companies from dictating how a service will work for everybody.

                            1. 1

                              “ but the business model for current social media companies is what ultimately drives that.”

                              I definitely agree with that. Now we’re in tricky territory, though. The uptake model for social media is it has to be easy to use/understand, preferably free if maximizing participants, and dirt cheap to scale if either free or low-cost. That already disqualifies most decentralized schemes people create. The last thing is people go where other people are. So, to bring in the masses, it needs to sort of already be popular at least among groups of them with some motivation for them to invite their friends. Those people are mostly locked into Facebook and such right now with lots of friends, family photos, etc they might stand to lose.

                              With that, I’m not sure how to make decentralized, private, social media take off in a big way. It’s one of the only types of applications I have no confidence in. That’s in general, not just decentralized. Only a small number of players even made huge waves. Fewer than that survived with any large usage. We might be stuck with a situation where they stay stuck on social media but we push private messaging as extra medium with other benefits like no limits on characters, immediate delivery, etc. Fortunately, a ton of people already moved to IM. It should be an easier sell than before.

                        1. 10

                          On a related note, it’s also worth noting that the user control situation is even worse on mobile devices. You pretty much can’t buy phones or tablets with unlocked firmware that you can easily put your own operating system on.

                          1. 10

                            Well there is the Librem at least.

                            https://puri.sm/shop/librem-5/

                            1. 1

                              It is my understanding that even this and Fairphone still require blobs and the baseband is totally opaque. The battle for complete user freedom on mobile still seems to be completely lost.

                              1. 3

                                This is correct. Purism routinely exaggerates about what they are able to provide in terms of openness, without any plausible way of actually delivering. It’s quite tiresome.

                                Not only will Librem 5 have blobs, they’ve now shamelessly announced they intend to use a loophole to procure FSF RYF certification despite this. If this is allowed to stand, it also makes RYF rather meaningless.

                            2. 7

                              Also Fairphone:

                              We offer the ability to choose between the Google experience and the freedom of open source. Both versions are officially supported by Fairphone and we will provide continuous software updates.

                              In addition, and because the code is openly available, everybody is free to work on making other operating systems work on the Fairphone 2. The community already offers alternative operating systems like Sailfish OS, Ubuntu Touch and LineageOS.

                              1. 2

                                Fairphone requires proprietary firmware blobs anyway.

                                1. 1

                                  Thanks, haven’t seen Fairphone before. I really hope there will be enough of a niche for companies like them and Librem going forward.

                                  1. 5

                                    As a Fairphone user: the market is made by buying the damned phones.

                                    I wish there was an official Sailfish distro. I’m a happy user of the community port, but I also tolerate some glitches. Like not being able to calibrate the proximity sensor or run android apps.

                                    But, as stated, they do have a non-Google android for those who want to be closer to the mainstream and a Google android for people who don’t care that much.

                                2. 2

                                  You can unlock the bootloader on most Android phones and you can run LineageOS or other AOSP forks, sometimes Ubuntu Touch and Sailfish ports, or postmarketOS.

                                  You typically have to run the vendor android kernel fork if you want to have useful functionality, but some devices (Nexus 5, Nexus 7, Xperia Z2, Xperia Z2 Tablet) can run mainline Linux.

                                  https://wiki.postmarketos.org/wiki/Devices

                                  1. 1

                                    I know that you can unlock the bootloader, but I think that’s very far from ideal. Also the tools themselves tend to be closed source, and sketchy. You should be able to decide what runs on your phone without jumping through hoops.

                                1. 10

                                  This is the same tired argument in favor of static typing that you see in every blog. The problem is that while the arguments sound convincing on paper, there appears to be a serious lack of empirical evidence to support many of the benefits ascribed to the approach. Empiricism is a critical aspect of the scientific method because it’s the only way to separate ideas that work from those that don’t.

                                  An empirical approach would be to start by studying real world open source projects written in different languages. Studying many projects helps average out differences in factors such as developer skill, so if particular languages have a measurable impact it should be visible statistically. If we see empirical evidence that projects written in certain types of languages consistently perform better in a particular area, such as reduction in defects, we can then make a hypothesis as to why that is.

                                  For example, if there was statistical evidence to indicate that using Haskell reduces defects, a hypothesis could be made that the the Haskell type system plays a role here. That hypothesis could then be further tested, and that would tell us whether it’s correct or not. This is pretty much the opposite of what happens in discussions about static typing however, and it’s a case of putting the cart before the horse in my opinion.

                                  The common rebuttal is that it’s just too hard to make such studies, but I’ve never found that to be convincing myself. If showing the benefits is truly that difficult, that implies that static typing is not a dominant factor. One large scale study of GitHub projects fails to show a significant impact overall, and shows no impact for functional languages. At the end of the day it’s entirely possible that the choice of language in general is eclipsed by factors such as skill of the programmers, development practices, and so on.

                                  I think it’s important to explore different approaches until such time when we have concrete evidence that one approach is strictly superior to others. Otherwise, we risk repeating the OOP hype when the whole industry jumped on it as the one true way to write software.

                                  1. 6

                                    One large scale study of GitHub projects fails to show a significant impact overall, and shows no impact for functional languages.

                                    That is not the language used by the authors of the paper:

                                    The data indicates functional languages are better than procedural languages; it suggests that strong typing is better than weak typing; that static typing is better than dynamic; and that managed memory usage is better than un-managed.

                                    1. 2

                                      Look at the actual results in the paper as opposed to the language.

                                    2. 3

                                      Annecdote but Typescript exists purely to make an existing language use static types. It has near universal appeal among those who have tried it, and in my experience an entire class of errors disappeared overnight while being having almost no cost at all apart from the one-time transition cost

                                      Meanwhile “taking all projects will average things out” is unlikely to work well. Language differences are rarely just about types, and different languages have different open source communities with different skill levels and expectations

                                      1. 3

                                        As much as I like empiricism and the “there’s not actually that much difference” hypothesis, that article has flaws. In particular, it has sloppy categorization, fex classifying bitcoin as “typescript”. Also, some of its conclusions set off my “wait what” meter, such as Ruby being much safer than python and typescript being the safest language of all.

                                        1. 3

                                          The study has many flaws, and by no means does it provide any definitive answers. I linked it as an example of people trying to approach this problem empirically. My main point is that this work needs to be done before we can meaningfully discuss the impacts of different languages and programming styles. Absent empirical evidence we’re stuck relying on our own anecdotal experiences, and we have to be intellectually honest in that regard.

                                        2. 2

                                          That link doesn’t seem to be working. Is this the same study?: http://web.cs.ucdavis.edu/~filkov/papers/lang_github.pdf

                                          I think you make very good points (even though I currently have a preference for static types). I’d love to see more empirical evidence.

                                          1. 1

                                            Thanks, and that is the same study. It’s far from perfect, but I do think the general idea behind it is on the right track.

                                            1. 2

                                              I only skimmed the study, but doesn’t it actually show a small positive effect for functional languages? From the study:

                                              Result 2: There is a small but significant relationship between language class and defects. Functional languages have a smaller relationship to defects than either procedural or scripting languages.

                                              I realise that overall language had a small effect on defect rate, and they noted that it could be due to factors like the kind of people attracted to a particular language, rather than language itself.

                                              1. 4

                                                The results listed show a small positive effect for imperative languages, and no effect among functional ones. In fact, Clojure and Erlang appear to do better than Haskell and Scala pretty much across the board:

                                                lang/bug fixes/lines of code changed
                                                Clojure  6,022 163
                                                Erlang  8,129 1,970
                                                Haskell  10,362 508
                                                Scala  12,950 836
                                                
                                                defective commits model
                                                Clojure −0.29 (0.05)∗∗∗
                                                Erlang −0.00 (0.05)
                                                Haskell −0.23 (0.06)∗∗∗
                                                Scala −0.28 (0.05)∗∗∗
                                                
                                                memory related errors
                                                Scala −0.41 (0.18)∗
                                                0.73 (0.25)∗∗ −0.16 (0.22) −0.91 (0.19)∗∗∗
                                                Clojure −1.16 (0.27)∗∗∗ 0.10 (0.30) −0.69 (0.26)∗∗ −0.53 (0.19)∗∗
                                                Erlang −0.53 (0.23)∗
                                                0.76 (0.29)∗∗ 0.73 (0.22)∗∗∗ 0.65 (0.17)∗∗∗
                                                Haskell −0.22 (0.20) −0.17 (0.32) −0.31 (0.26) −0.38 (0.19)
                                                

                                                The study further goes to caution against overestimating the impact of the language:

                                                One should take care not to overestimate the impact of language on defects. While these relationships are statistically significant, the effects are quite small. In the analysis of deviance table above we see that activity in a project accounts for the majority of explained deviance. Note that all variables are significant, that is, all of the factors above account for some of the variance in the number of defective commits. The next closest predictor, which accounts for less than one percent of the total deviance, is language.

                                                This goes back to the original point that it’s premature to single out static typing as the one defining feature of a language.

                                        1. 3

                                          I still find it really weird that everyone in clojure calls them “specs” and never uses the word “contract”.

                                          Don’t get me wrong, contracts are both amazing and criminally underused, but they’re not a new or groundbreaking idea. This would just be a terminology peeve, except I’ve met more than a few clojurists who thought spec was wholly unique to clojure.

                                          1. 1

                                            As you note, runtime contracts are very much underused and most people aren’t familiar with the concept. Since Rich decided to call them specs everybody working with Clojure calls them that now. It’s really unfortunate Racket contract system isn’t well known, as it’s quite comprehensive and was clearly an inspiration for Spec.

                                          1. 2

                                            Would cubicles be better? That’s one cost efficient way to turn an office to a non-open office, I think 🤔

                                            1. 2

                                              Cubes combine the distracting background noise of an open plan office with having to sit by yourself :/

                                              1. 2

                                                Cubicles are far better than open offices in my opinion.

                                                1. 3

                                                  Agreed - while headphones can at least block out audible distractions in an open-office plan, there’s nothing to be done for people shooting hoops and reenacting last night’s Warriors game, or people trying to circumvent my “do not disturb” notice on Slack by waving their hands in front of my monitor (both actual examples at $OLDJOB). Visual distractions, at least for me, are just as bad!

                                                  1. 1

                                                    Not really. Noise is way more disturbing if you can’t see it’s source, apparently.

                                                1. 3

                                                  I think remote flexibility is a solution. I would hate my open office less if I wasn’t forced to be in it and could just come by a few times a week.

                                                  1. 9

                                                    The fact that the option to work remotely is not a standard thing in 2018 is just shocking in my opinion. Vast majority of people working in tech end up commuting just to sit in front of a computer in a different place. The whole model of having people clock in and out is based around factory work. It makes absolutely no sense for creative activities like programming. You don’t have a steady output as a coder, and you’re not going to be productive for 8 contiguous hours a day.

                                                    I also think that remote work is one of the most practical ways to combat traffic congestion in big cities. If everybody who works with a computer would get off the road then we’d have drastically less traffic in cities.

                                                    It doesn’t even have to be all or nothing, as you point out a mix of coming to the office a few times a week and working from home when you don’t need to be there would be a huge improvement. There’s also benefit for the companies as they would need a lot less office space.

                                                    1. 6

                                                      It says a lot about the business world that this idea is considered radical.

                                                      1. 3

                                                        Agreed on all counts. I just think it’ll be hard to find a workplace that truly commits to abandoning work hours and trusting that the engineers will deliver better. I would even sign a piece of paper that says “if my work output decreases, I’ll stop”.

                                                    1. 9

                                                      The worse open-plan office I’ve been in is when developers were sharing the room with marketing. There was time it was literally impossible to work or concentrate. On busy day, marketing guys would spend all day talking loud on the phone. On quiet days, they’ll spend most of the time chatting loudly with each others. Even when I had urgent work, I had no choice but to give up and browse the web or go out, since I couldn’t do any work. Talk about productivity.

                                                      It’s not even a criticism of the marketing department - they enjoy their job and good for them, but it was absurd to put us all in the same room.

                                                      1. 8

                                                        Having an open office is basically telling your employees that you see them as nothing more than cattle.

                                                        1. 4

                                                          Well said, if it works with chickens or cows, surely it must work with humans. ¬¬

                                                          1. 3

                                                            Isn’t that the plot of Texas Chainsaw Massacre 2?

                                                      1. 14

                                                        I’ve been using Macs for nearly a decade on the desktop and switched to Linux a couple of months ago. The 2016 MacBook Pro finally drove me to try something different. Between macOS getting more bloated each release, defective keyboard, terrible battery life, and the touch bar I realized that at some point I stopped being the target demographic.

                                                        I switched to Manjaro and while there are a few rough edges as the article notes, overall there really isn’t that much difference in my opinion. I’m running Gnome and it does a decent enough job aping macOS. I went with Dell Precision 5520, and everything just worked out of the box. All the apps that I use are available or have equivalents, and I haven’t found myself missing anything so far. Meanwhile it’s really refreshing to be able to configure the system exactly the way I want.

                                                        Overall, I’d say that if you haven’t tried Linux in a while, then it’s definitely worth giving another shot even though YMMV.

                                                        1. 4

                                                          terrible battery life

                                                          Really? It’s that bad? The Dell is better?

                                                          1. 3

                                                            I don’t know about Dell, but my 2016 MacBook Pro was hit pretty hard after the Specter/Meltdown fix came out. I used to go 5 or 6 hours before I was down to 35-40%. Now I’m down to %20-25% after about 4 hours.

                                                            1. 2

                                                              Same here. I wonder if the specter/meltdown fiasco has at all accelerated Apple’s (hypothetical) internal timeline for ARM laptops. Quite the debacle.

                                                              In regards to the parent, I have actually been considering moving from an aged Macbook Pro 15” (last of the matte screen models – I have avoided all the bad keyboards so far), to a Mac /desktop/ (mac pro maybe). You can choose your own keyboard, screen, and still get good usability and high performance. Then moving to a linux laptop for “on the road” type requirements. Being able to leave work “at my desk” might be nice too.

                                                              (note: I work remotely)

                                                              1. 3

                                                                I honestly don’t understand the fetish for issuing people laptops, particularly for software development type jobs. The money is way better spent (IMHO) on a fast desktop and a great monitor/keyboard.

                                                                1. 2

                                                                  Might be the ability to work remotely. I’m with you, though, that laptops are a bizarre fetish, as is working from Anywhere You Want(!)

                                                                  1. 2

                                                                    It’s an artifact of, among other things, the idea that you PURSUE YOUR PASSIONS and DO WHAT YOU LOVE*; I don’t want to “work anywhere” – I want to work from work, and leave that behind when I go home to my family. But hey, I’m an old, what do I know.

                                                                    *: what you love must be writing web software for a venture funded startup in San Francisco

                                                                2. 2

                                                                  Same here. I wonder if the specter/meltdown fiasco has at all accelerated Apple’s (hypothetical) internal timeline for ARM laptops.

                                                                  I wouldn’t guess that. Apples ARM design was one of the few also affected by meltdown. Using it for a laptop wouldn’t have helped.

                                                                  1. 1

                                                                    I bought a Matebook X to run Arch Linux on and it’s been pretty great so far.

                                                                    1. 1

                                                                      I’ve been thinking about a librem 13. I’ll take a look at the matebook too. Thanks!

                                                                3. 2

                                                                  Yeah I get 4-6 hours with the Dell, and I was literally getting about 2-3 hours on the Mac with the same usage patterns and apps running. I think the fact that you can be a lot more granular regarding what’s running on Linux really helps in that regard.

                                                                  1. 5

                                                                    +1 about deciding what you run on GNU/Linux.

                                                                    I have a Dell XPS 15 9560 currently running Arch (considering switching to NixOS soon), and with Powertop and TLP set up I usually get around 20 hours (yes, 20 hours) per charge on light/normal use.

                                                                    1. 1

                                                                      Ha! Thanks for this I didn’t know these were available!

                                                                      1. 1

                                                                        No problems! They’re very effective, and are just about the first package I install on a new setup.

                                                              1. 4

                                                                Barliman is another similar system, there’s a video discussing their approach in detail here.

                                                                1. 4

                                                                  Having built large apps with both approaches, I think SPA is the right way to develop any non-trivial web apps. One huge advantage of SPA approach is that you have clear separation between the client and the server. The client manages all the UI state, and the server provides a query API for the client.

                                                                  Managing the state client-side makes a lot of sense in practice. It’s easier to reason about, you end up sending less data across, and you generally have a smoother user experience because you have less refreshes happening.

                                                                  This approach also allows for building alternate UIs later on, such as native apps. Since you end up with a service API from the start, it’s much easier to write alternative clients against it in the future.

                                                                  There are also benefits on the server-side as well. Since the state is managed on the client, the server can be stateless making caching, horizontal scaling, and load balancing much simpler. The server code becomes much simpler as well as it turns into a set of independent operations handling different types of queries by the client.

                                                                  I think a lot of the reservations around SPAs come from poor tooling and frameworks available in JavaScript. However, alternative languages provide a much better experience nowadays. This article has a nice comparison across some Js frameworks and compile-to-Js languages like Elm and ClojureScript. My team works with ClojureScript, and we use re-frame for all our front-end development.

                                                                  ClojureScript addresses many of the pain points present in Js ecosystem. The language itself is much cleaner and simpler than Js. The tooling is much better as well. Leiningen manages dependencies, runs tests, hot loads code during development, and packages the release artifacts. This is typically accomplished by a bundle of tools in Js ecosystem with varying degrees of success. The compiler prunes unused code, does code splitting, and minifies release artifacts out of the box. A lot of these things are either difficult or outright impossible to do well with plain Js. Meanwhile, interop with Js is pretty seamless, and it’s possible to leverage Js libraries out of the box.

                                                                  For example, I’m using React Semanitc UI in a project currently. Here are the steps I needed to leverage it:

                                                                  1. add the dependency to the project [cljsjs/semantic-ui-react "0.81.1-0"]
                                                                  2. require the library in the namespace (:require [cljsjs.semantic-ui-react :as ui])
                                                                  3. use its components: [:> ui/Menu [:> ui/MenuItem {:name “Home” :onClick #(js/alert “Hello”)}]]

                                                                  If Js is what’s stopping you from moving your UI to the front-end I highly recommend taking a look at ClojureScript. This workshop is a good walkthrough a small project from start to finish. I recommend spending a few minutes working through it to get a feel for the workflow.

                                                                  1. 2

                                                                    Opened the blog and saw the box about how dynamic typed languages are easier to use (as in what people think).

                                                                    Dynamically typed languages don’t enforce any type checking and hence anything could happen. I love static typing and have never felt underpowered whilst using it.

                                                                    1. 13

                                                                      There’s a spectrum here. I’m guessing that when you use static typing, you’re probably not using SPARK, Dafny, or Liquid Haskell. Compare to them, most statlangs are pretty weak in what they can actually tell you. In those languages, you can also statically verify behavior, like “this procedure always terminates” or “this function is always called with a nonempty list and returns the same list, but sorted.”

                                                                      The problem is that they’re a lot harder to use. It’s the standard expressiveness vs legibility tradeoff here: the more valid expressions you can write in a language, the fewer properties they all share in common. Statically-typed languages have more expressiveness and less legibility than formally verifiable languages, and dynlangs have more expressiveness and less legibility than statlangs. In return for losing static typechecking, you get the ability to leverage the complete runtime language for defining types. For example, in Python you can define the type of all classes with an odd number of letters in their name, and in J you can define the obverse (quasi-inverse) of a function.

                                                                      I think most popular dynamics end up too expressive with not enough legibility. My justification is how rapidly gradual type-checkers are spreading. It implies that the parts of the dynlangs being used aren’t the bits that require the crazy expressivity dynamic typing gives you, so it’s worth adding legibility. But there’s still a lot space left to explore.

                                                                      1. 14

                                                                        Opposite experience here. I’ve worked with many kinds of statically typed languages, including Java, Haskell, and Scala for nearly a decade. I ultimately found that static typing introduces a lot of mental overhead in practice, and limits the way you’re able to express yourself. Many dynamic patterns such as Ring middleware become difficult in static languages. I’ve been working with Clojure about 8 years now, and I don’t miss types in the slightest. If I did, I would’ve gone back to a typed language a long time ago.

                                                                        Dynamic typing tends to be problematic in imperative/OO languages. One problem is that the data is mutable, and you pass things around by reference. Even if you knew the shape of the data originally, there’s no way to tell whether it’s been changed elsewhere via side effects. The other problem is that OO encourages proliferation of types in your code. Keeping track of that quickly gets out of hand.

                                                                        What I find to be of highest importance is the ability to reason about parts of the application in isolation, and types don’t provide much help in that regard. When you have shared mutable state, it becomes impossible to track it in your head as application size grows. Knowing the types of the data does not reduce the complexity of understanding how different parts of the application affect its overall state.

                                                                        My experience is that immutability plays a far bigger role than types in addressing this problem. Immutability as the default makes it natural to structure applications using independent components. This indirectly helps with the problem of tracking types in large applications as well. You don’t need to track types across your entire application, and you’re able to do local reasoning within the scope of each component. Meanwhile, you make bigger components by composing smaller ones together, and you only need to know the types at the level of composition which is the public API for the components.

                                                                        REPL driven development also plays a big role in the workflow. Any code I write, I evaluate in the REPL straight from the editor. The REPL has the full application state, so I have access to things like database connections, queues, etc. I can even connect to the REPL in production. So, say I’m writing a function to get some data from the database, I’ll write the code, and run it to see exactly the shape of the data that I have. Then I might write a function to transform it, and so on. At each step I know exactly what my data is and what my code is doing.

                                                                        Where I typically care about having a formalism is at component boundaries. Spec provides a much better way to do that than types. The main reason being that it focuses on ensuring semantic correctness. For example, consider a sort function. The types can tell me that I passed in a collection of a particular type and I got a collection of the same type back. However, what I really want to know is that the collection contains the same elements, and that they’re in order. This is difficult to express using most type systems out there, while trivial to do using Spec.

                                                                      1. 2

                                                                        This problem is solved beautifully by multimethods in Clojure. For example, you could do:

                                                                        (defmulti get-speed :type)
                                                                        
                                                                        (defmethod get-speed :european [bird]
                                                                          (:speed bird))
                                                                        
                                                                        (defmethod get-speed :african [bird]
                                                                          (- (:speed bird) (:load-factor bird)))
                                                                        
                                                                        (defmethod get-speed :norwegian-blue [bird]
                                                                          (if (:nailed bird) 0 (:speed bird)))
                                                                        
                                                                        (defmethod get-speed :default [_]
                                                                          0)
                                                                        

                                                                        The really handy part is that the multimethod is open, so anybody can implement their own defmethod for a new case without having to change any existing code. This makes it a really useful tool for providing extensible library APIs. I use this pattern in my reagent-forms UI component library that provides an init-field multimethod that can be used by the users to implement their own custom widgets.

                                                                        1. 4

                                                                          Java is a language, while Node is a runtime. Node should be compared against the JVM because each platform can be targeted by different languages. For example, I can target both Node and the JVM with Clojure. In that scenario the problems regarding locking threads don’t exist because Clojure is designed to be thread safe and it provides tools, such as atoms, for working with shared mutable state.

                                                                          My experience targeting both the JVM and Node, is that the JVM provides a much simpler mental model for the developer. The JVM allows you to write predominantly synchronous code, and the threads are used to schedule execution intelligently ensuring that no single chunk of code hogs the CPU for too long. With Node you end up doing scheduling by hand, and it’s your responsibility to make sure that your code isn’t blocking the CPU.

                                                                          Here’s a concrete example from a script I ended up writing on Node:

                                                                          (defn post-status-with-images
                                                                            ([status-text urls]
                                                                             (post-status-with-images status-text urls []))
                                                                            ([status-text [url & urls] ids]
                                                                             (if url
                                                                               (.get (if (string/starts-with? url "https://") https http) url
                                                                                     (fn [image-stream]
                                                                                       (post-image image-stream status-text #(post-status-with-images status-text urls (conj ids %)))))
                                                                          (post-status status-text (not-empty ids)))))
                                                                          

                                                                          here’s what the JVM equivalent would look like:

                                                                          (defn post-status-with-images [status-text urls]
                                                                            (future (post-status status-text (map post-image urls))))
                                                                          

                                                                          You could use promises or async to make the Node example a bit cleaner, but at the end of the day you’re still doing a lot more manual work and the code is more complex than it would’ve been with threads.

                                                                          1. 1

                                                                            Couldn’t this be better described as a limitation of the implementation Clojure on Node and not actually node?

                                                                            1. 2

                                                                              I don’t really see how that’s the case. The problem I’m describing is that Node has a single execution thread, and you can’t block it. This means that the burden of breaking up your code into small chunks and coordinating them is squarely on the developer.

                                                                              As I said, you could make the code a bit more concise, but the underlying problem is still there. For example, I used promises here, but that’s just putting on a bandaid in my opinion.

                                                                              Threads are just a better default from the developer perspective, and it’s also worth noting that you can opt into doing async on the JVM just fine if you really wanted to. It’s not a limitation of the platform in any way.

                                                                              1. 1

                                                                                Threads are just a better default from the developer perspective

                                                                                There is the caveat that threads (at last in the JVM) dramatically increase the complexity of the memory model and are generally agreed to make it harder to write correct code. Single threaded event-loop style programs don’t remove the chance of race conditions and dead locks but they remove a whole class of issues. Personally, I like something like the Erlang model which is fairly safe and scales across hardware threads. My second personal preference is for a single threaded event-loop (although I generally use it in Ocaml which makes expressing the context switches much more pleasant than in JavaScript/Node).

                                                                                1. 1

                                                                                  The part about it being harder to write correct code only applies to imperative languages though. This is why I’m saying that it’s important to separate the platform from the language. I like the Erlang model as well, however shared nothing approach does make some algorithms trickier.

                                                                                  Personally, I found Clojure model of providing thread safe primitives for managing shared mutable state to work quite well in practice. For more complex situations the CPS model such as core.async or Go channels is handy as well in my experience.

                                                                          1. 42

                                                                            GitLab is really worth a look as an alternative. One big advantage of GitLab is that the core technology is open source. This means that anybody can run their own instance. If the company ends up moving in a direction that the community isn’t comfortable with, then it’s always possible to fork it.

                                                                            There’s also a proposal to support federation between GitLab instances. With this approach there wouldn’t even be a need for a single central hub. One of the main advantages of Git is that it’s a decentralized system, and it’s somewhat ironic that GitHub constitutes a single point of failure.

                                                                            1. 17

                                                                              Federated GitLabs sound interesting. The thing I’ve always wanted though is a standardised way to send pull requests/equivalent to any provider, so that I can self-host with Gitea or whatever but easily contribute back and receive contributions.

                                                                              1. 7

                                                                                git has built-in pull requests They go to the project mailing list, people code review via normal inline replies Glorious

                                                                                1. 27

                                                                                  It’s really not glorious. It’s a severely inaccessible UX, with basically no affordances for tracking that review comments are resolved, for viewing different slices of commits from a patchset, or integrating with things like CI.

                                                                                  1. 7

                                                                                    I couldn’t tell if singpolyma was serious or not, but I agree, and I think GitHub and the like have made it clear what the majority of devs prefer. Even if it was good UX, if I self-host, setting up a mail server and getting people to participate that way isn’t exactly low-friction. Maybe it’s against the UNIX philosophy, but I’d like every part of the patchset/contribution lifecycle to be first-class concepts in git. If not in git core, then in a “blessed” extension, à la hub.

                                                                                    1. 2

                                                                                      You can sort of get a tracking UI via Patchwork. It’s… not great.

                                                                                      1. 1

                                                                                        The only one of those Github us better at is integration with CI. They also have an inaccessible UX (doesn’t even work on my mobile devices, can’t imagine if I had accessibility needs…), doesn’t track when review comments are resolved, and there’s no UX facility for viewing different slices, you have to know git stuff to know the links

                                                                                      2. 3

                                                                                        I’ve wondered about a server-side process (either listen on http, poll a mailbox, etc) that could parse the format generated by git request-pull, and create a new ‘merge request’ that can then be reviewed by collaborators.

                                                                                        1. 2

                                                                                          I always find funny that usually, the same people advocating that emails are a technology with many inherent flaws that cannot be fixed, are the same people that advocate using the built in fit feature using emails…

                                                                                      3. 6

                                                                                        Just re: running your own instance, gogs is pretty good too. I haven’t used it with a big team so I don’t know how it stacks up there, but I set it up on a VPS to replace a paid Github account for private repos, where it seems fast, lightweight and does everything I need just fine.

                                                                                        1. 20

                                                                                          Gitea is a better maintained Gogs fork. I run both Gogs on an internal server and Gitea on the Internet.

                                                                                          1. 9

                                                                                            Yeah, stuff like gogs works well for private instances. I do find the idea of having public federated GitLab instances pretty exciting as an alternative to GitHub for open source projects though. In theory this could work similarly to the way Mastodon works currently. Individuals and organizations could setup GitLab servers that would federate between each other. This could allow searching for repos across the federation, tagging issues across projects on different instances, and potentially fail over if instances mirror content. With this approach you wouldn’t be relying on a single provider to host everybody’s projects in one place.

                                                                                          2. 1

                                                                                            Has GitLab’s LFS support improved? I’ve been a huge fan of theirs for a long time, and I don’t really have an intense workflow so I wouldn’t notice edge cases, but I’ve heard there are some corners that are lacking in terms of performance.

                                                                                            1. 4

                                                                                              GitLab has first-class support for git-annex which I’ve used to great success