1. 2

    I get that core/async Clojure code follows the Go channel example fairly close, but it seems misleading wrt the actual problem of starting two expensive computations and aggregating their results.

    This can be done in Clojure using futures as succinctly as it’s shown to be in Scala.

    1. 3

      Yup, Scala example could be translated directly as:

      (defn long-comp-1 [] 5)
      (defn long-comp-2 [] 6)
      
      (defn aggregate [i j]
        (println "i is" i "j is" j))
      
      (def result-1 (future (long-comp-1)))
      (def result-2 (future (long-comp-2)))
      
      (defn aggregated-future []
        (aggregate @result-1 @result-2))
      
      1. 16

        It’s even easier when using ii from suckless. We have a bot on #openbsd-gaming now that reports how many people are currently playing. It just runs qstat every 5 minutes, massages the output and spits it out to the input file tied to our channel. It’s hard to beat echo "hello world" > irc/chat.freenode.net/#openbsd-gaming for scripting bots.

        1. 5

          This is like some weird Portlandia thing…“The dream of Plan9 is alive in suckless”, etc.

          Still, neat though! :)

          1. -6

            ii sounds great in theory, but try to answer new incoming queries. now instead of parsing a single stream of text you have to monitor an entire directory tree with files appearing out of nowhere at any time

            parsing irc is super simple and ii is a retarded idea for a bot

            1. 15

              parsing irc is super simple and ii is a retarded idea for a bot

              This isn’t constructive. If anything the toxicity detracts from your argument above.

              1. 7

                ii sounds great in theory, but try to answer new incoming queries. now instead of parsing a single stream of text you have to monitor an entire directory tree with files appearing out of nowhere at any time

                Sure, if your bot needs to respond to private queries. The one on our channel doesn’t parse any input at all. Including the channel itself - it’s a notification bot.

                parsing irc is super simple and ii is a retarded idea for a bot

                You’re telling me it was retarded to output the result of qstat every 5 minutes to a file? It took 5 minutes to write the notification using ii - it serves it’s purpose.

                Does ii fit every use case of writing a bot for IRC? Nope. However it does make it dead easy to have various tools output content to a file and get it delivered on an IRC channel that way.

                1. 4

                  To be fair, even for notification, it seems overkill to pull ii and play with files when you can simply send to socket:

                  NICK bot
                  JOIN #foo
                  PRIVMSG #foo :My text message
                  

                  All you need is echo and nc and IRC is yours. ii look to me like an overkill solution for simple problems and limited solution for complexes ones. But then I might simply be missing some complexity about writing bots, manager server configuration, connection throttling, etc.

                  1. 2

                    Sure, but you will either connect to the network each time you invoke that notification or will need to maintain the connection up, respond to keepalive pings from the server etc. It is really easier to just dump a notification to a file every 5 minutes and have ii handle the connection.

                    It’s not perfect for all use cases, but it does simplify this specific one we had :)

                  2. -8

                    yeah i’m sure not many irc bots want fancy features such as being able to reply to things

              1. 6

                As someone currently writing free monad code for something that could probably just be dependency injection, this hit a bit too close to home.

                1. 1

                  It’s been a while since I did any Rust, but I remember the compiler giving similarly useful error messages. Bad error messages are easy to overlook until you experience how good they can be.

                  1. 2

                    Definitely something I’ve been bit by in the past and will comment on in code review. My general rule is no _ for pattern matches on user defined ADTs (since they may be extended in the future). Fine with it for builtin types because they often aren’t extensible.

                    Un(but almost)related nit. Hate it when people use _ to avoid explicitly typing the final variant of an ADT.

                    1. 4
                      • Notes: free one hour sessions for early stage projects!
                      1. 6

                        This comes off more like self promotion than an offer to provide mentorship.

                        1. 3

                          To me it seems like both, which isn’t necessarily a bad thing.

                          1. 1

                            I did a quick rain-check on the IRC channel if such a post is okay with us - all I got was one thumb up. But myself I wasn’t sure if this would fly. My only line of defense is that I guess we could both agree that there exist more powerful and direct ways of self-promotion.

                        1. 3

                          disconnected - the graph is made up of sub-graphs or it is bipartite.

                          Just a small correction, but a bipartite graph can be connected. Here’s an example of a bipartite connected graph.

                          1. 1

                            Is that graph connected, though? The red nodes aren’t connected to each other.

                            1. 1

                              edit: That graph is connected because there is a path from every node to every other node. Wolfram alpha does a good job visualizing all the different connected bipartite graphs of size n (for small n’s) at the bottom of the page here.

                              When the path from every node to every other node is a unique edge, then you have a complete graph.

                              1. 1

                                aha! I always mix up ‘connected’ and ‘complete’ :P

                          1. 18

                            If we do this we should also rename ml to ml-language so that people don’t continue to misfile it.

                            ((metalanguage-language!)

                            1. 3

                              Agreed on both counts.

                              1. 2

                                I think metalanguage would be more clear than ml-language.

                                1. 1

                                  I’d prefer if we kept ml as ml and called “ai” or “ml” or whatever is this weeks name for applied statistics “statistics” instead.

                                  1. 4

                                    But “ai” is more broad than machine learning / applied statistics. I would expect an “ai” tag to cover things like evolutionary algorithms, expert systems, etc, as well as your more typical (these days) machine learning.

                                1. 4

                                  That example for the threading macro could go either way, I certainly wouldn’t consider it crappy.

                                  Definitely possible to go overboard with threading. I often find it neatest to thread certain subexpressions in an expression that could otherwise be fully threaded because it makes the ‘core’ semantics of the operation clearer.

                                  1. 2

                                    You can’t determine if a link is a universal link for a given user (which requires them having the associated app installed on their device), but you can tell if it supports universal links by checking a domain for an apple-app-site-association file (e.g. http://google.com/apple-app-site-association).

                                    This could allow a privacy conscious mobile browser to conservatively remove links that support universal linking, regardless of whether or not they would have opened a native app if clicked on that user’s device.

                                    1. 5

                                      For a long time I felt similarly with respect to Haskell being a poor fit to domains that require a lot of “io plumbing”. Certainly you lose a lot of the pleasantness given to you by an expressive static type system when most of your application logic consists of handling third-party input and performing simple transformations on said input.

                                      That said languages like Haskell make it easy to write good abstractions, around ugliness like that. If done right, it can be -very- easy to extend the input handling functionality without making it feel like you’re playing the “read who knows what and get it into the form of a application specific ADT, handling errors cleanly” game.

                                      Just a couple of days ago I added a feature to a Haskell project I hadn’t touched in years that allowed it to parse a completely new type of binary message over the wire. It was as easy as adding a value constructor to an ADT and updating some pattern matches that the compiler could detect were no longer exhaustive.

                                        1. 6

                                          Sweet landing page, very polished.

                                          Funny opening with “A powerful language for building scalable systems on the JVM” followed by (can’t say for sure without checking the compiled output) what looks like a terribly unscalable implementation of “quicksort”.

                                          1. 3

                                            It’s perfectly reasonable idomatic Haskell. It’s got a bug, mind you (it de-dupes), but it’s idiomatic and performant when compiled by ghc. Since Eta is based on ghc, there’s a very good chance it’s also performant.

                                            1. 3

                                              Doing it in-place would be ideal. Here’s an example of an efficient variant of quicksort:

                                              http://hackage.haskell.org/package/vector-algorithms-0.7.0.1/docs/src/Data-Vector-Algorithms-Intro.html#sort

                                              But I don’t mind seeing the naive quicksort implementation. It’s not algorithmically optimal but it’s very easy to understand.

                                          1. 1

                                            Has anyone read this book before? Is it any good?

                                            1. 1

                                              Friends don’t let friends use bitmasks when they could have just used an extra element in the (arguably) simpler earlier versions. Depending on the size of each element I’d prefer simpler code. Plus the no mask versions are basically a design pattern that many programmers are familiar with so it should be somewhat self documenting.

                                              1. 0

                                                But then how are your peers suppose to know how smart you are?

                                                1. [Comment from banned user removed]

                                                  1. 15

                                                    Please, let’s not turn Lobste.rs into Reddit with threads of tired old witticisms, eh? It adds no value to the discussion.

                                              1. 3

                                                Inefficiency is a common critique of functional programming. I dislike that simplified quicksort example because it appears to reiterate that idea.

                                                1. 5

                                                  Link to previous Lobste.rs conversation about this https://lobste.rs/s/vhkucf/illegal_numbers

                                                  1. 2

                                                    ha! my brain hasn’t failed me when i thought “i’ve posted that” ;)

                                                  1. 8

                                                    I liked the bit about the new ? operator. A convincing argument for when something should be turned into a language built-in (in my opinion).

                                                    1. 8

                                                      I’m concerned with how subtle it is. It took me a while to figure out the revised code because I just didn’t see the first ?. I saw the second, but couldn’t figure out how it worked.

                                                      Maybe rust isn’t C, but I’ve never liked control flow macros. I get nervous when I can’t see all the ways out of a function.

                                                      1. 2

                                                        I really like the new operator - but I can understand that people might find it too invisible when glancing at a codebase.

                                                        The big benefit of ? compared to throw of other languages (C++, Java) is that it the underlying concept (Result<T>) forces you to handle the possibility of errors in every layer. Compared to C or Go (both force you to think about adding if err != nil { return err; }).

                                                        So compared to Java/C++ it’s more obvious where errors can happen and compared to C/Go it’s forcing you to handle errors where they happen (just ignoring a Result will result in a compiler warning).

                                                        1. 2

                                                          I’m concerned with how subtle it is.

                                                          But isn’t that the intention? The idea is that it looks like you’d write code almost as if errors don’t exist, while giving the possibility to let errors bubble up. I agree that it hides errors to some extend, but the same is true for checked exceptions or error monads.

                                                          1. 5

                                                            I don’t like exceptions either.

                                                          2. 1

                                                            I share your overall unease with hidden function-exits and would recoil at seeing things like break/continue/goto/return in a macro, but I don’t think all control-flow macros are necessarily bad (e.g. the Linux kernel’s list_for_each or the analogous sys/tree.h traversal macros in BSDland).

                                                          3. [Comment removed by author]

                                                            1. 3

                                                              HKT and do notation has a number of unresolved questions in Rust, ones that might take years to be resolved, if ever.

                                                              The need to make error handling is immediate and affects most Rust users.

                                                              If that ends up being a wart on the language in years, well, at least everyone’s life will be improved between now and then. rust will never be perfect.

                                                              1. 3

                                                                Wouldn’t that require quite large changes to the type system, including higher-kinded types?

                                                                But I agree that it could be more powerful, such that it would also work for e.g. Option…

                                                                1. 1

                                                                  The current implementation might only be the first step. There’s an open RFC discussing the possibility of introducing a new trait that can abstract the handling of the question mark operator. With this, it would be possible to implement it for both Result and Option

                                                                2. 2

                                                                  How could it be more powerful than it is? Please explain, you really got my attention :D

                                                                3. 1

                                                                  At first glance, I really like it. I code mostly backends in Erlang/Elixir. One of the biggest issues of my code is having nested cases (match in Rust or OCaml). Elixir somehow got it solved with the with special form. The RabbitMQ team created Erlando using Erlang’s parse transform (sort of macros) that adds syntax extensions to Erlang, with the do syntax for monads being the most important one to solve somehow this issue.

                                                                  Is there any other way of solving this issue? Is there any other concept that solves this type of problem that is not somehow related to monads?

                                                                  I ask this since the last years it appeared to me that in the end if I don’t have support or tools similar to do notation I keep on reiventing the wheel or non standard tools like Erlando or semi powerful constructs like Elixir with.

                                                                  1. 1

                                                                    I’m looking at the special forms there, and I’m wondering why you need nested matches. It seems like the use case is subsumed by matching on a tuple instead of a single value.

                                                                1. 2

                                                                  Does anyone know if a dictionary implemented in a low-level language like Rust/C/C++/D/Go, and using the same compact/ordered structure, would have the same benefits?

                                                                  1. 3

                                                                    It seems likely. Most of the benefits discussed in the pypy blogpost about it don’t have anything to do with Python (GC friendliness is the only one that does, and that would probably also affect Go and D depending on the details of their GC).

                                                                    1. 6

                                                                      Interesting. FWIW, Go intentionally “randomises” map iteration order (this was introduced after people started relying on a stable iteration order).

                                                                        1. 7

                                                                          Users are the worst.

                                                                    2. 1

                                                                      That would be exciting, and there is precedent for this. Timsort was developed for Python, and has found adoption elsewhere. It’s now the default sort for Java 7!

                                                                      1. 2