1. 5

    How do you think the person who submitted this neat project feels when only a tiny fraction of the replies to their submission even talk about it?

    tldr: It drives new contributors away from the community.

    I came across a paper recently (Understanding lurkers in online communities) that covers this question and I quote below (poster refers to someone already contributing to the community):

    A lack of reciprocity also stops members from contributing. Lurkers were more sensitive to community reciprocity and out- come than posters (Fan et al., 2009), and the attitudes of lurkers were more influenced by reciprocity norms, whereas posters were more affected by social trust (Liao & Chou, 2012). Thus, lurkers are not aware of the benefit of participation in a community that lacks reciprocity norms, and they may think ‘‘posting is of no value to me’’ (Nonnecke, Preece, Andrews, Voutour, 2004).

    1. 2

      Lovely little product that I would pay for, the trackreddit interface is abysmal.

      Tech wise though - is the reason you don’t support searching the entirety of Reddit a scaling issue? I ask because the global comment firehose seems to be freely available, so I’m wondering if there is a reason you don’t use that over selecting specific subreddits. Thanks!

      1. 4

        Thanks for the feedback!

        I built F5Bot in only a couple hours, so I didn’t do a lot of research or planning. It appears that the ‘comment firehose’ you posted doesn’t even go back one second in time. Is that right? I’m not sure how I could realistically use that without hitting Reddit several times a second, and even then I would miss a lot when Reddit goes down (which is often, I now know). Also, when I posted to Hacker News, a couple commenters mentioned Reddit API limits.

        So I just took the lazy/easy way by monitoring only the few subreddits that I actually cared about anyway. In this case, I can check back every couple minutes, and if sometime goes wrong I can check back even later without missing anything.

        Would this be substantially more useful to you if it pulled all of Reddit, instead of the current subset?

        It’s nice of you to say I could charge money for this. I think I’ll leave the current feature-set up for free. Realistically, it only took me a couple hours to build, so I don’t think it makes sense to monetize that. In fact, I was thinking about going the opposite way and open-sourcing it. I might add premium features in the future, but I’m not sure yet.

        1. 5

          Hey, we’ve documented some API rules here.

          You should use a unique user-agent as mentioned in the previous link. Also using OAuth will increase the rate limit to 1 qps. If you’re using PRAW, it’ll automatically handle rate limiting for you. If you have any more questions, feel free to reply here, post on r/redditdev, or PM me.

          1. 2

            Would this be substantially more useful to you if it pulled all of Reddit, instead of the current subset?

            Yes. Social Media monitoring is quite a large market: Mention, Hootsuite, etc but they all come with complex UI, reporting and cost quite a bit. There are a few in the cheaper “just notify me” space but the ones I have used have been fairly awful UI wise.

            As to hitting reddit every second, I had made the assumption you’d be doing that anyway - but yes, it would be worth reading around to find out what they deem acceptable.

          2. 2

            Just checked out trackreddit. You weren’t kidding about the interface! I guess maybe they were thinking to make it more powerful, but man, they did not optimize for the common use case at all.

            1. 1

              It actually works, but the email notifications send you to their mobile feed which has an ever worse UI than the main app. Also when it came to cancel, you can’t within the app and they ignored my request for 2 months leaving me with no choice but to raise a PayPal complaint.

              Felt like a hobby project gone wrong.

          1. 3

            I really wish there was an easy way to integration test a bunch of different distros / shell scripts for autojump. Maybe Docker’s the answer.

            Besides that, I’m trying to roll out a company internal image hosting service at work that came out of a Hackathon project. I should probably open source it as well while I’m at it.

            1. 1

              @steveklabnik it looks like higher kinded types won’t make it in? Do you know if that was a conscious decision to keep the type system simple, or it just isn’t a high priority (ie may be included later)?

              1. 3

                However, the Rust team is trying to get 1.0 out the door, and higher-kinded types would be backwards compatible, so I don’t think we’ll be seeing them for a while. There’s also questions about the overhead and syntax that would need to be resolved for them to make it in.

                steveklabnik

                1. 1

                  Yes, thank you. Sorry I wasn’t on top of this thread as I was the reddit and HN ones :(

                2. 2

                  I didn’t get a notification about this comment :( @wting is correct. Over on Reddit, (though I can’t find the thread :() there were three or four people that said they have proposals 75% done, but everything really is focused on getting 1.0 shipped, so they’re holding off until then.

                1. 12

                  My main issue with these posts is that they are largely a complaint about how bad actual projects are. Which I hear from all sides. The fault here, mostly, are structural and planning problems, from which a type system doesn’t save you. Haskell has huge pitfalls here as well, e.g. by the record syntax making it impossible to have to attributes of the same name within the same module. Also, a lot of anecdotal evidence and that is usually negative (I mean, positivity doesn’t sell, right?).

                  To add anecdotes: I’ve seen and worked on huge, clean and well implemented Ruby projects, doing all kinds of things you wouldn’t expect Ruby to do - up to high-traffic, low-latency servers for ad-tracking and video conferencing. All those share one property: an undogmatic team with a good sense for constructing huge systems (which primarily means: interaction between many components that cannot be typed, e.g. network). Many of those deviated from the “Rails way” at well-picked places.

                  I think we are focusing on program properties too much and not enough on systems building as a craft.

                  1. 8

                    I agree that bad projects exist on both sides. A project’s success is mostly dependent on how hard one can get the developers to work rather than the quality of their tools. So, IMO, the argument for or against static typing is one of making developers life easier, not about success of a project (not that I’m saying anyone is arguing that, but that is just my point of view).

                    That said, IME, the one benefit that a language with a decent static type system is that it gives developers what a dynamic one does not: a small sliver of guarantees when they refactor. It may not be much, but if you are refactoring code that is a mess and has no tests, it’s something you latch on top, knowing that at least your refactoring produces something of the same type. And in that way, I think it is a benefit to developers.

                    I think software development is going through an unfortunate anti-intellectualism fad right now. There is a lot of good research on how to design programs and how to develop teams to implement said programs. I believe many people fall back on saying that development is more of an art than a science, thus we don’t need much rigorous thinking. Maybe this is good because it means a lot of people who develop things even if the underlying design of it is poor. I think quantity is a poor substitute for quality though.

                    1. 4

                      I don’t think refactoring without tests is a good case for static typing. In the end, tests are very important to ensure the formal correctness of a program taking the requirements into account. If I test +, and refactor it and suddenly 1+1 is 3, I am in the same hellhole, types or not - my project manager will call me stupid. A good test suite makes sure the program still works to specification after refactoring and types don’t cover your specification. The whole “we don’t need tests” is just as much as anti-intellectualism as the whole type debate - because it assumes all important parts of a spec can be covered by the compiler (read: the compiler can read your mind).

                      I don’t think we are going through anti-intellectualism - we (as unscientific programmers) are just horribly bad at seeing the advantages of both approaches and there are not a lot of people that can competently argue both sides. We are also bad at judging the impact of non-technological components in software development process (which, every scientific paper about how a certain language feature makes development sooo much easier happily brushes aside).

                      I am not arguing that static typing is bad - it’s a great tool at the right spots - but it’s also not flawless and dynamically typed languages are here for very practical reasons.

                      I don’t believe there is such a thing as a mass idiocy (which ‘anti-intellectualism’) implies.

                      1. 4

                        Static types and tests can be used complementarily (at least until dependent types become cheap and easy; actually, the expense is the whole debate here). In my experience, probably 30-70% of the logic of tests in programs in dynamic languages are just implementing a bad type system. This gets especially bad when mocks are introduced.

                        Among the ones that aren’t type related, they’re usually very partial on the intended behavior, usually because they’re struck with the difficulty of traversing the entire possible state space.

                        Purity and types improve both of those situations nearly automatically. Nobody argues that types completely replace testing, instead that they make it easier to test and that fewer tests are required.

                        1. 2

                          No one is making the argument that strong static typing will eliminate most bugs, especially logical ones. Static typing only eliminates a subset of bugs. There is a set of bugs caught by unit tests, and a set caught by static typing. There is an intersection between those two sets but they are not subsets of each other.

                          @apy was making the argument that static typing simply catches a set of bugs that is not caught in dynamical languages and provides a small sliver of guarantee.

                          1. 1

                            Also, I’m not arguing that one should not test code. What I am saying is that if you inherit a codebase that is a mess and has no tests, a statically typed language gives you at least some correctness coverage and as you refactor the code, including adding tests, it gives you something to work with to know what’s going on.

                            1. 1

                              Sure, but I think that effect is overrated.

                              You can also build yourself into the corner with a type system quite nicely and not being able to cut corners can also be a problem.

                              In the end, the tests - the things that actually validate the business value of your code - are the more important stuff.

                              I also don’t think languages should be built for how well salvageable they are.

                              1. 1

                                I think tests, especially high level business value ones, are like symptoms of diseases. When they are indicating trouble your project is sick.

                                Types are like good appetite and healthy diet. They won’t keep you from being sick, but they are relatively cheap and lower your susceptibility across the board.

                      2. 3

                        Turing completeness bites every time language comparisons are made. Of course you can achieve things in any language, and of course outside factors influence it.

                        The benefit of <things like Haskell> is the same benefit of usig better tools in any endeavor: a constant nudge toward quality and ease. In the hands of a beginner it’s possibly a waste of resources, and a pro will still win when coding in Perl, but a pro using a good tool will be able to perform optimally.

                        And finally, you can definitely type networked stuff. That’s what schema are all about. A rich network interface type declaration is exactly what API documentation is.

                        All to say, of course Ruby can work and of course it’ll take expert judgement and divergence from “best practices”, but I don’t think that’s the argument being had. It’s more like everyone is complaining because they play at a tennis club which requires they use baseball bats.

                        1. 1

                          A schema is not a guarantee in the sense most a type system do it. And I can certainly apply schemas in dynamic languages. What I meant by that is the following: during runtime, such a system cannot guarantee me that the data read from the network will actually fit. In a sane runtime, a program can actually make that expectation.

                          I fundamentally criticize the notion of “better”. Haskell gives me a lot of guarantees, but asks quite some ceremony in return. I also don’t want to say that Haskell is bad - far be it from me, I love it.

                          What I am missing are comparisons on the level of “Static Typing Where Possible, Dynamic Typing When Needed” [1] that compare those two approaches without broad strokes.

                          [1] http://mediakit.govexec.com/docs/Meijer.pdf

                          1. 2

                            A schema isn’t a guarantee, but it is a type. You just operate in a system where types aren’t respected… Unless you control both ends and can stop that. To be more clear: “types” only are distinguishable in systems with both statics and dynamics. Data is purely static so it depends upon the larger system it’s embedded in as to whether a schema acts as a type. It’s up to the system designers to make those guarantees and profit from them.

                            I think that Haskell is better in the sense of “whenever you can afford it, static types are better”. In my experience, dynamic types aren’t so much cheaper either: you end up with about half the “checking” expense, but it’s all performed ad hoc in comments, informal contracts, and programmer sweat. In this mode, half the checking is three times as expensive. It just feels cheaper to begin.

                            Activation energy is probably the biggest detriment to static types. That is definitely the case. I think my tennis racket analogy still applies though.

                            (Also, while I buy Meijer’s premise I’m pretty sure I don’t follow his conclusion. He’s not arguing powerfully, just building C# allies. The tradeoffs between static and dynamic can already be easily done in a static system: you just make larger types. It’s merely that without a static system at all (or with a broken one) you can’t add smaller types as available or needed.)

                      1. 3

                        I’d like to point out that Google Drive is a cheap alternative. They have a 1TB at $10/mo option while Dropbox is 500GB at $550/mo (converted from yen pricing).

                        Unfortunately I can’t switch myself because Google Drive lacks Linux support.

                        1. 2

                          I hear there is an alternative called Grive. Haven’t tried it out yet, but it might be what you want for your linux box.

                        1. 2

                          Sorry, I should have linked the blog post that better explains Haxl instead.

                          1. 3

                            When stealing a link, read the comments first to steal the good one. :)

                            1. 2

                              Updated.

                            1. 13

                              Very interesting. It looks like in the “Top” view, you just show all the front page HN posts first, followed by all the front page Lobste.rs posts, and finally all the front page /r/programming posts. Have you considered how best to interleave them based on popularity? I would suggest you give each story a normalized score based on the cumulative score of everything on the front page. That is, for an HN story, the score would be

                              {Score on HN} / {Cumulative Score of all HN Posts}
                              

                              Then something similar for Lobsters and Proggit. That way, the Lobsters posts wouldn’t all drift to the bottom because of the site’s lower readership.

                              Also, as mentioned in the “What are you working on?” post, links to the comment sections would be nice.

                              1. 3

                                I will definitely work on this! Thank you for your input.

                                1. 2

                                  I’d balance the relative scores between the sites. Like if something gets a +20 on lobste.rs then it would be like +500 on hnews or proggit.

                                  Links to the discussions would be nice.

                                  1. 5

                                    That’s why I suggested normalizing based on the total number of points for each site.

                                  2. 2

                                    I really like hckrnews.com’s filtering of top 20 or top 50% by day. It gives me a quick digest of what’s popular rather than wading through Hacker News' front page.

                                    Lobste.rs doesn’t have enough traffic to warrant the same filtering though.

                                  1. 6

                                    From this Reddit post:

                                    A quick overview:

                                    • Statically typed with type inference.
                                    • Generics.
                                    • Closures.
                                    • No exceptions.
                                    • Extension methods.
                                    • Properties (syntax similar to C#), including lazy properties with the "@lazy" annotation.
                                    • Functions, methods and type (static) methods.
                                    • Support for observers (with "willSet" and "didSet"). Interesting to see the observer pattern baked in a language although I’m more partial to event buses for this kind of thing.
                                    • Enums.
                                    • Classes and structures (structures have restrictions regarding inheritance and other things).
                                    • For and while loops (statements, not expressions).
                                    • "mutating" keyword.
                                    • Named parameters.
                                    • Deinitializers (finalizers).
                                    • Protocols (interfaces).
                                    • Optional chaining with "a?.b?.c" and forced dereference with "!."“.
                                    • Convenient “assign and test”: "if let person = findPerson() ...".
                                    • Type casting with "is", down casting with "as?" (combines nicely with the "let" syntax. Ceylon does it right too).

                                    Also option types.

                                    1. 10

                                      Makes me think of Curse of the Excluded Middle where Erik Meijer talks about functional-ish programming displacing the gains that could occur by full functional programming.

                                      By this persons reasoning, I could program functionally in C.

                                      I’d like to see a more detailed post titled Necessary but not Sufficient Mechanisms for Functional Programming

                                      1. 2

                                        By this persons reasoning, I could program functionally in C.

                                        Are you referring to the OP? If so, I’m not sure how you gathered that. Look at OP’s first point: “Standard tooling fosters simplicity.”

                                        1. 4

                                          It’s in reference to the “Functions are first-class” section. While functional programming is ill defined, function pointers alone do not make a language functional.

                                          I find the headline a bit linkbaitish since the author concludes with:

                                          Go is not a functional language, nor does it support the common functional applications. However, the spirit of Go definitely nods in the direction of the functional ideal: simplicity and ease of reasoning.

                                          I’d argue that good code is simple and easily reasoned, regardless of which language or paradigm used.

                                          1. 2

                                            It’s in reference to the “Functions are first-class” section.

                                            I know that. Sorry, I guess I wasn’t clear. My point was that the OP’s reasoning would not apply to C because it would require ignoring everything else the OP said.

                                            I find the headline a bit linkbaitish since the author concludes that Go is not a functional programming language:

                                            shrug If it is, it’s pretty mild bait. To me, the headline implies that the OP is trying to persuade functional programmers to give Go a try. And indeed, that’s exactly what OP tries to do.

                                      1. 6

                                        I think people are rediscovering the benefits of static typing for performance and correctness reasons. The latest generation of statically typed languages[0] all have some level of type inferencing which helps.

                                        If Python is fast enough for you, it’s a fantastic language. The problem is once performance or codebase demands scale, dynamic typing rears its ugly head and there are no simple solutions. At work we sidestep this issue by writing a plethora of tests, but now dynamic typing productivity gains are offset and we spin up a lot of AWS instances to scale performance.

                                        [0] Go, Rust, Scala. Haskell and OCaml have had it for a while.

                                        1. 2

                                          I think we’re over-emphasizing speed here. It’s true that for some kind of applications speed should be optimized for ground up. It’s a good with have choices, especially choices designed by Ken Thompson. That said, the reason people choose frameworks like Django and Rails is not because they need raw application speed. Developers need frameworks to write code quickly, avoiding mistakes. So it’s a nice thing that we have Rust and Go, but let’s not get over-excited. Both of these programming language have a serious lack of libraries and community support for professional development today. We’ll see how they evolve in the years to come.

                                          1. 1

                                            Speed is absolutely available in Python if one codes in a reduced subset as shown by Shedskin. Python is a wonderfully flexible language with rich metadata support than can enable programming in-the-large via decorators, macros and quickcheck. No reason to leave.

                                        1. 2

                                          I have experience with GitHub, Bugzilla, Trac, and JIRA. I would go with either Trac (standalone) or JIRA (web service).

                                          JIRA feels like it’s created for developers, and is a more extendable than Trac at the cost of some setup complexity.

                                          1. 7

                                            github issues seems to work fine, and it’s really convenient if you’re already using github

                                            1. 4

                                              GitHub issues doesn’t do email-based support, and it requires your customers to have GitHub accounts to report bugs. That’s fine if you’re doing a random open-source project, or if you have an external system to handle the customer management side, but it’s otherwise not an acceptable bug tracker.

                                              1. 4

                                                I think a lot of people upvote GitHub due to familiarity, but as a bug tracking system it’s pretty crappy compared to “real” bug tracking software.

                                                1. 1

                                                  Yeah, that’s pretty much a deal-breaker (forcing customers to have github accounts). Thanks for pointing that out.

                                              1. 3

                                                This is a pretty big release that solves a lot of problems associated with cabal hell:

                                                • dependency freezing
                                                • parallel builds
                                                • no re-linking unless a file has changed
                                                • temporarily ignore upper bound requirements
                                                • new sandbox implementation!
                                                1. 2

                                                  Choosing between improving tooling vs solving business problems is not a binary decision. vim / emacs are complex tools with a learning cost, yet most would agree that they are worth the complexity. Google and other companies have positions dedicated solely to improving plumbing.

                                                  No one is arguing using a new technology for its own sake, but rather it’s a question of trade-offs.

                                                  1. 2

                                                    Improving tooling provides business value for Google. That’s not necessarily true for all businesses.

                                                    1. 2

                                                      The analogy used (restaurant owner and plumber/electrician), suggests that the type of business the author is talking about is not primarily a tech company, but a regular business which happens to need some IT infrastructure (say a website). In such a case, using established and proven technology would be the best thing to do so that the owners can focus on their core business.

                                                    1. 3

                                                      Forgive my ignorance, but what can you do with higher-kinded types? Why introduce the [_] syntax? What would it help me do that I can’t already do in Rust? I really don’t understand the rationale or excitement here. At the moment it just seems like needless complexity. Please explain.

                                                      1. 7

                                                        Without higher-kinded polymorphism, we would be able to write this for lists:

                                                        map :: (a -> b) -> [a] -> [b]
                                                        

                                                        But higher-kind polymorphism allows abstraction, thus less code repetition. We could call a single “mapping” function when we want to map, instead of a new one per data type. In Haskell it’s called fmap which works for all functors:

                                                        fmap :: Functor f => (a -> b) -> f a -> f b
                                                        

                                                        Where f is any type-constructor which implements Functor - not tied to list, like the first example.

                                                        So we could write another function, like so:

                                                        x :: Functor f => f Int -> f Bool
                                                        x = fmap (== 42)
                                                        

                                                        And we can run the above on lists, maps, trees, functions, state, configuration, loggers, etc.

                                                        This would be especially useful for Rust’s traits (i.e. type classes) because then we could write a “functor” trait and just use the fmap function which would work for any type which implements the trait.

                                                        1. 3

                                                          Out of curiosity, how much influence is there from Haskell (& friends) on the development of Rust as a language? I haven’t had time to do any nontrivial programming with Rust yet, but the sense that I get is that it has a lot of the good ideas from languages like Haskell, (e.g., powerful types, ‘free theorems’ from the compiler) but aimed at programming at a more ‘system’ level, where you want to have control over resources.

                                                          Is that sort of accurate (or is there a better way to express it?)?

                                                          1. 1

                                                            I haven’t done much Rust but I’d say that’s only a little true. Rust’s type system is a little bit impressive, but the lack of higher kinded polymorphism, existential types, etc means it’s quite a bit less powerful than Haskell. Free theorems aren’t as powerful either, since Rust doesn’t feature effect tracking.

                                                            You’d be able to do the above in a language designed for systems development but the combination with Rust features would probably take time to figure out.

                                                            The biggest I think which relates Rust to Haskell would be type-classes.

                                                            1. 3

                                                              Rust has existential types. They are called “trait objects.”

                                                              Rust’s type system is a little bit impressive

                                                              Its linear types make it very impressive IMO.

                                                              1. 2

                                                                Thanks, those are both good points!

                                                            2. 1

                                                              You see a lot of features traditionally found in functional programming languages like type inferencing, type classes, option types, pattern matching, map / filter / reduce, etc.

                                                              At the same time, Rust’s priority is a systems language so it has dropped / ignored certain features (e.g. tail call optimization, higher kinded polymorphism).

                                                        1. 4

                                                          Why a new implementation instead of PyPy:

                                                          • method-at-a-time JIT (like V8) instead of tracing JIT
                                                          • conservative garbage collector
                                                          • LLVM backend instead of RPython
                                                          • no GIL

                                                          FYI, GvR is currently working at Dropbox. GitHub repo.

                                                          I wish it targeted v3.x and not v2.7 though.

                                                          1. 1

                                                            For me the biggest draw is their intention of making C extension modules just work. Pypy has slowly started getting C extensions working, but even when it works it’s slower than CPython (due to the compatibility layer involved). Having a drop-in JIT'ing replacement that still works with the likes of numpy/scipy is very exciting to me.

                                                            I know people like to rag on the GIL and python, but I honestly don’t think it’s that big of a deal, and they don’t really have any concrete plan on how to get rid of the GIL (the README at least outlines a plan of approach for C extensions, it says nothing about how they plan on getting rid of the GIL).

                                                            1. 1

                                                              Obviously it’s liable to change, but listing GIL removal as a primary goal is a good sign. There are plenty of CPU bound Python programs that can’t be solved with multiprocessing, either at work or in my personal projects. Gearman or Celery is overkill for these projects.

                                                          1. 7

                                                            Flask was originally an April Fool’s Joke (pdf).

                                                            1. 1

                                                              I’ve already mentioned this elsewhere, but I think shared libraries is the best default option. You’re trading security vs stability, and I would prefer a secure, broken program over a stable, possibly insecure program.

                                                              I think defaulting to static linking is fine for what Go is currently used for (in house sites and services), but it’s bad for the FOSS ecosystem. For example, if I use a Go binary that is linked against a vulnerable library, I have to hope that the developer is following CVE reports for all dependencies. When a new security exploit is discovered, the developer has to recompile against the updated libraries, repackage, and push the new package to each distro.

                                                              What was originally a single responsibility for monitoring security issues is now distributed among all the maintainers and developers.

                                                              1. 1

                                                                Since when do developers push binaries to distros? It seems like packagers should have a flag than be easily set that says “statically compiled, recompile when a dependency changes.”

                                                                1. 2

                                                                  packagers should have a flag than be easily set that says “statically compiled, recompile when a dependency changes.”

                                                                  Perhaps in an ideal world, but that’s not how Linux currently works. A CVE was opened up against a software I maintain, and the RedHat maintainer contacted me to fix it. I patched it and he backported it the version in RedHat’s repos. The (minor) vulnerability still exists in Debian and Ubuntu. If this was a static library it’d be no different, the onus is on the developer to update the software.

                                                              1. 3

                                                                The one thing I desire from Rust is a portable binary format. I know it is aimed for system programs, but a portable binary format that can be AOT or JIT translated to native would “break the mold” and standout among the plethora of language implementations currently available.

                                                                1. 2

                                                                  Experimental JIT support was added two years ago, but later removed because of instability and limited dev resources.