HNHacker News
TopNewBestAskShowJobs

mark242

2,159 karma · joined May 12, 2011

https://markbeeson.net

[ my public key: https://keybase.io/mark242; my proof: https://keybase.io/mark242/sigs/nJ2IAh2nEXLlnolJOnWEDYJT48SvfBE0w9dqQoQ4d0Q ]

submissionscomments
mark242··on VISA Api: The Power of Visa Network Delivered as an API
"I am really failing to understand how this could be broadly useful."

For one, it is a huge step forward from existing payment processor communication. Most card acquirer software is vintage 1997, either by sending large amounts of unstructured text over the wire, or parsing through XML, or dealing with error codes that mean nothing from acquirer to acquirer. Switching banks, for example, is such a massive pain in the ass because you essentially have to rewrite your entire card processing code from scratch. Having this easy-to-use API will encourage competitors to play catch up, and it is a pretty good selling point for using Cybersource.

Second, and you can make an argument about monopolies or whatever, but PCI is essentially controlled by Visa and Mastercard. It is entirely possible for Visa to strongarm mom-and-pop-acquirer to play by this API, and then (hopefully) add the public tokenization later. For e-commerce, storing and transmitting only tokens is huge, and goes a long long way towards mitigating the severity of these massive retail breaches.

mark242··on VISA Api: The Power of Visa Network Delivered as an API
The token comes from your acquirer (eg Stripe), not the bank-- the acquirer is the one holding the card info, then when you submit a request to your acquirer, they perform a lookup on the token, grab the card data, and do the real lifting of charging the card.

For a company like Visa, this should be a trivial feature.

mark242··on VISA Api: The Power of Visa Network Delivered as an API
https://developer.visa.com/images/cybersource.png

https://developer.visa.com/products/cybersource/reference#cy...

Ugh. Using this means that your application is in scope for PCI controls, since card data will be transmitted across your network into your application.

One of the reasons that Braintree and Stripe, for example, are so popular is because of the tokenization that they do prior to sending the card data to your systems, thereby putting your application out of scope for PCI.

If Visa added that one detail, this would be a fantastic solution.

mark242··on SoundCloud Will Be Worth More Than Spotify
Blatant Show HN plug: https://octave.is is a paid version of SoundCloud without the ads, Youtube-esque comments, and other garbage that clutters up individual artists' pages. Consider it the Vimeo to SC's Youtube.
mark242··on Expect Some Unicorns to Lose Their Horns, and It Won’t Be Pretty
This is all you need to read:

https://web.archive.org/web/20050715000000*/http://www.fucke...

mark242··on Expect Some Unicorns to Lose Their Horns, and It Won’t Be Pretty
"With that being said given the state of the public market (going down + low dividends) startups will still look sexy for a long time. I wouldn't worry about it."

This is such a ridiculous comment that it needs to be highlighted for just how myopic it really is.

Angel-and-after VC investment has been driven, increasingly, by the effects of ZIRP. "Fuck it, we don't have anywhere else to put our money, we might as well gamble on 23 red" is basically the prime justification for a lot of money that's been put into, say, companies that deliver lunches in San Francisco.

Now that we are moving away from ZIRP, sinking money into glorified AWS-React-Node applications is going to dry up, naturally. There are huge institutional investors who will no longer be willing to take the risk, period.

The "state of the public market" is getting hammered by oil prices, and by China. I don't know how you read that as "startups will still look sexy". The roulette table looks sexy when the bank isn't giving your savings account any return. The moment it does, guess what happens.

mark242··on Java 8’s new Optional type doesn't solve anything
The Scala landscape is very, very quickly creating their own libraries for similar popular Java libraries/frameworks. It is entirely possible to create an application, web or otherwise, that uses no Java libraries at all (save for the sbt dependency tree).

As for "Scala novices who just love using nulls", if you're seeing that, then the coder in question missed day 1 of Scala training, which is always "if you are writing the word null, you are doing something wrong" (right up there with "if you are writing the word var, you are probably doing something wrong").

mark242··on Sharding Pinterest: How we scaled our MySQL fleet
Am I missing the obvious? They're using text columns as blob stores for JSON data? How on earth do you query that in MySQL? How do you run a secondary index, on say the user_id? Is it just one gigantic instance of Elasticsearch or Lucene?
mark242··on New Heroku Dynos Get 2.5GB RAM
That's fine for simple one-off apps that don't require serious infrastructure, but Heroku is just ridiculous with its pricing if you need any kind of complexity.

I can burn through 1GB of Redis cache really easily; on Heroku, that's $200 a month. On AWS a cache.t2.small instance is $16 a month. The same for SQL space, disk storage, etc., once you're past a certain point Heroku becomes just unbelievably expensive.

mark242··on The Hamburger Menu Doesn't Work
James Archer, author of the piece, is Chief Creative Officer of both Crowd Favorite, and Forty, both of which use -- surprise -- the hamburger menu in their mobile sites. Is this another case of "do what I say, not what I do"?
mark242··on Show HN: Baker Street – A simple client-side load balancer for microservices
Except most people deploy dual HAProxy servers connected via heartbeat, which share a floating IP. There's no SPOF. Deploying new microservices is as simple as managing the HAProxy config file via Chef or Puppet.
mark242··on Immutable annotations for Java
case class Foo(bar: String, baz: String)
mark242··on Immutable annotations for Java
val immutableString = "foo"

val immutableList = List(1, 2, 3)

val immutableMap = Map("foo" -> "bar")

var mutableString = "foo"

val mutableList = collection.mutable.List(1, 2, 3)

val mutableMap = collection.mutable.Map("foo" -> "bar")

mark242··on HTTP/2 Is Done
"As someone who would like to avoid going to the trouble to implement HTTP2 (...)"

Good luck with that. Google has been incredibly adept at using the leverage of their search engine to make webmasters adhere to best practices. ("mobile friendly" e-mails lately, anyone?) Once HTTP/2 lands as a default in Chrome, Apache, Nginx, and Netty, of course they'll push HTTP/2-friendly sites higher in search results.

mark242··on Reactive prefetch on Google Search: 100-150ms speedup
I would imagine that once HTTP/2 becomes a serious implementation, this kind of thing will be unnecessary.
mark242··on An Opinionated Guide to Modern Java, Part 3: Web Development
"The asynchronous, non-blocking approach, is always wrong."

http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Comput...

If you have a method that relies upon a DNS query, and your DNS server starts to respond to requests very slowly, your blocking application will run out of threads very quickly, and you'll be spending time poring over thread dumps trying desperately to see why all of your threads are waiting when the load average on your app server is basically zero. Your monitors will be going off like crazy because it appears that your application is flapping, sometimes able to handle a request and sometimes not. You will be tearing your hair out (and Java devs have all done this, though maybe not because of DNS).

If you have a non-blocking application, you will get an alarm that one of your pages may be acting a little slower than normal (even though the rest of your app is running normally). You'll look into the controller source, see that it's performing a DNS query, and poof, your debugging is done and you're off to restart bind.

mark242··on An Opinionated Guide to Modern Java, Part 3: Web Development
Don't take my comment as "quit living in the past". Take it as "here's how exciting the future is". I'm not telling you your startac phone is crap, I'm telling you there's this great new thing called the iPhone/Android/smartphone.

The real benefits of Play and Akka become apparent when a third-party service you send API calls to starts acting flaky. Or when your web service that you offer to clients is suddenly being hit by an iPhone game that just got purchased by a million people. Or when that nasty little bug that winds up throwing an exception from time to time rears its head all of a sudden. Play and Akka give you a resilience that is very hard to come by in the Java world.

Typesafe's home page has, in giant type, "Applications are becoming Reactive" and they are absolutely spot f'ing on. Writing blocking code, waiting on threads, assuming you're running on one JVM, these things are great and all, and very easy to do because all of those templates are built into IntelliJ and you just have to click a few buttons to get all that, but wow, the performance difference once you get into the Play world is just frighteningly good.

mark242··on An Opinionated Guide to Modern Java, Part 3: Web Development
Blocking in Play should be foreign. On modern hardware architectures, writing code that blocks is the equivalent of throwing up your hands and saying "I can't trust myself to write efficient code so I'll just scale out my hardware and hope for the best". This is how Amazon winds up making so much money off Java developers who get constrained by thread pools and wind up spinning up a million instances of m3.medium machines.

This is, imho, what makes Play so fantastic. That you can have def index = Action { hardComputation() } for blocking code, and change it to def index = Action.async { Future { hardComputation() } } and you have magically changed your application to be asynchronous through the request-as-actor paradigm of Play. Play makes it easy to write async code. Play makes it way easier to control configuration for things like thread pools, dispatchers, and the like vs. Jetty. The performance of the nonblocking async code is incredible, and winds up saving a ton of money and developer time.

mark242··on An Opinionated Guide to Modern Java, Part 3: Web Development
It's funny. An "Introduction to Modern Java Web Development" sounds like a primer for the Play Framework, Scala, and Akka. Each of the examples looks like the starter documentation for Play, in that you've got your json manipulation, routing, connecting to a database, DI, actors, etc.

Java devs-- you seriously owe it to yourself to spend the time investigating and ramping up onto Scala and Play. This is where the future of Java web app development is being driven from, by Typesafe and the Play / Spray /Akka open source developers. You do yourself a great disservice by sticking with Spring, Hibernate, JBoss, and the old standbys.

mark242··on A Look at the Formula 1 Steering Wheel
Surprisingly enough, before the 2014 season with brake-by-wire, drivers would have to adjust the brake bias (forward vs rear) by moving a little lever down next to their knees. They'd be taking their hands off the wheel all the time.
mark242··on A Look at the Formula 1 Steering Wheel
The reason that -- at least on the Sauber -- the speed is displayed so large is that it's the number that's changing the most rapidly. It isn't a primary piece of information, but when the car is accelerating away from a corner, the driver needs to be able to discern acceleration by way of more than just the seat of his or her pants. With the immense amount of torque available this year, being able to optimize that acceleration out of a corner is absolutely paramount.

The "marks to hit for straightaways or (...)" are visual indicators on the sides of the track, showing the distance to the corner. Part of what makes these drivers the best in the world are that they're able to hit -- mostly -- the exact same braking spot coming from 300kph down to 60kph lap after lap after lap, without a computer telling them when to brake.

Coincidentally, that row of LEDs on the top of the wheel is supposed to tell drivers when to shift, but teams found out a long time ago that the visual indicator wasn't being processed fast enough by the drivers' brains, so now drivers get a little beep in their ear when they're supposed to up/downshift.

mark242··on Choosing Scala
Having worked with Scala for the past almost two years, I can tell you this: you're missing out by not using IntelliJ. It is a huge timesaver, not just from the code completion or the inspections, but also by being able to fire up FSC outside of IntelliJ and have your code recompile very, very quickly when you make changes. The one thing that IntelliJ doesn't do very well yet is work with sbt. It works, sure, but the maven support in IntelliJ is that much further along, so I generally still use maven for in-IDE dependencies, and then write up an sbt file when I publish my work.
mark242··on A killer app for Bitcoin? – Spam and Phishing Emails Killer
Specifically, "Requires immediate total cooperation from everybody at once"
mark242··on No More Callbacks: 10,000 Actors, 10,000 Threads, 10,000 Spaceships
An Akka actor simply must not issue a DB call

That's untrue. With Akka's pipe pattern, you can take the results of any future and pipe it back to the sender, including using a map on the future if you like. This is how we do reactive database calls in Akka. For example:

  def receive = {
    case msg => {
      val f = future { myDatabaseResult(msg) }
      f map { result => myTransformResult(result) } pipeTo sender
    }
  }
At no point does this actor block. Assuming you even have something like Play calling this actor, you wouldn't be blocking there, either, you'd take the result from the actor, likely map it to a result, and Play would asynchronously return that. My basic rule is that if you're typing Await.result anywhere in your Play/Akka code, you're doing it wrong.
mark242··on Java to Scala converter
A good Scala programmer will never write the word null in their code. Ever. If I was overly concerned that the method was going to be called by Java code, I'd put this:

  Option(s).getOrElse(List[String]()).filter(str => Option(str).fold(false)(_.length > 5))
mark242··on Java to Scala converter
Here is the magic of Scala.

A collection designed for concurrency:

val users = List("seanmcdirmid", "mark242").reverse

That same collection, designed for parallelism and concurrency:

val users = List("seanmcdirmid", "mark242").par.reverse

mark242··on Java to Scala converter
Ah, synchronizedCollection, the...

hang on...

wait a sec...

one more sec, someone's doing something...

now? no, not yet, wait...

how about... NOW! synchronizedCollection, the global lock for Java's mutable datatypes.

Here's the fundamental difference between Java and Scala: if I say, in Scala, val people = List[String]("quacker", "mark242") then by default people is an immutable list. I don't have to do anything special. In Java, either I'm suddenly using the Guava libraries to get something similiar (but not the same), or I'm doing all kinds of funky dances around list iterators, or I'm using Arrays.copyOf, or what have you. In any case, you have all of this extraneous code, when it isn't necessary.

Quick: give me a list comprehension method in Java that takes a list of Strings and returns that list, filtered, of Strings that are only five characters or longer. Make it null-safe and thread-safe. This isn't difficult-- you're thinking about 6-7 lines of Java code in your head, right? Null check, synchronized, new ArrayList, for(s in sList), that kind of thing, right?

In Scala, it's this. Some would argue you don't even need a separate method.

  def getFiveCharacters(s: List[String]) = s.filter(_.length >= 5)
If I have millions of things stored in an immutable data structure, do I not have to copy the entire structure when I want to modify anything within?

Dear god, man, what are you doing wrong in your Java code? This is the exact scenario where you want an immutable list, otherwise you'll be running synchronized code and precisely one core of your CPU will be glowing red like lava, while your other CPU cores sit idle.

I just did this in the scala repl:

  (0 to 1000000).toList.par.filter(_ % 100 == 0)
What that does is grab all of the integers from 0 to 1,000,000, convert them to an immutable List, then filter that List (yes-- an iterator! with a filtered copy!) by only taking numbers divisible by 100. The whole thing takes a couple hundred ms in the repl (which is fantastic, since it's compiling then executing the code) and almost no memory overhead. For code that is absolutely thread safe. And the ".par" makes this run in parallel on all my CPU cores.
mark242··on Java to Scala converter
-- I'm not convinced that the overhead of copying immutable data doesn't outweigh the benefits of the ability to trivially parallelize the code.

Let me introduce you to my friend, Mister ConcurrentModificationException. He's a wily fellow-- he rarely pops up when you're doing local development, but he has this nasty habit of showing up in production whenever you start hitting a decent load. He's like Keyser Soze. You see him, then you try to debug the place he shows up, and poof he's gone, back into the shadows from whence he came, only to reappear when you try to iterate over that singleton java.util.ArrayList once more.

Now, let me introduce you to my other friend, Miss scala.collection.immutable.List. She's a superheroine. You can run code using her on one thread, or ten threads, or ten thousand threads, she doesn't care, you're always going to get the same iterator back when you call List.foreach. For the very small price of a little bit of garbage (which Mister ParallelGC takes care of very readily), Miss immutable.List will return that filtered list the exact same way, every single time you run the filter method with those parameters you set. You can run code with her in development, staging, production, she's always ready to go, and you'll never run into Mister ConcurrentModificationException when you're dealing with Miss immutable.List.

-- I'm not convinced that a project

What do you mean? All I read was "I'm not convinced that a project". Someone else must have come by and edited your post before I was able to read it.

mark242··on Java to Scala converter
This is completely untrue.

Every single Java developer that I introduce to Scala-- every single one-- six months later, they tell me "please don't make me go back to Java".

The "disenchanted" piece, I think, comes from the fact that if you're just writing Java-OO-style in Scala, you're losing almost all the benefits. Once you start working with the FP style, understanding Options, working with fold, list comprehensions, and the resulting massive reduction in lines of code, you start seeing how FP Scala code becomes the last refactoring you'll ever need to do, because it's so concise.

mark242··on Effective Scala
I don't think that's right.

TraversableLike, and FilterMonadic will both size up the resulting return value based upon the length of what's passed to it. You'll get a List of N items, and the call to flatMap will also traverse the list to remove/flatten the Options. Items will then get dropped in the List. You're looking at one or two collectable objects every time you run through that method, as opposed to bin.items.length collectable objects in your original code.

Look at it this way-- what happens if bin.items is a List() of 10M objects? completed_items can be replaced up to 10M times. The .flatMap creates one collection of 10M length, removes the None objects, and returns the resulting List.

← PreviousPage 9 of 12Next →