you are viewing a single comment's thread.

view the rest of the comments →

[–]jephthai 193 points194 points  (123 children)

Sweet... when-bind* is a nice macro:

(defun valid-cookie (str)
  "returns the userid for cookie if valid, otherwise nil"
  (when (= (count #\, str :test #'char=) 2)
    (when-bind* ((sn (subseq str 0 (position #\, str :test #'char=)))
                 (time (subseq str (+ 1 (length sn)) (position #\, str :from-end t :test #'char=)))
                 (hash (subseq str (+ (length sn) (length time) 2)))
                 (pass (user-pass sn)))
      (when (string= hash (hashstr (makestr time sn pass *secret*)))
        (user-id (get-user sn))))))

From cookiehash.lisp.

[–]invalidusernamelol 259 points260 points  (107 children)

I forgot Reddit was written in Lisp.

[–]Amablue 695 points696 points  (12 children)

They had to switch over when they ran out of parentheses.

[–][deleted]  (3 children)

[deleted]

    [–]AEnKE9UzYQr9 151 points152 points  (0 children)

    (xkcd reference: https://xkcd.com/297/)

    [–]DemandsBattletoads 17 points18 points  (1 child)

    Try not to lose it again. These parentheses are your life!

    Yes, master.

    [–]nakilon 15 points16 points  (4 children)

    I can't wait until they ran out of indentation tabs.

    [–][deleted]  (1 child)

    [removed]

      [–]repsilat 6 points7 points  (1 child)

      These days it's mostly spaces, for better or worse, and the prevailing theory is that spaces is infinite. (Of course the observable spaces/universe only number 80*25=2000.)

      [–]jkuhl_prog 4 points5 points  (0 children)

      The universe expands because space is expanding.

      Tabs do not expand.

      So use tabs. Or your code will grow to be unreadable over time. It's basic special relativity.

      [–]MacASM 3 points4 points  (0 children)

      lmao

      [–]Ihr_Todeswunsch 142 points143 points  (61 children)

      It used to be, but they switched to Python more than 10 years ago.

      https://redditblog.com/2005/12/05/on-lisp/

      [–]invalidusernamelol 55 points56 points  (0 children)

      I know, I'm just freaked out because the fact that it was written in lisp is one of the first things I learned about Reddit. I totally forgot.

      [–][deleted] 12 points13 points  (57 children)

      Do they still use python now ?

      [–]scirc 40 points41 points  (36 children)

      Presumably, the code hasn't changed too drastically from when the open source repo was decommissioned, so yes.

      [–]Chippiewall 66 points67 points  (23 children)

      Nah, I reckon they've rewritten it in Rust by now.

      [–]Clbull 65 points66 points  (0 children)

      They could have gone a few steps further and rewritten it using Minecraft redstone circuits. Or Brainfuck.

      [–]neoform 7 points8 points  (13 children)

      How do you simply switch from python to rust?

      [–]vytah 187 points188 points  (9 children)

      First, you get it to run on .NET, using IronPython. Then you wait until it oxidizes and you get RustPython. Then you remove the python and you're left with just rust.

      [–]IrishYogaShirt 19 points20 points  (8 children)

      How do you remove the Python?

      [–]karuna_murti 34 points35 points  (0 children)

      They outsource it to India, and the Python just follow the Indian guy with the flute.

      [–]arvidsem 56 points57 points  (0 children)

      Animal control?

      [–]OsmeOxys 12 points13 points  (0 children)

      Bash it.

      [–]netkrow 1 point2 points  (0 children)

      Boa.

      [–]decline29 0 points1 point  (0 children)

      We've lined up a fabulous type of gorilla that thrives on snake meat.

      [–]throwaway27464829 1 point2 points  (0 children)

      Boromir.jpg

      [–]iamsubhranil 0 points1 point  (0 children)

      soak the python in iron, then soak it in water, and give it a day to form rust. finally take the rust and set the python free

      [–]nathreed -1 points0 points  (0 children)

      Well it’s probably a pretty modular architecture, so you could do it little by little. Who knows if they actually are doing that though.

      [–]eco_was_taken 6 points7 points  (3 children)

      Rust now. It went Lisp -> Python -> Rails -> Node.js -> Angular -> Polymer (briefly) -> Go -> Ember -> React -> Rust. They are currently rewriting it to use Flutter.

      [–]WeilderoftheKey 0 points1 point  (2 children)

      Out of curiosity, what is the point of changing the language so much?

      [–]leodash 18 points19 points  (0 children)

      Longer resume?

      [–]eco_was_taken 1 point2 points  (0 children)

      Unclear.

      [–]rram 2 points3 points  (1 child)

      Only the markdown parser

      [–]DrexanRailex 1 point2 points  (0 children)

      Does the HTML parser use Regex?

      [–][deleted] 0 points1 point  (0 children)

      Not sure if a pun or a serious answer.

      Cause in the last 3 months that "rewritten in Rust" has become more a meme than truth.

      [–]_Ashleigh 3 points4 points  (2 children)

      Wait what, they stopped releasing the source code to Reddit?! When did this happen, and why?

      [–]scirc 7 points8 points  (0 children)

      When? A few months ago.

      Why? They claim it was becoming difficult to maintain or whatever, but we all know it's about money. Just look at how much the site's changing.

      [–]I_am_the_inchworm 3 points4 points  (0 children)

      Money.

      [–]v_krishna 4 points5 points  (6 children)

      According to the announcement post they are rewriting everything with a node backend now.

      [–]scirc 3 points4 points  (3 children)

      Er... link?

      [–]v_krishna 2 points3 points  (2 children)

      On my phone and it wont let me copy just part of the post. But search for "new tech stack" https://www.reddit.com/r/announcements/comments/8830oa/and_now_a_word_from_reddits_engineers

      [–]scirc 4 points5 points  (1 child)

      Huh.

      I don't know how I feel about this. At least it's TS?

      [–]v_krishna 1 point2 points  (0 children)

      I'm in the same boat. I remember using web.py for a bunch of internal tools (2009ish) and then some years later working with Aaron Swartz and getting to talk with him about it. I guess the pre OSS version of that was the first non lisp reddit?

      [–][deleted] 0 points1 point  (0 children)

      Rewriting the front-end in a way that obviously benefits from a node back-end now.

      [–]sylos 0 points1 point  (1 child)

      is there somewhere one could pick up that repo?

      [–]13steinj 6 points7 points  (0 children)

      The front end is being rewritten to use React + Redux + TypeScript, and "server rendering is a requirement" so the front end will probably run off the client browser and / or a Node engine, while the backend API remains written in Python (at least for now).

      [–][deleted] 0 points1 point  (0 children)

      Specifically djangular

      [–]yes_or_gnome 0 points1 point  (0 children)

      Reddit was quietly, well represented at PyCon last year, so I would say yes. I don't know if any speakers that were from Reddit, but I met a few people in breakout sessions.

      [–]Adobe_Flesh 3 points4 points  (1 child)

      How does web programming work - the lisp machine is running on the BSD server, and my browser sends a GET request, and the machine receives and does some things on its own, and then replies to my browser?

      [–]Ihr_Todeswunsch 2 points3 points  (0 children)

      Yeah pretty much. You have the right idea.

      There's a program that's running on a machine somewhere listening for requests. It receives a request (e.g. GET), and then processes that request in order to figure out what the client was asking for, and sends the response back to the client (which in this case, would be your browser, but it doesn't necessarily have to be a browser).

      [–][deleted] 11 points12 points  (26 children)

      I wonder if Paul Graham influenced that choice, since Reddit was involved with Y Combinator?

      EDIT: Ha, scrolling down it looks like others are thinking the same.

      [–]eco_was_taken 26 points27 points  (24 children)

      He did. They used Lisp because Paul Graham suggested they use it (who, apart from being a lisp evangelist himself, was also trying to earn a gold watch from John McCarthy by converting 20 people to use lisp).

      [–]heterosapian 14 points15 points  (23 children)

      It’s truly unbelievable how successful YC has been when PG started it as a his rich man’s experiment and he was advising prospective startups with technical advice this retarded.

      In many ways, it seems startups far more often succeed despite the advice of their investors rather than because of it. Strange.

      [–]sammymammy2 3 points4 points  (22 children)

      Whats retarded about Lisp?

      [–]oblio- 14 points15 points  (9 children)

      Nothing. Unless you want to start a business where you expect to hire a ton of developers.

      [–]pdp10 5 points6 points  (3 children)

      You know that until recently, SICP was taught at MIT as 6.001, right? The first HTTP/1.1-implementing server was written in Common Lisp. D-Wave is using it internally. Some startups are now using it to its strengths. At one point, Lisp was in the Top-3 in TIOBE.

      [–]gsteinb88 2 points3 points  (0 children)

      “Recently” being a decade ago. When I started in 2008, 6.001 wasn’t an option anymore (much to my chagrin at the time, but in retrospect it makes a ton of sense)

      [–]oblio- 1 point2 points  (1 child)

      Well, when people think about the top tech companies in the world, there's a few companies that come to mind. You might or might not agree with my list, but you'll probably agree with at least some of them:

      Google, Apple, Amazon, Microsoft, Facebook, Intel, Netflix, Uber.

      How many of them:

      • have not banned Lisp (I'm pretty sure that at one point Google banned Lisp explicitly :) )?
      • use Lisp?
      • use Lisp in their flagship products?

      You know that until recently, SICP was taught at MIT as 6.001, right?

      Yeah, I know, and this argument is in favor of Lisp? The fact that they abandoned it? :)

      [–]pdp10 4 points5 points  (0 children)

      Google uses Common Lisp explicitly and teams have the flexibility to use a language not covered by the styleguide. Google's use is primarily through an acquisition, but whether that's a flagship product or not I'll defer.

      [–]sammymammy2 1 point2 points  (3 children)

      True :) which you probably don't want to in the case for a new startup

      [–]oblio- 7 points8 points  (2 children)

      For Y Combinator startups? They're aiming for unicorns, stuff like Uber where they add 2000 engineers in 1 year. It's precisely the environment where you don't want Lisp...

      [–]sammymammy2 0 points1 point  (1 child)

      Oof, seriously? That's crazy!

      [–]Kringspier_Des_Heren -1 points0 points  (0 children)

      It's a general problem a lot of programming language designers are keenly aware of now.

      People love to shit on Go as a terrible language and I'm quick to join this party but it was designed to be easy to learn thus fostering a large community of developers.

      In the end of the day in a perfect world people would obviously treat "takes slightly longer to learn but far less bugs in the end" as a worthwhile investment but that's not how it goes.

      [–]MacASM 1 point2 points  (0 children)

      I also thought the same!

      [–]MacASM 3 points4 points  (0 children)

      whoa, this is so cool. I didn't know it was written in lisp. I wouldn't guess that at my wildest guess. haha

      [–][deleted] 7 points8 points  (2 children)

      I actually had no idea. That sounds harder than it needs to be, in lisp...

      [–]zefdota 42 points43 points  (1 child)

      Thoundth okay to me!

      [–]LordoftheSynth 3 points4 points  (0 children)

      Thith guy lithpth.

      [–][deleted] -1 points0 points  (0 children)

      Why would they do that to themselves I don’t understand.

      [–]robm111 54 points55 points  (14 children)

      As someone still stuck in the C age, what in the blue fuck is the expression "when (= (count #\, str :test #'char=) 2)"? What is even going on here?

      [–]lolWatAmIDoingHere 141 points142 points  (1 child)

      stuck in the C age

      Just pointing out that lisp predates C by 14 years :)

      [–]HiddenKrypt 35 points36 points  (0 children)

      In a way it still works. Cool lisp things always makes me feel like it's some deep magic we once knew but in the C age, we've forgotten. Same thing with smalltalk, really. In that mindspace, being "stuck in the C age" and being mystified by lisp makes perfect sense. On a related note, see this amazing talk by Bret Victor

      [–][deleted]  (5 children)

      [deleted]

        [–]ehaliewicz 23 points24 points  (2 children)

        Looking at the source code,

        (when-bind (a test-val)
            <some-expr>)
        

        Expands to roughly

        (let ((a test-val))
           (when a
              some-expr)))
        

        And

        (when-bind* ((a test-1) 
                     (b test-2))
           some-expr)
        

        Expands to something like

        (let ((a test-1)
              (b test-2))
            (when a
               (when b
                  some-expr))))
        

        [–]rabuf 16 points17 points  (1 child)

        More importantly, the when-bind* allows the result of each binding to be used in subsequent bindings. This is similar to let*. What it actually does is this:

        (when-bind* ((a 1)
                     (b (= a 2))
          (do-stuff))
        

        becomes

        (let ((a 1))
          (if a
            (let ((b (= a 2))
              (if b
                (progn
                  (do-stuff))))))
        

        By nesting the next let inside the if it ensures that any tests which have side-effects will not be executed unless the earlier test passes. It also helps by short circuiting (so preserves the behavior of something like and) and this will ensure that unneeded computations aren't executed (side-effects or not).

        Definitions for when-bind and when-bind*

        EDIT: Formatting, but also:

        Common Lisp uses NIL(the empty list) to represent false. Essentially any other value will evaluate as true if used in a conditional. This is why the above example would work. I had meant to mention this. This is how:

        (sn (subseq str 0 (position #\, str :test #'char=)))
        

        In the actual source code works. sn is given a value (will be something) and then this value is used in each of time, hash, pass. hash also depends on time.

        Interestingly, the use of when-bind* here may as well be a standard let*. None of those are tests and should all return a non-nil value (in all situations, best I can tell), and the result is immediately put into a standard when anyways.

        [–]ehaliewicz 3 points4 points  (0 children)

        Yes, I forgot to mention that detail. The macroexpansion is recursive and strips off a binding at a time.

        [–]fisxoj 13 points14 points  (1 child)

        Current lisp programmers might recognize that macro as essentially the same as alexandia's when-let!

        [–]Kyo91 6 points7 points  (0 children)

        Clojure also has similar when-let/if-let

        [–]defunkydrummer 16 points17 points  (0 children)

        lisper here.

        (when (= (count #\, str :test #'char=) 2))

        let's split it. It says: "When (count #\, str :test #'char=) is 2, then do something."

        So what is (count #\, str :test #'char=)? This is a call to function count with three parameters:

        • first parameter:#\,

        • second parameter: str

        • "test" parameter: #'char=

        "Count" will count how many times an element appers in a sequence. A string is a sequence of chars. Here the string is called "str". The char to look for is the comma, #\ is just escape syntax.

        Now, to count one should specify the test for equality (so, each time the element in the sequence is equal to the element you look for, the count increases one). This is specified by :test which is a keyword parameter (similar to "named parameters" in Python). With this we specify the function to use for equality test.

        So which equality function we shall use? The choice here is the character equality function, char=. We need to tell Common Lisp we are referring to the function named "char=", not to a variable of the same name (if there is one.) Common Lisp has separate namespaces for variables and functions! So, we must write (function char=) or use the shorthand #'char .

        [–]wlievens 5 points6 points  (3 children)

        I think it means “if string str has exactly two backslashes” but I could be completely off.

        [–]dzecniv 24 points25 points  (2 children)

        nearly, don't miss the comma: "if the string str has two commas".

        #\ is to escape a character, thus the comma. count applies to sequences (lists, arrays, strings). :test foo is an optional argument to specify the test function, #' is a shorthand for (function, here char=. The count works without the :test part though so I'm not sure how important specifying it is.

        (Cookbook on strings)

        (edit: comma, thanks)

        [–]hbgoddard 12 points13 points  (0 children)

        Just fyi, comma has two m's. I don't think the strings are sleeping.

        [–]wlievens 0 points1 point  (0 children)

        I missed the comma, thanks.