1. 1
    primes n = [ x | x <- [2..n], prime x ]
    
    primes(n) = [ x for x = 2:n if prime(x) ]
    

    This recurses forever and busts the call stack.

    1. 2

      No it doesn’t. prime != primes.

      1. 1

        You’re right, my bad.

      2. 1

        I don’t currently have a Haskell compiler on my machine, but I just tested the Julia code with Julia 1.6.1, and it works fine. Note - primes depends on prime, and prime depends on factors, so you need to define all three of those functions.

      1. 1

        This got my attention:

        given two sorted integer lists, calculate the median value of the combination of the two lists, ideally in O(log(m+n)) time

        And then this lost my attention:

        One more thing. I have been calling the procedure’s inputs lists, but in fact this second implementation will use not lists but vectors.

        A bit of a bait and switch there!

        1. 3

          90% of the time is spent in reading code. Maybe we need to optimize for that instead. The indentation syntax chosen by lispers make it difficult to see scope and the 2 space indentation makes me want to stab my eyes. I like the kebab-case though. Long back I tried messing with begin / end instead of parens and found the resultant code much better and ruby-like.

          Lisp sorely needs a coffeescript, an external DSL as opposed to internal macros along with the appropriate tooling. JavaScript is really pragmatic in this regard. Why do lisp programmers hate lexers and parsers ? Until that happens Lisp will never be a real alternative to anything - again, 90% of time is spend in reading code. I have always had a soft-spot for dylan.

          1. 7

            The indentation syntax chosen by lispers make it difficult to see scope and the 2 space indentation makes me want to stab my eyes.

            I feel the same way reading Java. This has everything to do with familiarity and basically nothing to do with any inherent superiority in either style.

            Lisp sorely needs a coffeescript

            These kinds of dialects get created on a regular basis. It’s honestly very predictable if you follow a lisp mailing list. In the end no one uses them because the advantages are not very compelling; they only seem that way to people who haven’t spent much time using lisp.

            1. 1

              In Lisp parens are overloaded to represent

              1. Assignment
              2. Block Scope
              3. Expressions / Statements
              4. Function calls
              5. Function body
              6. Macro body
              7. Data structures

              When looking at a piece of Lisp code how quickly can you tell each of the above apart ?

              Lispers can adopt this style for better representing block scope

              (let [x 5]
                  (if x
                      (do
                          (print y)
                          (+ x y)
                      ) ; end-do
                  ) ; end-if
              ) ; end-let
              

              One use of Lisp’s regular parens, it actually makes the code easier to read because you don’t have to remember all the syntax. What I object to is the paren placement. where cuddling them together makes the scope not clearly visible. Can I use 8 spaced indentation in Lisp without the entire lisp community complaining ? I don’t think so.

              Let us look at how absurd the situation is. Because of the paren syntax - people are using XML, python and compiling JavaScript to a lisp like vm bytecode to avoid Lisp. One advantage of XML is the use appropriate beginning and ending tags. which makes it easy to tell things apart. I would bet you that if you take into account the reading time / comprehensibility time as opposed to lines of code in a large piece of code - Python/XML/C-like syntax would win.

              1. 4

                Your list of seven things includes a lot of duplicates. #1, #2, and #5 are just special cases of #6. It’s unclear what #3 “Expressions/statements” means since statements do not exist in lisps. It’s true that for #7 older lisps (CL, Scheme, and Emacs) certainly do have this problem of using parens for too many things, but newer lisps use other types of brackets. In Java, parens are used for two things: calling methods, and grouping operands in math expressions. So it’s not as if overloading the meaning of delimiters is somehow unique to lisps.

                You say that it’s difficult to read, and I say that it’s easy to read once you have experience. One of us has experience, and one of us doesn’t. Not really sure where else the argument can go from there.

                1. 1

                  #1, #2, #3, #5 are not special cases of #6 in terms of side-effects they cause.

                  1. 1

                    FWIW, I believe that define in Racket could be considered a statement since it raises a syntax error if used in an expression position.

                  2. 2

                    When looking at a piece of Lisp code how quickly can you tell each of the above apart ?

                    About as quickly as I can scan it, honestly. The keywords like if, let, and do are more significant in understanding it, but I take your meaning that finding the the close paren can be hard. I have seen Clojure beginners mess up their code by placing the close paren incorrectly. Most good editors have matching paren highlighting to make this easier.

                    BTW, an experienced Clojure programmer would code this up more tersely, something like:

                    (when-let [x 5]
                      (print y)
                      (+ x y))
                    
                    1. 1

                      The keywords like if, let, and do are more significant in understanding it,

                      Yes thats what I mean. If I look at a blob of any non-lisp code … I can immediately say where the conditionals, loops and function calls are. For lisp I have to go through each line to get the idea.

                       // If C programmers wrote like lisp
                       for (i = 0; i < 10; i++) {
                           if (i % 2 == 0) {
                               doSomething (i); }
                           else {
                               doSomethingElse (i); } }
                      
                      

                      You can’t add new statements without messing up “{” and “}”. The same happens in lisp if I want to add more statements in cond blocks. Lisp also forces programmers to not use standard control flow and favors recursion all times, all these hinder readability.

                      1. 4

                        To me this reads like a combination of a lack of literacy in the language (although in Clojure for is a loop keyword and if is a conditional—just like in C) and a mindset favoring imperative programs (based on your use of the term “statement.”) To be clear, I don’t think imperative is a “wrong way” of thinking but it will be an impedance to effectively using a Lisp language where all syntactic forms—including loops and conditionals—are expressions that have some value when executed.

                        I’m unsure what you mean by standard control flow but I rarely find myself writing recursive programs on finite data in Clojure or any other language. I agree with you that a recursive program is probably harder to understand vs the the equivalent iterative program in many instances.

                    2. 1

                      This is also a point where I find C-style syntax lacking. Other languages have for/next, do/od, if/fi or if/endif where the ending bracket must match the beginning bracket. In C, Java, Go, you often just find yourself at a big stack of {{{{.

                  3. 5

                    Lisp sorely needs a coffeescript, an external DSL

                    That wouldn’t be a DSL as it wouldn’t have anything domain specific about it. Quite the opposite.

                    Alternative syntaxes do exist and are used by a few. The general consensus over the 50 year old discussion about them, is that the vast majority of lispers do perfectly fine without them.

                    I’d say that, as any other language, it rather need practical selling points and marketing by some invested company, rather than theoretical/technical merits.

                    1. 4

                      The whole point of using Lisp instead of some other modern high level language is that it supports macros and is homoiconic, so you can write macros in Lisp itself instead of in a different macro language. If you get rid of this, why not just use Ruby? I’m not as familiar with Dylan - how easy is it to write macros there vs. in a more traditional lisp?

                      1. 3

                        90% of the time is spent in reading code. Maybe we need to optimize for that instead. The indentation syntax chosen by lispers make it difficult to see scope and the 2 space indentation makes me want to stab my eyes. I like the kebab-case though. Long back I tried messing with begin / end instead of parens and found the resultant code much better and ruby-like.

                        IME reading more code and becoming more familiar with the style makes different formats easier to read. In any case, there’s no requirement that Lisp use 2 spaces.

                        Personally, I use the default Emacs indentation for everything, and don’t have any problems reading Lisp, C++, Javascript, Python, or any of the other languages I have to use.

                        Lisp sorely needs a coffeescript, an external DSL as opposed to internal macros along with the appropriate tooling. JavaScript is really pragmatic in this regard. Why do lisp programmers hate lexers and parsers ? Until that happens Lisp will never be a real alternative to anything - again, 90% of time is spend in reading code. I have always had a soft-spot for dylan.

                        To be blunt, I suspect JavaScript programmers are quick to use non-Javascript whenever they can because Javascript is unpleasant to work with.

                        As far as why Lisp programmers prefer using macros and DSLs, it’s mainly because it’s so convenient to use one language and set of tooling for everything. Why complicate things with five different tools when one can do the job equally well? And it means anybody who knows the language can jump to the source code and see what’s going on.

                        As you said, reading code is the important thing, so why not spend your time reading and understanding one language instead of a bunch?

                        1. 1

                          It’s also worth pointing out that by far, the most commonly-used “Javascript+” language is Typescript… which is just Javascript with types. Same syntax.

                        2. 1

                          I was going to mention Dylan here until I saw your ending paragraph.

                          1. 1

                            90% of the time is spent in reading code. Maybe we need to optimize for that instead … The indentation syntax chosen by lispers make it difficult to see scope

                            I agree about the importance of optimizing for readability. I’m not sure exactly what you mean re: “indentation syntax”, but one of the things I absolutely love about programming in Racket (a lisp) is how lexical scope is handled with parenthetical blocks, and how easy it is to move lexically scoped blocks around in the editor.

                            Readability is very subjective, so I’m not trying to invalidate your view of lisp readability, but having scope neatly contained in the structure of the code is a very nice feature for me.

                          1. 5

                            The author has a thread on TalkChess.com that details some of the progress along the way.

                            1. 3

                              Since JavaScript was influenced by Scheme, I’m surprised that it doesn’t have an if expression. That seems like a serious omission. I primarily program in Racket and using the result of an if is commonplace.

                              1. 3

                                What JavaScript took from Scheme were closures, and not much else. The syntax of JS was inspired by C, so if including if-as-statement instead of if-as-expression was a conscious choice it was presumably made for familarity, since that’s how C does it and there were no mainstream languages at the time that had if blocks as expressions rather than statements.

                                1. 3

                                  Hmm, I do

                                  $foo = $bar if $baz;
                                  

                                  all the time in Perl (unless I want to test the inverse, in which case I use unless). Does this count as an if-expression?

                                  1. 3

                                    Oh yeah, I guess I forgot about Perl. Then I guess JS does it because of C.

                                    1. 2

                                      C

                                      The cause of, and solution to, so many computing problems ;)

                                  2. 2

                                    Funnily enough, the Atari 2600 BASIC had if expressions (it’s also an IDE for a machine with 4K of ROM and 128 bytes of memory—quite impressive even if the results are lackluster).

                                1. 7

                                  Welcome to Lobste.rs! New York Times articles are generally not well recieved or removed by moderators, because either they are offtopic, or in this case, are targeted at a non-technical audience (explaining prime numbers, simplification of encryption to RSA). See https://lobste.rs/domain/nytimes.com.

                                  In the future, I’d look for something more detailed and aimed at a more technical audience.

                                  1. 4

                                    What you did here is fantastic and I’m going to try to start doing this, too.

                                    1. 3

                                      Thanks for the tip!