Threads for javcasas

  1. 3

    This got me curious. Does V8 or other JS engine optimize .map calls with fusion?

    1. 3

      I don’t think so because it would mess up the ordering of side effects.

      1. 3

        No. Stream fusion is still a pretty unique capability of Haskell.

        1. 1

          My thought exactly. Without some form of lazyness, this code is really suspicious to begin with

        1. 40

          If the people you’re working with tell you there’s “too much magic” there’s too much magic. It’s a subjective position, and the other people on your team are the ones who get to decide. Stop trying to show how clever you are and write code people can read.

          1. 22

            The opposite also exists. If you are told to write it in a for(…;…;…) loop so that others understand it and you think there are better ways to do it, it’s fine to judge that the team needs some extra maturity.

            map, filter and reduce have been existing for a long long time. Using them instead of for loops that construct new arrays is not clever code.

            1. 6

              The maturity of the team is not a variable that can be influenced by anyone who is writing code. At least, not in any relevant timeframe. You have to write code to the level of the team you have, not the team you wish you had. Anything else is negligence.

              edit: To a point, of course. And I guess that point is largely a function of language idioms, i.e. the language should be setting the expectations. If some keyword or technique is ubiquitous in the language, then it’s appropriate; if it’s a feature offered by a third-party library then you gotta get consensus.

            2. 6

              Stop trying to show how clever you are and write code people can read.

              I think that is a pretty pessimistic interpretation of why people might write code in a particular style. (Though I don’t doubt that’s why some people might do it.) But I think most of the time it’s because they got excited about something and that distinction is important.

              For example, the way you are going to respond to someone who is trying to show off or lord over others is going to be different than someone who is expressing a genuine interest.

              If someone on your team is taking an interest in something new it might be because they are bored. If you treat them like they are being a jerk then you are only going to make them feel worse. Instead, it’s better to redirect that energy. Maybe they need a more challenging project or they should work with an adjacent team.

              That said, someone who is excited about something new might go off the deep end if they are given a lot of freedom and a blank canvas so it’s important to help guide them in constructive and practical directions. Acknowledging interests instead of shunning them can open up space for constructive criticism.

              Overall, it’s important to be kind and try to work together.

              1. 4

                That said, someone who is excited about something new might go off the deep end if they are given a lot of freedom and a blank canvas so it’s important to help guide them in constructive and practical directions.

                Exactly - someone might be so excited about the new possibilities of coding in a certain way they forget about readability in their excitement to golf it down to the most elegant point-free style. But that same programmer, after a few months looking back at their own code might cringe in horror at what they’ve wrought. If even the original author later might not understand what they wrote, it’s a terrible idea to just merge it in even if the other teammembers are total blockheads (which is highly unlikely given the type of work we do), and the tech lead would be in their rights to require modifications to make it more easy to understand.

            1. 3

              Really looking forward to the JSON Schema writeup now that you’ve had this experience!

              Ninja edit: Do you know about Spectral as well?

              1. 1

                I haven’t heard of Spectral! Very cool.

                JSON Schema seems so verbose, at first look.

                1. 4

                  JSON Schema pays with verbosity being able to be serialized, stored and sent over the network. The advantages of being JSON.

                  BTW I can’t recommend JSON schema enough.

              1. 3

                Multiplicities are hard if you don’t study your theory.

                • One: T
                • Zero or one: Maybe
                • Zero or many: List

                And now you combine them with tuples.

                • One or two: (T, Maybe)
                • At least three: (T, T, T, List)
                • Two to five: (T, T, Maybe, Maybe, Maybe)

                Of course, you can throw dependant types and interfaces to it to make it nicer.

                1. 6

                  Laurence Tratt has been publishing PLT papers for almost two decades, I think he knows the theory.

                  1. 4

                    Yes, but are there any programming languages that make structures like this easy to work with?

                    For example if you have “at least one” and (T, List) and you want to insert into the front of the list it is a bit awkward. I think you could probably make a generic type that made this easy to work with (or even adding a min parameter to existing list types) but I wouldn’t want to pass around funny tuples.

                    1. 1

                      We use the NonEmpty type in Haskell all the time, it has mostly the same interface as list. IMO the basic list of structures you need for 99% of cases representing relationships between data are:

                      • a
                      • Maybe a
                      • [a]
                      • NonEmpty a

                      Beyond that is quite rare, and at that point you should really be using custom types that only allow the valid states.

                  1. 2

                    Hm, I’d say the example is more specific: it is “internal iteration”, rather than general strategy. I usually code those as

                    fn halistone_numbers(n: u128, sink: &mut dyn FnMut(u128))
                    

                    It probably is important to note, for pedagogical purposes, that in this case external iteration works fine:

                    let halistone = std::iter::successors(Some(n), |x| if x == 1 { None } else { Some(if x % 2 == 0 { x / 2 } else { 3*x + 1 })})
                    
                    1. 2

                      I’m aware there are a ton of alternative implementations here – I chose it as an example because it’s easy to understand, with a little more complexity than “fizzbuzz.” If it helps, imagine it’s actually weather simulations.

                      1. 1

                        This is exactly what I’m thinking. You are constructing finite lists, so construct the list then operate on it.

                        let hailstone_count = hailstone(n).length
                        let hailstone_max = hailstone(n).fold(max)
                        

                        If you cannot construct the whole list, or reconstruct it, then deal with it as a streaming problem and just combine a bunch of traversals on the stream.

                        With this your hailstone function doesn’t have to know something about how is it going to be consumed, and therefore is simpler and more generic.

                        1. 1

                          I don’t thin finitness plays a role here. iter::successors would work just fine for an infinite list as well.

                      1. 9

                        I am OK with CS 101 DS and algo type of questions. The ones I am afraid the most are with additional “real-world” knowledge: design an efficient shuffling deck of cards, OOP design of parking garage, meeting time scheduling. I’m not familiar with playing card games. I don’t drive a car and have no idea wtf how a parking garage operates.

                        1. 4

                          Make them do a fizzbuzz. That’s like algorithms 101, yet it reveals so much on the programmer:

                          • Can write loops and conditionals?
                          • Indents code properly?
                          • Uses good variable names?
                          • for(let i=1; i<100; i++) vs for i in [1..100] vs i = 0; loop { i = i+1; if i=100 exit(1) } and all degrees and variations
                          • Multiple ifs vs if-elseif-elseif-else
                          • Care for errors by 1
                          • Simple program vs class fizzbuzz and class fizz and class buzz
                          1. 1

                            Fizzbuzz is pretty good. The only issue I’ve encountered is not knowing or not remembering what modulo is. I certainly didn’t know the first time I was asked to implement it.

                            1. 3

                              When I was 17, I did very badly in a Cambridge undergraduate admissions interview. The interviewer asked me a simple question with an obvious answer. Cambridge interviews are notoriously hard and so I assumed that I was missing something important and stalled for a long time while I tried to work out what the trick part of the question was. Eventually they gave up and told me the answer. It was precisely the one that I’d thought of immediately but since I’d been primed to expect a difficult question, I couldn’t believe that this was really what they were asking. I think I used somewhere between a quarter and a half of the total interview time failing to answer a question that they were expecting would take 30 seconds. I did not get an offer.

                              Questions like Fizzbuzz worry me because I’d expect them to trigger the same response from a lot of people. Fizzbuzz, in particular, has a very large solution space. A trivial implementation might look something like this:

                              for (int i=1 ; i<max ; i++)
                              {
                                 if ((i % 3) == 0)
                                  printf("fizz\n");
                                 else if ((i % 5) == 0)
                                  printf("buzz\n");
                                else if (((i %3) == 0) && ((i %5) == 0)
                                  printf("fizzbuzz\n");
                                else
                                   printf("%d\n", i);
                              }
                              

                              You could remove one of the branches by allowing fall-through into the buzz case even after you’ve done fizz, but then you need to worry about atomicity of the writes. Is that something the interview is expecting the candidate to think about? Are they expecting the candidate to think about the problem a bit more and realise that the pattern repeats 15 times (because 3 and 5 are both prime and 15 is 3x5 and therefore the lowest common multiple)? If so, the solution should look something like this, which avoids any modulo arithmetic:

                              for (int i=1 ; i<max ; i+=15)
                              {
                                printf("%d\n%d\nfizz\n%d\nbuzz\nfizz\n%d\n%d\nfizz\nbuzz\n%d\nfizz\n%d\n%d\nfizzbuzz\n"
                                   i, i+1, i+3, i+6, i+7, i+10, i+12, 1+13);
                              }
                              

                              With some special-case logic at the end for an incomplete sequence. Of course, printf is a very expensive call. You could optimise this by computing it once for each digit length and then just doing decimal arithmetic in the string.

                              And so on. There is a lot more optimisation that you can do with fizzbuzz. Knowing what the interviewer expects from the first attempt may not be obvious.

                              1. 2

                                not knowing or not remembering what modulo is.

                                Except it’s not necessary… it’s not particularly hard to do the arithmetic to figure divisibility or keep a couple extra loop counters and solve it without knowing/using the operator while still not introducing any new concepts to the solution. You might have to give a candidate doing that a bit more time, perhaps. But if anything, seeing that solution and then offering an explanation of modulo w/ a chance to revise is likely to be an even better assessment.

                          1. 2

                            Coding interviews are necessary because there are too many non-coders out there pretending to be coders. You need to make the candidates write code.

                            Having said that, 1-hour coding interviews in the style of “show me that you can fetch and show some data from a public API” is probably the right size, as it shows enough of the day to day practices. Anything beyond that (especially take-home exercises) is stretching it.

                            1. 10

                              Coding interviews are necessary because there are too many non-coders out there pretending to be coders.

                              I have run many, many interviews at multiple companies. I have yet to encounter the mythical “non-coder” trying to trick the company into hiring them. As far as I can tell, the whole idea is based on a literal vicious cycle where anyone who fails an interview is deemed to be utterly unable to do any coding, and that’s used as justification for ratcheting up the difficulty level, which results in more people failing and being deemed unable to code, which justifies ratcheting up the difficulty…

                              And that’s not just my personal opinion/anecdote: this online interviewing platform has a decent sample size and says:

                              As you can see, roughly 25% of interviewees are consistent in their performance, but the rest are all over the place. And over a third of people with a high mean (>=3) technical performance bombed at least one interview.

                              In the interviews they didn’t do well in, they probably were labeled as unqualified, incapable, etc. – but in the rest of their interviewers they were top performers.

                              1. 7

                                I have run many, many interviews at multiple companies. I have yet to encounter the mythical “non-coder” trying to trick the company into hiring them.

                                Lucky you. I haven’t run that many interviews, and so far I can remember a few cases:

                                • Junior finishing degree from degree mill, trying to pass a 5 million banking system as his own. Upon further investigation, his contribution to the code base was around 20 changes to README files.
                                • HR woman wanting to join because HR is so easy she expects to pick programming by just working with us.
                                • Applicant-provided code looks good. But the code in the on-site interview is very different (way lower quality). Upon further investigation, turns out the provided sample was written by her boss, not actally by the applicant.
                                • 20 years of experience on CV. Can only do what the IDE offers as buttons/dropdowns. Unable to debug the SOAP authentication in their company API because there is no button for it.

                                Sure, some of these can work as programmers if you are willing to lower enough the requirements. But without a technical interview where they get to write some code, or explain some code they wrote in the past, you wouln’t find out.

                                And yes, I also have hired people without degrees that were able to demo me something they built. I had to teach them later working in teams, agile, git, github and other stuff, but they still did good nodejs and mongo.

                                It’s very hard to completely bomb an interview if you can write some code. You can write wrong abstractions, bad syntax, no tests, and that is still so much better than not being able to open an IDE, or not being able to open a terminal and type ls.

                                1. 6

                                  have hired people without degrees that were able to demo me something they built. I had to teach them later working in teams, agile, git, github and other stuff,

                                  This doesn’t seem degree related, since degree work won’t teach you working in teams, agile, git, or github

                                  1. 1

                                    I have run many, many interviews at multiple companies. I have yet to encounter the mythical “non-coder” trying to trick the company into hiring them.

                                    I’ve seen it happen; I’ve worked with someone who managed to work at a company for several years, even though it was an open secret that they couldn’t code without pairing (he was tolerated because he was likeable, and took care of a lot of the non-programming related chores)

                                    I’ve also seen people strut into an interview with great confidence, only to write code that didn’t remotely resemble the syntax of the language they were supposedly proficient in. If this was due to anxiety, they certainly didn’t show it.*)

                                    I don’t think it’s common enough to warrant all the anxiety about “fake programmers”, but it’s not completely imaginary.

                                    *) I live in a country where software shops are among the few white-collar employers that’ll happily accept people who don’t speak the native language. That might mean we get more applicants for whom software development wasn’t exactly their life’s calling.

                                    1. 1

                                      work at a company for several years, even though it was an open secret that they couldn’t code without pairing

                                      I would hope that after years of pairing they started being able to code… Otherwise I blame their pairing partners.

                                      1. 1

                                        I don’t know how the situation arose, but by the time I got there, he was already known as the guy who did the “chores”, and avoided pairing to - presumably - reduce the chance of being found out. This all changed when new management came in, which implemented some - very overdue - changes.

                                        Maybe the takeaway should be that there might be room for “non-coders” in development teams, but the situation as it was can’t have been easy on anybody.

                                  2. 3

                                    Coding interviews are necessary because there are too many non-coders out there pretending to be coders. You need to make the candidates write code.

                                    I can’t speak for all jurisdictions, but this feels a little overblown to me, at least in the Australian market.

                                    If someone manages to sneak through and it turns out they have no experience and can’t do the job, you can dismiss them within the 6 month probation period.

                                    Yes, you would have likely wasted some time and money, but it shouldn’t be significant if this is a disproportionately small number of candidates.

                                    1. 2

                                      The thing is the culture in the US is quite different- some companies will fire people willy nilly, which is bad for morale, and other companies are very hesitant to fire anyone for incompetence, because by firing someone you leave them and their family without access to health care (and it’s bad for morale). Either way, you do actually want to make good decisions most of the time when hiring.

                                  1. 44

                                    Name popular OSS software, written in Haskell, not used for Haskell management (e.g. Cabal).

                                    AFAICT, there are only two, pandoc and XMonad.

                                    This does not strike me as being an unreasonably effective language. There are tons of tools written in Rust you can name, and Rust is a significantly younger language.

                                    People say there is a ton of good Haskell locked up in fintech, and that may be true, but a) fintech is weird because it has infinite money and b) there are plenty of other languages used in fintech which are also popular outside of it, eg Python, so it doesn’t strike me as being a good counterexample, even if we grant that it is true.

                                    1. 28

                                      Here’s a Github search: https://github.com/search?l=&o=desc&q=stars%3A%3E500+language%3AHaskell&s=stars&type=Repositories

                                      I missed a couple of good ones:

                                      • Shellcheck
                                      • Hasura
                                      • Postgrest (which I think is a dumb idea, lol, but hey, it’s popular)
                                      • Elm
                                      • Idris, although I think this arguably goes against the not used for Haskell management rule, sort of

                                      Still, compare this to any similarly old and popular language, and it’s no contest.

                                      1. 15

                                        Also Dhall

                                        1. 9

                                          I think postgrest is a great idea, but it can be applied to very wrong situations. Unless you’re familiar with Postgres, you might be surprised with how much application logic can be modelled purely in the database without turning it into spaghetti. At that point, you can make the strategic choice of modelling a part of your domain purely in the DB and let the clients work directly with it.

                                          To put it differently, postgrest is an architectural tool, it can be useful for giving front-end teams a fast path to maintaining their own CRUD stores and endpoints. You can still have other parts of the database behind your API.

                                          1. 6

                                            I don’t understand Postgrest. IMO, the entire point of an API is to provide an interface to the database and explicitly decouple the internals of the database from the rest of the world. If you change the schema, all of your Postgrest users break. API is an abstraction layer serving exactly what the application needs and nothing more. It provides a way to maintain backwards compatibility if you need. You might as well just send sql query to a POST endpoint and eliminate the need for Postgrest - not condoning it but saying how silly the idea of postgrest is.

                                            1. 11

                                              Sometimes you just don’t want to make any backend application, only to have a web frontend talk to a database. There are whole “as-a-Service” products like Firebase that offer this as part of their functionality. Postgrest is self-hosted that. It’s far more convenient than sending bare SQL directly.

                                              1. 6

                                                with views, one can largely get around the break the schema break the API problem. Even so, as long as the consumers of the API are internal, you control both ends, so it’s pretty easy to just schedule your cutovers.

                                                But I think the best use-case for Postgrest is old stable databases that aren’t really changing stuff much anymore but need to add a fancy web UI.

                                                The database people spend 10 minutes turning up Postgrest and leave the UI people to do their thing and otherwise ignore them.

                                                1. 1

                                                  Hah, I don’t get views either. My philosophy is that the database is there to store the data. It is the last thing that scales. Don’t put logic and abstraction layers in the database. There is plenty of compute available outside of it and APIs can do precise data abstraction needed for the apps. Materialized views, may be, but still feels wrong. SQL is a pain to write tests for.

                                                  1. 11

                                                    Your perspective is certainly a reasonable one, but not one I or many people necessarily agree with.

                                                    The more data you have to mess with, the closer you want the messing with next to the data. i.e. in the same process if possible :) Hence Pl/PGSQL and all the other languages that can get embedded into SQL databases.

                                                    We use views mostly for 2 reasons:

                                                    • Reporting
                                                    • Access control.
                                                    1. 2

                                                      Have you checked row-level security? I think it creates a good default, and then you can use security definer views for when you need to override that default.

                                                      1. 5

                                                        Yes, That’s exactly how we use access control views! I’m a huge fan of RLS, so much so that all of our users get their own role in PG, and our app(s) auth directly to PG. We happily encourage direct SQL access to our users, since all of our apps use RLS for their security.

                                                        Our biggest complaint with RLS, none(?) of the reporting front ends out there have any concept of RLS or really DB security in general, they AT BEST offer some minimal app-level security that’s usually pretty annoying. I’ve never been upset enough to write one…yet, but I hope someone someday does.

                                                        1. 2

                                                          That’s exactly how we use access control views! I’m a huge fan of RLS, so much so that all of our users get their own role in PG

                                                          When each user has it its own role, usually that means ‘Role explosion’ [1]. But perhaps you have other methods/systems that let you avoid that.

                                                          How do you do for example: user ‘X’ when operating at location “Poland” is not allowed to access Report data ‘ABC’ before 8am and after 4pm UTC-2, in Postgres ?

                                                          [1] https://blog.plainid.com/role-explosion-unintended-consequence-rbac

                                                          1. 3

                                                            Well in PG a role IS a user, there is no difference, but I agree that RBAC is not ideal when your user count gets high as management can be complicated. Luckily our database includes all the HR data, so we know this person is employed with this job on these dates, etc. We utilize that information in our, mostly automated, user controls and accounts. When one is a supervisor, they have the permission(s) given to them, and they can hand them out like candy to their employees, all within our UI.

                                                            We try to model the UI around “capabilities”, all though it’s implemented through RBAC obviously, and is not a capability based system.

                                                            So each supervisor is responsible for their employees permissions, and we largely try to stay out of it. They can’t define the “capabilities”, that’s on us.

                                                            How do you do for example: user ‘X’ when operating at location “Poland” is not allowed to access Report data ‘ABC’ before 8am and after 4pm UTC-2, in Postgres ?

                                                            Unfortunately PG’s RBAC doesn’t really allow us to do that easily, and we luckily haven’t yet had a need to do something that detailed. It is possible, albeit non-trivial. We try to limit our access rules to more basic stuff: supervisor(s) can see/update data within their sphere but not outside of it, etc.

                                                            We do limit users based on their work location, but not their logged in location. We do log all activity in an audit log, which is just another DB table, and it’s in the UI for everyone with the right permissions(so a supervisor can see all their employee’s activity, whenever they want).

                                                            Certainly different authorization system(s) exist, and they all have their pros and cons, but we’ve so far been pretty happy with PG’s system. If you can write a query to generate the data needed to make a decision, then you can make the system authorize with it.

                                                    2. 4

                                                      My philosophy is “don’t write half-baked abstractions again and again”. PostgREST & friends (like Postgraphile) provide selecting specific columns, joins, sorting, filtering, pagination and others. I’m tired of writing that again and again for each endpoint, except each endpoint is slightly different, as it supports sorting on different fields, or different styles of filtering. PostgREST does all of that once and for all.

                                                      Also, there are ways to test SQL, and databases supporting transaction isolation actually simplify running your tests. Just wrap your test in a BEGIN; ROLLBACK; block.

                                                      1. 2

                                                        Idk, I’ve been bitten by this. Probably ok in a small project, but this is a dangerous tight coupling of the entire system. Next time a new requirement comes in that requires changing the schema, RIP, wouldn’t even know which services would break and how many things would go wrong. Write fully-baked, well tested, requirements contested, exceptionally vetted, and excellently thought out abstractions.

                                                        1. 6

                                                          Or just use views to maintain backwards compatibility and generate typings from the introspection endpoint to typecheck clients.

                                                  2. 1

                                                    I’m a fan of tools that support incremental refactoring and decomposition of a program’s architecture w/o major API breakage. PostgREST feels to me like a useful tool in that toolbox, especially when coupled with procedural logic in the database. Plus there’s the added bonus of exposing the existing domain model “natively” as JSON over HTTP, which is one of the rare integration models better supported than even the native PG wire protocol.

                                                    With embedded subresources and full SQL view support you can quickly get to something that’s as straightforward for a FE project to talk to as a bespoke REST or GraphQL backend.. Keeping the schema definitions in one place (i.e., the database itself) means less mirroring of the same structures and serialization approaches in multiple tiers of my application.

                                                    I’m building a project right now where PostgREST fills the same architectural slot that a Django or Laravel application might, but without having to build and maintain that service at all. Will I eventually need to split the API so I can add logic that doesn’t map to tuples and functions on them? Sure, maybe, if the app gets traction at all. Does it help me keep my tiers separate for now while I’m working solo on a project that might naturally decompose into a handful of backend services and an integration layer? Yep, also working out thus far.

                                                    There are some things that strike me as awkward and/or likely to cause problems down the road, like pushing JWT handling down into the DB itself. I also think it’s a weird oversight to not expose LISTEN/NOTIFY over websockets or SSE, given that PostgREST already uses notification channels to handle its schema cache refresh trigger.

                                                    Again, though, being able to wire a hybrid SPA/SSG framework like SvelteKit into a “native” database backend without having to deploy a custom API layer has been a nice option for rapid prototyping and even “real” CRUD applications. As a bonus, my backend code can just talk to Postgres directly, which means I can use my preferred stack there (Rust + SQLx + Warp) without doing yet another intermediate JSON (un)wrap step. Eventually – again, modulo actually needing the app to work for more than a few months – more and more will migrate into that service, but in the meantime I can keep using fetch in my frontend and move on.

                                                2. 2

                                                  I would add shake

                                                  https://shakebuild.com

                                                  not exactly a tool but a great DSL.

                                                3. 21

                                                  I think it’s true that, historically, Haskell hasn’t been used as much for open source work as you might expect given the quality of the language. I think there are a few factors that are in play here, but the dominant one is simply that the open source projects that take off tend to be ones that a lot of people are interested in and/or contribute to. Haskell has, historically, struggled with a steep on-ramp and that means that the people who persevered and learned the language well enough to build things with it were self-selected to be the sorts of people who were highly motivated to work on Haskell and it’s ecosystem, but it was less appealing if your goals were to do something else and get that done quickly. It’s rare for Haskell to be the only language that someone knows, so even among Haskell developers I think it’s been common to pick a different language if the goal is to get a lot of community involvement in a project.

                                                  All that said, I think things are shifting. The Haskell community is starting to think earnestly about broadening adoption and making the language more appealing to a wider variety of developers. There are a lot of problems where Haskell makes a lot of sense, and we just need to see the friction for picking it reduced in order for the adoption to pick up. In that sense, the fact that many other languages are starting to add some things that are heavily inspired by Haskell makes Haskell itself more appealing, because more of the language is going to look familiar and that’s going to make it more accessible to people.

                                                  1. 15

                                                    There are tons of tools written in Rust you can name

                                                    I can’t think of anything off the dome except ripgrep. I’m sure I could do some research and find a few, but I’m sure that’s also the case for Haskell.

                                                    1. 1

                                                      You’ve probably heard of Firefox and maybe also Deno. When you look through the GitHub Rust repos by stars, there are a bunch of ls clones weirdly, lol.

                                                    2. 9

                                                      Agree … and finance and functional languages seem to have a connection empirically:

                                                      • OCaml and Jane St (they strongly advocate it, mostly rejecting polyglot approaches, doing almost everything within OCaml)
                                                      • the South American bank that bought the company behind Clojure

                                                      I think it’s obviously the domain … there is simple a lot of “purely functional” logic in finance.

                                                      Implementing languages and particularly compilers is another place where that’s true, which the blog post mentions. But I’d say that isn’t true for most domains.

                                                      BTW git annex appears to be written in Haskell. However my experience with it is mixed. It feels like git itself is more reliable and it’s written in C/Perl/Shell. I think the dominating factor is just the number and skill of developers, not the language.

                                                      1. 5

                                                        OCaml also has a range of more or less (or once) popular non-fintech, non-compiler tools written in it. LiquidSoap, MLDonkey, Unison file synchronizer, 0install, the original PGP key server…

                                                        1. 3

                                                          Xen hypervisor

                                                          1. 4

                                                            The MirageOS project always seemed super cool. Unikernels are very interesting.

                                                            1. 3

                                                              Well, the tools for it, rather than the hypervisor itself. But yeah, I forgot about that one.

                                                          2. 4

                                                            I think the connection with finance is that making mistakes in automated finance is actually very costly on expectation, whereas making mistakes in a social network or something is typically not very expensive.

                                                          3. 8

                                                            Git-annex

                                                            1. 5

                                                              Not being popular is not the same as being “ineffective”. Likewise, something can be “effective”, but not popular.

                                                              Is JavaScript a super effective language? Is C?

                                                              Without going too far down the language holy war rabbit hole, my overall feeling after so many years is that programming language popularity, in general, fits a “worse is better” characterization where the languages that I, personally, feel are the most bug-prone, poorly designed, etc, are the most popular. Nobody has to agree with me, but for the sake of transparency, I’m thinking of PHP, C, JavaScript, Python, and Java when I write that. Languages that are probably pretty good/powerful/good-at-preventing-bugs are things like Haskell, Rust, Clojure, Elixir.

                                                              1. 4

                                                                In the past, a lot of the reason I’ve seen people being turned away from using Haskell based tools has been the perceived pain of installing GHC, which admittedly is quite large, and it can sometime be a pain to figure out which version you need. ghcup has improved that situation quite a lot by making the process of installing and managing old compilers significantly easier. There’s still an argument that GHC is massive, which it is, but storage is pretty cheap these days. For some reason I’ve never seen people make similar complaints about needing to install multiple version of python (though this is less off an issue these days).

                                                                The other place where large Haskell codebases are locked up is Facebook - Sigma processes every single post, comment and massage for spam, at 2,000,000 req/sec, and is all written in Haskell. Luckily the underlying tech, Haxl, is open source - though few people seem to have found a particularly good use for it, you really need to be working at quite a large scale to benefit from it.

                                                                1. 2

                                                                  hledger is one I use regularly.

                                                                  1. 2

                                                                    Cardano is a great example.

                                                                    Or Standard Chartered, which is a very prominent British bank, and runs all their backend on Haskell. They even have their own strict dialect.

                                                                    1. 2

                                                                      GHC.

                                                                      1. 1

                                                                        https://pandoc.org/

                                                                        I used pandoc for a long time before even realizing it was Haskell. Ended up learning just enough to make a change I needed.

                                                                      1. 23

                                                                        There are three levels of frontend interaction complexity:

                                                                        • Up to form action=foo method=post and button type=submit. For this, HTML + CSS is the easiest solution.
                                                                        • Up to buttons with simple animations. Jquery or vanilla is the easiest solution.
                                                                        • Anything over it. React with potentially extra state management libraries is the easiest solution.

                                                                        Yes, you don’t need React for websites with minimal interactivity requirements, but as soon as you have to add just a few of those requirements, you quickly regret not having React.

                                                                        Also, things like GatsbyJS or NextJS can be configured to output static sites. This may look like totally overkill, except for a tiny detail. You get to use all the module management and import semantics from Javascript to manage your components, which is way better than plain old CSS files and copy-pasta for HTML snippets. Add in Typescript and you have a strong proposition. Though WebComponents may do something similar here…

                                                                        1. 4

                                                                          There’s a level past React too though. React can’t really do high performance things, so for those you need to turn to Canvas or something and handroll it. Tom MacWright made this point in the now classic “Rethinking the Modern Web”.

                                                                          Here’s one way to think of it:

                                                                          • Google search: can be handled as HTML, CSS, sprinkles of JS animation
                                                                          • Gmail: you’ll want some kind of JS framework to handle all the zillions of screens
                                                                          • Google maps: you don’t want a framework doing the map because it will be too slow. The map is canvas or some other smart layer that can load tiles on the fly. (Nav buttons can be whatever.)
                                                                          1. 3

                                                                            It’s extremely easy to migrate from a simple HTML + CSS site to a site with JQuery or vanilla JavaScript, because JavaScript is basically just a layer over the HTML page that’s already there. React wants to have the center stage, and most knowledge about the underlying technology is useless at best and sometimes even harmful, as React wants everything done in a very specific way.

                                                                            1. 15

                                                                              See this line of code? https://github.com/manirul41/react-mvc-app/blob/master/src/index.js#L7 It tells React to do its thing on the id=“root” element in the page. What tends to happen is https://github.com/manirul41/react-mvc-app/blob/master/src/index.html#L15 - I/E the only element in the page is that id=“root”.

                                                                              It doesn’t have to be like this. You can tell React to render on any subsection of the page, and manage the rest of the page in a different way. (This is the big secret behind all that microframeworks hipe we saw a few months ago). When you do React this way, it becomes another layer of the system. It becomes just an element with incredibly advanced functionality. And you can delete the element with node.parent.removeChild(node) and the React node goes away and the React runtime stops.

                                                                              React doesn’t want to have the center stage. People put React in the center stage.

                                                                              1. 4

                                                                                most knowledge about the underlying technology is useless at best and sometimes even harmful, as React wants everything done in a very specific way

                                                                                In my experience, this hasn’t been the case. React outputs some HTML, and you still have to know what HTML to use and how to use it.

                                                                            1. 7

                                                                              I had a few attempts to learn it, but I failed every time. It is fair to say that I don’t understand it, so I cannot even rant about its features, shortcomings, or flaws.

                                                                              Nice 👍🏻

                                                                              1. 3

                                                                                to be fair I’m using it for one hobby project (not a webdev at day) and still feel overwhelmed by the amount of additional plugins (Redux, how do you do global state for login + user-menu that is decoupled, hooks…). Add the whole JS stack on top (with its 40k modules) and you are starting to feel like every major rust dependency graph is irrelevant in comparison. Vue felt way easier but lacked one major component for one thing I needed (QR code display) and often it’s not obvious how you use any external JS libraries together with these self-managing frameworks.

                                                                                1. 10

                                                                                  Don’t do Redux. Only big sites warrant using it. Start with minimal hooks (useState) passing the state and setters as params. everywhere. Once you understand this, work your way up using contexts and effects. You don’t need more than this for 80% complex sites out there.

                                                                                  1. 3

                                                                                    thanks for the explanation, will look into that

                                                                                    1. 2

                                                                                      contexts and hooks are probably the best thing to happen to react since JSX

                                                                                1. 29

                                                                                  UML works for a very narrow view of software development. I found that out when I wrote my thesis in OCaml and had to document it in UML. How do you express a curried function in UML? How do you express a simple function in UML that happens to not be attached to an object?

                                                                                  And that is only the tip of the iceberg.

                                                                                  How do you express a complex SQL query in UML? Entity-relation diagrams help modelling the schema, but what about a query with joins and window functions?

                                                                                  How do you express a map-reduce operation in UML? What’s the diagram for filtering a list, then aggregating the results?

                                                                                  How do you express a minimally-complex algorithm in UML (think Sieve of Erastothenes)? Why can’t I use pseudo-code, which beats diagrams every day of the week?

                                                                                  How do you express a reactive user interface in UML? Why do I have to use something like a collaboration diagram, when the state of the interface derives directly the representation of the interface? It’s not the case that the input enables the submit button when it finds itself no longer empty.

                                                                                  How do you express a Prolog program in UML? Do you think the UML committee has ever known about the existence of Prolog?

                                                                                  How do I represent a multi-param generic data structure? For example, a mapping/hash table from A to B, where A and B are arbitrary types.

                                                                                  And then we ignore the old problem of documentation and software diverging over time, and having to update the documentation when the software changes.

                                                                                  UML comes from an era where Object Oriented (Obsessed?) Design was the whole world, and everything that wasn’t OOD was being forced to not exist. In this era, Architects would draw UML diagrams and cheap Indian code monkeys would do the coding, because we thought that code monkeys would be cheap and replaceable. This was perfect for the MBAs because programmers started to be annoying by not delivering on the expected deadlines, and claiming about the algorithms, the damned algorithms. We wanted to replace them with cheaper and less-whiny ones.

                                                                                  Turns out that the details of the system are in the code, not in the diagrams, and only the trivial parts of the system would be expressed in diagrams, and the devil is in the details. But this makes programmers non replaceable and fungible, because the better ones can express algorithms that the worse programmers will never understand. And many times, you need these better algorithms.

                                                                                  All this makes UML not anymore the silver bullet for bodyshops. The broken idea of hiring 1 architect and 100 code monkeys from the consultancy just doesn’t work, because the architect is not expected to dig in the details, and the 100 code monkeys will just make a mess of the details.

                                                                                  UML was dead on arrival when it ignored most of the details of Software Development. Doesn’t mean though that some parts of UML can be salvaged, such as sequence diagrams, state diagrams, or entity-relation diagrams. But trying to model in UML an arbitrary problem and solution is likely to become wrestling with the language to express anything minimally complex or different.

                                                                                  1. 13

                                                                                    How do you express a … UML was dead on arrival when it ignored most of the details of Software Development.

                                                                                    The UML isn’t supposed to model software down to the query and the algorithm. It’s supposed to model a system and its processes, to assist with the design of a software implementation of that system.

                                                                                    If the way you think about modelling a system is “what complex SQL queries will I need, and how can I add a functional reactive UI” then indeed the UML will not help as the paradigm of its creators and users is the object oriented paradigm. You are thinking about the problem in a way the UML will not help you to express, so we do not expect it to help with the expression of those thoughts.

                                                                                    The OO paradigm of the UML isn’t the “objects are inheritance and encapsulation” straw man of blog posts about switching to functional, but the “objects are things in the problem domain reflected in software” of object oriented analysis and design.

                                                                                    To the extent that the UML and other tools from OOSE were “dead in the water” (an odd claim given their former prevalence), a more convincing reason is that they were sold as efficiency and productivity bolt-ons to programmers without also explaining the need for a paradigm shift. A large number of companies adopted Java, carried on writing structured software, and noticed that they were also having to do this O-O ceremony that doesn’t help them.

                                                                                    In a few years time they’ll notice that switching to Scala, carrying on writing structured software, and also doing this functional ceremony isn’t helping them, and we’ll all get to have this thread again on the “has currying died and nobody noticed?” posts.

                                                                                    1. 10

                                                                                      The UML isn’t supposed to model software down to the query and the algorithm. It’s supposed to model a system and its processes, to assist with the design of a software implementation of that system.

                                                                                      Then I would like to have the class diagram removed from UML, please, because class diagrams define a lot of details of data structures, and that restricts a lot on the algorithms I’m allowed to use.

                                                                                      You are thinking about the problem in a way the UML will not help you to express, so we do not expect it to help with the expression of those thoughts.

                                                                                      And now you are agreeing with me that many problems and solutions cannot be expressed in UML unless I twist the problem/solution to fit UML.

                                                                                      This is not about Object Oriented Programming vs Functional Programming. This is about the fact that I can’t express many things in UML, starting with the whole universe of functional programming, and continuing with database interactions, declarative programming, advanced data structures, compositional semantics, and many others that I haven’t got time yet to study. Each of those alternative ways to do computing beat the others in specific situations, and having to use UML just forces me to not be able to use the right tool for the job because the UML committee decided that it is hammers for everyone. And now I have to make this screwdriver look like a hammer to be able to draw it in UML.

                                                                                      1. 1

                                                                                        Then I would like to have the class diagram removed from UML, please, because class diagrams define a lot of details of data structures, and that restricts a lot on the algorithms I’m allowed to use.

                                                                                        Firstly, you’re welcome to not use class diagrams. Secondly, you’re welcome to only put the details you need into a diagram, and avoid constraining your implementation: the map is not the terrain.

                                                                                        And now you are agreeing with me that many problems and solutions cannot be expressed in UML unless I twist the problem/solution to fit UML.

                                                                                        I don’t think so. It sounds like you’re saying the UML is bad because you can’t do these things, whereas I’m saying the UML is good when I don’t do these things. “Doctor, it hurts when I lift my arm like this!”

                                                                                        1. 16

                                                                                          “Doctor, it hurts when I lift my arm like this!”

                                                                                          I hate when people use this analogy. If it hurts when I lift my arm like this, that’s probably a sign of some deeper underlying problem! Don’t tell me to not lift my arm.

                                                                                      2. 3

                                                                                        The OO paradigm of the UML isn’t the “objects are inheritance and encapsulation” straw man of blog posts about switching to functional

                                                                                        That straw man is exactly what I’ve been taught at school. Shapes and animals and all that. Sure it’s just for learning, but the next step is invariably “OO is hard”, “OO is complicated”, “OO takes times to master”… the usual conversation stoppers.

                                                                                        [UML is] “objects are things in the problem domain reflected in software”

                                                                                        That also is likely a mistake. As Mike Acton so eloquently put it, we should not code around a model of the world (in this case, the things in the problem domain). We should code around a model of the data. The things in the problem domain are what you speak of before managers or domain specialists. When you start actually programming however, it quickly becomes about the shape and size and flow of the data, and UML doesn’t help much there.

                                                                                        1. 2

                                                                                          “objects are things in the problem domain reflected in software” of object oriented analysis and design.

                                                                                          What does that even mean ? I have never seen this aspect explained except in the most superficial terms - creating a class which has a method name that reflects something from the domain usually resulting in bikeshed arguments.

                                                                                          I am sorry but that is not a model of anything. It is just naming. We can’t call naming modelling. When I am making a model of a circuit in software I can interact with the model, test all the assumptions. When an actual architect uses AutoDesk they are modelling things and can interact with them. BDD does this so it can absolutely be called modelling in some sense. I don’t know if it is the best modelling technique we can come up with but it works.

                                                                                          1. 1

                                                                                            I’d recommend Eric Evans’s book on domain-driven design. “Just naming” implies that you’ve already decided what the method does and that you want to find something in the problem domain to map it onto. OOA/D says that you have found something important in the problem domain and that you want your software to simulate it.

                                                                                        2. 4

                                                                                          Spot on. Frankly speaking, this was already crystal clear for many people back them. Many people realised immediately it was snake oil.

                                                                                        1. 1

                                                                                          I also posted about implementing a similar component. I didn’t cover handling the error state (so I appreciate that you did), but one problem I’ve run into was that when switching between two subtrees with the data loader component at the same level, the component wouldn’t actually be unmounted, which broke a few of my assumptions. I think wrapping it in another component like you did in the final CommentsSection implementation fixes this, though.

                                                                                          Also somebody in the comments also pointed to the Apollo Query component, which has yet another API but essentially does the same thing.

                                                                                          1. 1

                                                                                            Old components may not be unmounted because the final tree contains the same component in between state changes. This can be the case if all your sub-components are divs, for example. In that case, React will happily not rebuild the component, and instead will just change the props of it. Then you need to use the componentWillReceiveProps, that only complicates it and makes for more antipatterns and worse code.

                                                                                            Depending on how you can refactor it, you can trick React into rebuilding the whole component, for example by returning an array of a single component with a random key, or some kind of key that changes when you want the DOM tree to be rebuilt. It is a bit annoying, but it’s significantly less annoying than the componentWillReceiveProps route.

                                                                                            1. 1

                                                                                              Then you need to use the componentWillReceiveProps, that only complicates it and makes for more antipatterns and worse code.

                                                                                              Yep, componentWillReceiveProps has only caused me problems. That’s why I prefer hooks in general, they make it easier to spot this kind of errors and correct them “the right way”.

                                                                                          1. 1
                                                                                            The object may not have neither of the two fields.
                                                                                            The object may have only field1, and not field2.
                                                                                            Only if the object has field1, then it can have field2.
                                                                                            

                                                                                            It seems to me that the way these are worded is rather confusing. I can figure it out eventually going through each line, and the #2 creates a contradiction with #3. It seems to me that if #3 is true, then #2 cannot be true.

                                                                                            1. 1

                                                                                              It definitely could be more clearly worded. I think it’s saying:

                                                                                              • Both fields are optional
                                                                                              • field2 can only be supplied if field1 is supplied as well
                                                                                              1. 1

                                                                                                Thanks zzing and chenghiz for the kind suggestion! I’ll tune down the poetical approach to writing.

                                                                                            1. 1

                                                                                              I must be confused. You’re saying that every application should enumerate every potential combination of data, one-by-one? I don’t see where algebraic datatypes are being applied.

                                                                                              1. 1

                                                                                                Hi!

                                                                                                Enumerating every potential combination is obviously impractical. But thinking about it helps you design types in a better way so that you can reduce the amount of data that is valid. One of the principles I use when designing datatypes is looking for groups of data that are absolutely independent of each other, and thinking about them separately. Then, for the groups of data that are somewhat dependent on each other, there is usually one field that determines the others in some fashion, and I split the data based on this field.

                                                                                                The example applies the underlying ideas behind ADTs to look for the final solution. In Haskell, you could think of something equivalent in the style of:

                                                                                                data NoFields = NoFields
                                                                                                data Field1Only = Field1Only {
                                                                                                    field1 :: String
                                                                                                  }
                                                                                                data BothField1AndField2 = BothField1AndField2 {
                                                                                                    field1 :: String,
                                                                                                    field2 :: String
                                                                                                  }
                                                                                                data InvalidObject = InvalidObject  {
                                                                                                    field2 :: String
                                                                                                  }
                                                                                                data Fields
                                                                                                  = NF NoFields
                                                                                                  | F1O Field1Only
                                                                                                  | BF1AF2 BothField1AndField2
                                                                                                  -- Didn't put InvalidObject here
                                                                                                
                                                                                                1. 1

                                                                                                  I think I understand. But this seems like an application of structural typing to enumerate permissible combinations of fields, rather than of algebraic datatypes.

                                                                                              1. 1

                                                                                                I hope they add something like pattern matching to make checking through the cases of the ADT a bit less cumbersome. Given how much ceremony it takes to define and use an ADT, I sometimes wonder if I’m even doing the right thing.

                                                                                                1. 1

                                                                                                  The switch statement is kind of a weak pattern matching. It doesn’t allow you to match on the fields or extract field values easily. I still consider it a good tool for your toolbox, specially if you do Redux. In Redux, you have ADTs, either explicitly declared, or implicitly declared. I prefer explicit in terms of types, so at least the typechecker can spot some of my mistakes.

                                                                                                1. 2

                                                                                                  What I never understand with smart contracts that require off chain data:

                                                                                                  If it requires an oracle, why not just run it off chain? In this case you’re fully trusting the exchange, so it’s not any more “trustless” than if the buyer’s wallet had an integration with ShapeShift/Changelly/some other instant exchange.

                                                                                                  1. 1

                                                                                                    if the buyer’s wallet had an integration with ShapeShift/Changelly/some other instant exchange

                                                                                                    What if you want to deal with the average exchange ratio? How do you convince these instant exchanges to cooperate to provide the average ratio, considering that they may not want to cooperate? On the other hand, asking each one for an oracle, and having a smart contract that accepts several oracles to compute the average is not that hard.

                                                                                                    1. 1

                                                                                                      What if you want to deal with the average exchange ratio?

                                                                                                      Why? The average isn’t useful (in the context of the article). If I want someone to send me $10 USD, I’d ask the exchange how much $10 USD in Bitcoin is, and ask for that amount. The average would mean that I could get more or less depending on which exchange I have an account with.

                                                                                                    2. 1

                                                                                                      I think the idea is that you trust external parties to provide data (because it can be audited), but you don’t trust external parties to run code. I think it makes sense.

                                                                                                      1. 1

                                                                                                        This is pretty much the takeaway. You can run trusted code on chain, while using trusted data from off chain.

                                                                                                        1. 1

                                                                                                          You can also run the code yourself.

                                                                                                          i.e. User types in their wallet app to request $10 USD. The wallet secretly makes a deal with the user’s exchange and determines that $10 USD will be worth X Coins. The wallet makes a request to the other person for X coins. Using oracles just adds extra cost for not a lot more trust.

                                                                                                      1. 19

                                                                                                        Easy, Reverse Proxies are better at handling scaling connections, they can terminate SSL and they are battle hardened against the common noise of the internet. Likely all properties 99% of apps people develop do not have.

                                                                                                        1. 7

                                                                                                          Also reverse proxies like nginx can serve static assets (usually) a thousand times better than your application. They can show custom error pages, or failover to other services when your app crashes. They can implement cheap-ass authorization (401 and the like) over simple apps, discriminate against IP addresses and many other things you totally don’t expect from a software like nginx.

                                                                                                          It is not always a good idea to use all these features from nginx (over implementing these features in your app), but good knowledge of your reverse proxy can help you simplify your infrastructure.

                                                                                                          1. 1

                                                                                                            It is not always a good idea to use all these features from nginx (over implementing these features in your app), but good knowledge of your reverse proxy can help you simplify your infrastructure.

                                                                                                            Correct, I usually see a huge number of rewrite rules as a No-No unless they are explicitly necessary (ie, rewriting /<url> to index.php?<url>).

                                                                                                        1. 1

                                                                                                          To small RAM, 400kb is minimal for mruby.

                                                                                                          Hm… 48Mhz is very big. https://hackaday.io/project/13048-flea-ohm-fpga-project show how fast it will be. But too small memory. Second question is how many times i can programming this processor.

                                                                                                          1. 3

                                                                                                            FPGAs are not intended to have a lot of memory or to work like a processor. They are intended to be optimised to work like a very specific circuit for you to decide. The usual use for a FPGA is a middle point between general-purpose processors and hardcoded application specific integrated circuits. They may not be the best processors, or the best ASICs, but they are reconfigurable and can perform better than processors for specific tasks.

                                                                                                            You can reprogram an FPGA effectively infinite times, it stores its configuration in RAM. But sometimes you store that configuration on an external FLASH memory so it survives reboots and stuff, and this external memory may impose a limit on how many times you can reconfigure it.

                                                                                                            1. 1

                                                                                                              you are wrong. this device have ram ,many program need ram. I give a example. If You would like using processor to run specyfic program (for example windows system , yes exist procesor with instruction windows os)

                                                                                                              You melting fpga teoreticaly and this device. second trouble . exist more kind of ram ‘ram’ usualy normal ddr is durable than this fpga ‘ram’.

                                                                                                            2. 2

                                                                                                              48Mhz is very big

                                                                                                              On-board clock frequency is not very important, since PLLs can convert that to any frequency you require.

                                                                                                            1. 4

                                                                                                              Related: https://www.destroyallsoftware.com/talks/ideology

                                                                                                              Some people claim that unit tests make type systems unnecessary: “types are just simple unit tests written for you, and simple unit tests aren’t the important ones”. Other people claim that type systems make unit tests unnecessary: “dynamic languages only need unit tests because they don’t have type systems.” What’s going on here? These can’t both be right. We’ll use this example and a couple others to explore the unknown beliefs that structure our understanding of the world.

                                                                                                              1. 1

                                                                                                                Author here: Ideology by Gary Bernhardt is definitely part of the inspiration of this article, there is no point in hiding it. And I suggest you all go and check the talk, it’s really good, and goes way beyond programming.