Hacker Newsnew | past | comments | ask | show | jobs | submit | tangus's commentslogin

Everybody carries a gun in Heinlein stories, so those terrorists will be quickly dealt with by armed citizens, thus confirming the superiority of Libertarianism.


In 1940 when he wrote this Heinlein was a New Deal Democrat supporter of Franklin Roosevelt. He was an active progressive who had recently worked on Upton Sinclair’s socialist “End Poverty in California” campaign. His libertarian shift was twenty years in the future, in his fifties.


Those people were "everyone's self-sufficient, so only a few people down on their luck need the state" folk. They didn't realise that loads of people wouldn't be like that if they didn't have to be.


Heinlein's alleged libertarian shift. In the 1940s Heinlein was mentioned as a Social Credit supporter which implied he was always on the libertarian side of Socialism. Social Credit was the American party killed/disrupted by the red scare that believed in a UBI and universal health care. His posthumous published but first written novel "For Us, The Living" is even a wonderfully naive paean to UBI and credits a Social Credit party for its enactment and ensuing utopia.

Heinlein formally disowned some of those ideas, but did so under the duress of the McCarthy era and the Red Scare. Yet he also kept writing about them, just somewhat cloaked. Both "Stranger in a Strange Land" and "The Moon is a Harsh Mistress" are some of the most Socialist books I've ever read, if you assume the first person narrators are for the most part bloviating Vonnegut-esque patsies (rather than the author stand-ins they are often read to be; Heinlein seemed to clever for that). "Stranger in a Strange Land" is entirely about community effort and Socialism. It contrasts interestingly with "For Us, The Living" in part because cynicism seems to have been the big shift and Heinlein can no longer imagine America leading the charge towards Socialism and invents a dead Martian race to do it. "The Moon is a Harsh Mistress" is often credited as a deeply Libertarian book, but I think a lot of that is misreading the narrative and not paying attention to especially the second half of the book, which is entirely about AI-lead worker's strikes towards the goals of unionization. The first half sounds like a Libertarian dream and the narrator character describes it in lush terms that make it sound so, but plot is about overthrowing that and building a much more Socialist Moon together. Heinlein even comments about that misreading in "The Cat Who Walks Through Walls" which intentionally begins on a Moon like the one people reading the first half of "The Moon is a Harsh Mistress" seem to love, dialed up to 11 to better make it a grungy harsh Noir place for a classic gumshoe-for-hire to live, and eventually through world hopping the main character does happen to stop by "Mike's Moon" (Heinlein actually names his timelines based on the first man to step foot on the moon, I'm feeling to lazy to look this one up, but this timeline is also prominently known for a Moon AI named "Mike") after the events of "The Moon is a Harsh Mistress" and it reads a lot more Socialist and lot kinder than the protagonist's Moon the book started in.

A lot of modern Libertarians wouldn't expect a crossover boundary with Socialism like Social Credit, which is one of the problems with claiming politics is a spectrum or plane (there are more useful curves where ideologies meet than that), and a lot of modern Libertarians don't trust ideas like UBI and universal health care and don't trust things like unions again this century (despite having past pro-worker/pro-union perspectives), so it is easy to claim that Heinlein shifted over 20 years. But also, if Heinlein was a Social Credit + Libertarian throughout his life, the rest of politics shifted so much around Heinlein that he may have stayed in exactly the same place and it looked like he shifted.

I think his writing certainly shifted, but I think towards cynicism and anger and frustration after WWII and especially after the Red Scare, not necessarily towards deeper Libertarianism.

I also think there are lessons there for modern Libertarians, too. There are modern Libertarians feeling receptive to talking about ideas like UBI again as something that can have space in Libertarian conversations. There could be room in American politics again for a party like Social Credit that can be a coalition between Libertarian values and Democratic Socialist ones. The Libertarians could find better creative allies than destructive tendencies of "the far right". Talking about Heinlein's books isn't a bad place to start those conversations.


Thanks for that scholarly and thoughtful comment. The intro to The Roads Must Roll is an example of that complexity. It starts with a labor union meeting arguing for the workers to strike, and then a counter argument that could be an unacknowledged contribution from Ayn Rand. And this was from the presumably progressive early Heinlein.

I'd like to be there for a debate between 1940 Heinlein and 1980 Heinlein. I wouldn't be surprised if that event is scheduled for the Howard family reunion at the end of time and Time Enough for Love.


Which, to be fair, is also a Socialist utopia couched into a lot of Libertarian jargon/perspectives (to well beloved to mock extremes such as the way that society handles, say, the "Extreme Libertarian" approach to the incest taboo).


Looping in Ruby is the opposite of awful. You only have to define an `#each` method in your class and include the `Enumerable` module, and you get a plethora of composable methods to iterate and accumulate in every which way. I find it nothing short of brilliant.


Yet, iterating over several collections and accumulating values is awkward.

It is not that it is easy to implement the iteration protocol, it is that the construct for looping universally sucks. Even the awful loop macro from common lisp runs laps around most other facilities. Racket's is even less powerful, but is miles better than what python offers.

Ruby can do some destructuring, but not enough to actually be useful.


It may be somewhat awkward; zipping collections to iterate over them in unison makes the first one (the sender) seem special, while it not necessarily is. And accumulating more than one value isn't always straightforward; you usually have to reduce explicitly. But it's so much better in the general case!

Like the example you showcase your macro with. In Ruby it would be:

    lst = [[1, 2], :dud, [3, 4], [5, 6]]
    lst.grep(Array).flatten.sum
    => 21
You can see what it does at a glance, you don't have to immerse yourself inside the directives to follow the logic. And when you can't do that, declaring iterators and accumulators outside a loop and then iterating and accumulating "by hand" yields code not so different than your more complex examples.

  def partition (arr)
    yes = []
    no = []
    arr.each do |elt|
      if yield elt
        yes << elt
      else
        no << elt
      end
    end
    [yes, no]
  end


Your example of the flatten and grep will build two intermediate arrays before summing. That's inefficient.

I would also reach for higher order functions for most things, but when you need things to be fast that is not how you would do things. You would express it with nested for loops and ifs, and you would have to juggle state all by yourself. That is my main critique of looping constructs: they only cover the absolute simplest case, and then you are by yourself.

The partition example is not a particularly nice implementation of partition. It is there to show that you can write non-tail recursive loops, meaning you can use it to do tree walking and such. Using mutation, like your example, would make it prettier, but would make the code unsafe with schemes call/cc. Even a traditional named let (tail recursion) would be prettier.


For the record, if you want to avoid the creation of intermediate arrays, you can:

    lst.lazy.grep(Array).flat_map(&:itself).sum
Not as clear, because the standard library doesn't have a `#flatten` method for lazy enumerators.

But the point is the interface, not the implementation. Efficiency doesn't mandate assembly-like DSLs. Your interface could be as clear and clean as Ruby's and produce fast, inlined code by the power of macros. Ruby doesn't have macros, so chaining lambdas is the best it can do.

Ruby also has call/cc. None of the iterating methods has any provision to make them "safe" from it. They aren't safe from modifications to the iterated collection either. I think it makes sense; being forced to accumulate using only linked lists and having to be constantly on guard to support a rarely used quirky feature is a bad tradeoff IMO.


I dont think interfaces is the point. As it is now in ruby you have to pick between comfort and speed when you can have both.

Continuation safety has never been a thing in ruby, so caring about it doesn't make much sense regardless of the presence of call/cc.

And lastly, neither my loops nor others I have mentioned only accumulate into lists. My loops a re in the most general sense a left fold, although right folds are possible to write as well. I provide accumulators for just about any data type available, and writing a new one yourself is pretty easy. You can express lazy loops with it as well.

All without sacrificing performance. Any performance in most cases. I haven't written much ruby since the 1.9 days, but back then I remember having to rewrite the nice .each{}.blah.blah into for loops. I could prototype in a nice way which was nice, but in the code I ended up shipping I had to juggle state using for loops because the thing I prototyped ended up being a bit slow.

I use map, filter and friends in scheme all the time, but when those are insufficient or too slow I don't have to resort to named lets. I can just use the loop macro which compiles to a named let.


It's paywalled, please provide a workaround.


in an effort to teach you to fish instead of watching you demand a fish, I'd like to introduce you to the site https://archive.is/


Careful. Seeing how I was downvoted for asking, it looks people here don't want that information to spread.


you see how I was upvoted for providing? that's the takeaway here, not that people don't want to spread this information but that leaving a comment that just says "this is broken, fix it" doesn't help anyone


In the late 90's I had a girlfriend who worked for a shop that made web pages in COBOL. I thought those were COBOL's death throes, but apparently I was mistaken...


that's it. you get the reward for the weirdest gf ever.


They provoked the strike on purpose by giving the workers an unacceptable contract. The aim was to wreck the union (they succeeded). They prepared in secret for two years for this.

Here's an account: https://www.huffpost.com/entry/wash-post-busted-pressmens-un...


Also related: https://puzz.link/db/



Even if it didn't dedupe strings, mutable string literals means that it has to create a new string every time it encounters a literal in run time. If you have a literal string in a method, every time you call the method a new string is created. If you have one inside a loop, every iteration a new string is created. You get the idea.

With immutable strings literals, string literals can be reused.


Here’s a more concrete example:

You make an arrow function that takes an object as input, and calls another with a string and a field from the object, for instance to populate a lookup table. You probably don’t want someone changing map keys out from under you, because you’ll break resize. So copies are being made to ensure this?


Strings are going to keep being mutable by default. Only strings created by string literals won't be.


Thanks for the clarification! I have adjusted my wording.


>I do not understand how you can even begin coming to the conclusion of ...

Obviously he's not serious, he's playing the part of the out of touch old man.


Ah, okay. Maybe it’s more obvious in context, or maybe my hyperbole detector is broken.


I can imagine grumpy an old man frustrated by a different paradigm shouting at his computer.

We all become that eventually, hopefully we can all be as poetic and humble (and honest) about it.


Sure, but “JavaScript [is] utterly broken, incapable of executing the simplest programs without errors” is a bit much. I find it hard to believe that even when I’m completely out of touch, I’d say that about a language that people are obviously productive in (as much as I hate JS myself).

But apparently I didn’t get the hyperbole.


Sometimes when I play a point n click adventure and I am stuck for hours on a puzzle I tend to think: I've tried everything... surely there must be some kind of bug for why I am not proceeding.

Only to then realize (after reading the walkthrough) that there was indeed a way.

I think it's human nature to find (rather search) blame not only in yourself but everywhere else... anyhow, since the author is reflective we should be forgiving as well.


Just as a small note I did not get that too.


It is a rather common mindset among beginner programmers though, particularly younger ones.


Related to "Last is first", old Spanish books sometimes put at the end of the page the first syllable of the next page. (It was quite disconcerting when I first saw it.)


That's called a "catchword", and it's common in many older texts (not just in Spanish). It serves two purposes - it makes it easier for a person reading the book aloud to read smoothly while turning a page, and it makes it easier for bookbinders to spot pages which are missing or out of order. (Page numbers were, believe it or not, a later development.)


It was common throughout Europe in the early modern era.

I've got a book of recipes from Williamsburg, Virginia, a kind of outdoor museum LARPing as 1775. The recipes are from various sources, but they typeset it as a period document, including those catchwords. I find it charming.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: