The underlying problem is due to predominately calling methods to obtain values, which violates encapsulation. This is also known as tight coupling. A much more robust solution to avoid the null pointer problem is to loosely couple the classes through well-defined interfaces using a mechanism called self-encapsulation. Consider:
In the tight coupling example above, each time the Blue Agent requests data from the Green Agent a null value could be returned, which must be checked. Regardless of the checking mechanism (assertions, conditionals, annotations, catching exceptions), the entire approach is incorrect.
Instead, the Blue Agent should query the Green Agent to determine the correct course for subsequent actions based on a boolean result, thereby maintaining encapsulation. Such loose coupling offers critical benefits. First, it eliminates null checks, as null cannot be returned. Second, it permits extending the class without imposing changes on client classes; e.g., if the Green Agent were to require middle names, the Blue Agent code should not have to change.
The tight coupling anti-pattern is everywhere. In my mind, the most prominent example is file handling, such as:
String extension = FileUtils.getExtension( file );
if( "JPG".equalsIgnoreCase( extension ) ) { ... handle JPEG file ... }
if( "PNG".equalsIgnoreCase( extension ) ) { ... handle PNG file ... }
Beyond terrible, this is abysmal code and all the null-checking in the world–automated or otherwise–won’t improve it. First, it uses a “utility” class, which isn’t a true class (see Bertrand Meyer’s book). Second, the series of if statements would be better as a dictionary (mapping values to methods). Third, it isn’t extensible. There are more issues, but the jist should be clear.
A flexible approach avoids the problem’s crux entirely: stop breaking encapsulation. I’ve drafted a presentation on this subject that includes source code examples.
http://whitemagicsoftware.com/encapsulation.pdf
Constructive critiques are most welcome.
The practice you are criticizing has nothing to do with null pointers, it also doesn’t cause the other problem that you say it does (which is unrelated to null pointers), and your style of argument is profoundly unconvincing.
You’re arguing (maybe unintentionally?) for eliminating methods with return values, which is to say, all methods should be “commands” in Meyer’s sense. Meyer certainly doesn’t argue for eliminating queries (methods with return values), just separating them from commands. CPS-transforming buggy code doesn’t remove nulls; it just transforms them from return values to arguments. I’m not convinced that CPS-transforming tightly-coupled code makes it loosely-coupled, either.
Meyer’s Eiffel, which allows methods to have return values, is in fact free of null-pointer problems. So are ML and Haskell. In Haskell, in fact, functions that don’t have return values are useless, because there are no side effects. ML and Haskell don’t have encapsulation at all, but they still don’t have null pointer problems.
As for Blue Agent, I am deeply unconvinced by examples that rely on analogies to real-world objects:
I propose a new rule for discussions of object-oriented programming:
Anyone who brings up examples of Dog, Bike, Car, Person, or other real-world objects, unless they are talking about writing a clone of The Sims or something, is immediately shot.
I feel that this new policy will improve the quality of the discourse enormously.
If you want to find out if your ideas have merit, try them on some real code. Then you can show the “before” and “after” versions of the code, and show how the “after” version has some virtue that the “before” version lacks; for example, that some possible enhancement can be carried out by a local code change instead of a global one, or by adding code instead of changing it. Also, if you want to convince people who didn’t go to your talk, post an actual prose explanation of your argument, not just the bullet points, pull-quotes, and code samples in your slides. That way, people will be able to understand what you’re saying, instead of having to imagine it.
You may find it useful to use a more succinct language than Java for your code samples. Python or JS are much better at this.
Metaphors and similes are fine for helping people intuitively grasp your way of thinking. The problem is that they work equally well for learning ways of thinking that work and learning ways of thinking that don’t work. They are useful when you are trying to persuade someone who already trusts you to see things your way, but they do not help to persuade people to trust you or that you know what you are talking about.
I hope that is sufficiently constructive: I have given you specific step-by-step instructions for how to improve your presentation of your ideas, as well as, I think, identified some problems that you will have to address. I regret that you will probably have to do substantial background reading to understand what I have written above.
(And I don’t actually want to shoot you.)
I’ve written a post on their discussion site about the Deuce editor architecture from the Dylan IDE. Deuce was a descendant of ZWEI, a precursor to GNU emacs. This architecture would also help them solve some of their current performance and memory usage problems.
The post is here: http://discuss.atom.io/t/the-deuce-editor-architecture/2218
Lots of marketing speak.
How does IOS security compare to other phone OS’s? Other hardware platforms? Is it best of breed?
Can we do better in the future?
Anyone care to comment?
I’m surprised you’re so quick to dismiss this as marketing speak. That the 5s doesn’t stores fingerprints, but something akin to a hash of the fingerprint, is something worth knowing. The section on Data Protection APIs available to apps is also fairly technical.
What information is missing that you think is needed to make this a technical document?
You’re right. My comment might be a bit too trollish.
I think, in general, I am put off by all the “fluffy sentences.”
The introduction might have put me off with it’s talk of “major leap forward” and “stringent security features.” So, I didn’t read everything.
But more examples of fluff:
Every iOS device has a dedicated AES 256 crypto engine built into the DMA path between the flash storage and main system memory, making file encryption highly efficient
“Highly efficient” isn’t exactly technical. Efficient in time or space or power? I think they were talking about power. How much more efficient, then? Why are they even talking about efficiency, when the topic is security?
But my questions in the grand parent stand: Is IOS more secure than other platforms like Android? That topic of conversation was really the point of my post.
“Highly Efficient” may be an approximation, but it certainly isn’t non-technical. It is also used in a lot of technical papers:
http://scholar.google.com/scholar?hl=en&q=highly+efficient&btnG=&as_sdt=1%2C5&as_sdtp=
In regards to whether or not iOS is more secure than Android, that is a massive, and likely very difficult to quantify answer.
“Highly efficient” is not technical, in my opinion, because it’s not backed up with any facts (and doesn’t pertain to the topic of security). I think it’s just fluff.
In the google search you posted, for example, on the first result I looked at the article and they explain what they mean by highly efficient:
lipofection is from 5- to greater than 100-fold more effective than either the calcium phosphate or the DEAE-dextran transfection technique.
I think we may be playing semantics. Regardless, I do agree that it would have been nice to have a far more granular analysis of the various components that make iOS “secure”.
Why are they even talking about efficiency, when the topic is security?
People don’t use inefficient crypto. They are pointing out that they can easily, transparently encrypt all the data on the phone, as opposed to selectively only encrypting the very most important bits.
Why doesn’t every computer always encrypt everything on the hard drive? Because people are afraid it’s too slow.
As another point that’s not mentioned in the paper (likely beyond the scope), the ios kernel is perhaps better hardened against memory corruption exploits than any other I’m aware of.
Another reply. :)
Securely erasing saved keys is just as important as generating them. It’s especially challenging to do so on flash storage, where wear-leveling might mean multiple copies of data need to be erased. To address this issue, iOS devices include a feature dedicated to secure data erasure called Effaceable Storage.
That’s something I’m happy to read and which I didn’t know when I woke up this morning. When I erase my phone and mail it to Amazon, I like knowing that the data on the phone is not trivially recoverable with some undelete command. That’s not fluff to me.
I alluded to ios kernel hardening. For some of the things Apple doesn’t talk about, refer to this presentation.
Here is some analysis comparing android to ios, based on the original article (I think).
No? I mean, I came up with a better bug that was even more plausibly deniable without even trying.
http://www.tedunangst.com/flak/post/how-to-screw-up-crypto-the-easy-way
To clarify, a broken memcpy of a sha1 hash that only copied four bytes would have been much harder to detect by code inspection, and practically impossible to detect by random fuzzing. But it would have allowed anyone with a few hundred CPU hours to throw at the problem the ability to create a cert with a partial hash collision that ios would verify.
I think well informed infosec folks have seen it all before, know exactly how previous bugs happened, and are therefore less quick to rule out the possibility of unintentional mistakes.
What do I think is strange? John Gilmore watching the IPSEC sausage get made, saying nothing, then ten years later somebody tells him the NSA interfered in the process and suddenly he says “oh, yeah, I saw the whole thing.” what???
It’s all shadows on the cave wall.
Sublime Text features + JavaScript instead of Python for plugins would probably appeal to a lot of people.
Would people really switch to a new editor just because the plugin programming language is different? That seems like a lot of trouble for no benefit.
Agreein, There are so many vim plugins you would have to re-write! Maybe adding a vimscript interpreter would lessen the re-write time…. maybe..
JS would definitely lower the barriers to entry on creating plugins, which if the community were large enough, would lead to more/better plugins which would be a big advantage. Of course, the editor itself would have to at least be on par with the competitors.
The reason node doesn’t worry about callbacks is because the issue is going away with ES6 generators. This will be available in 0.12 with the –harmony flag; or you can just use the latest 0.11 unstable.
Promises work only in a limited number of scenarios and gets ugly pretty quickly; a fairly common use case:
The problem of callbacks in JS cannot be solved in a library. So they’ve has done the right thing; fix it in the language itself.
What can’t it be solved in a library? This is how it’s solved in Haskell and Scala, for example.
Haskell has built in support for monads. And works well with async code. Also see computation expressions in F#. Scala seems to be still debating how to best do async. But they have more tools to attack the problem than JS had.
What does built-in support mean? If it’s the do-notation, then that’s just syntax, which Scala has (not quite as good, but still). I’m not sure if async in Scala is being debated - you either use
scala.concurrent.Futureorscalaz.concurrent.Task.So I don’t see why JavaScript could not solve it as a library - even if it’s not as capable of abstraction, the “built-in support” seems to be just syntax.
I have rewritten the code in my first comment using generators, which IMO is cleaner than the one with promises. You can convince me with the Scala equivalent of this:
The Scala I write avoids exceptions, so it’d be something like this:
But you’re able to throw an exception, if you really want. Also, the type-signature could be inferred.
So will getUser() take a string, as it should? I am not able to tell how execution will suspend at: user <- getUser(username)
Forgive my inexperience with Scala.
The type of
getUserisString => Future[User]or something similar.Similar to the do notation. I was saying that this needs to be solved in the language. You are relying on language support to turn it into a callback pyramid; actually the other way around.
Add: Two ways you could do this. State machines or like you showed above. You need language support for both these things.
Yes, the problem with Callback Hell is not a syntactic one, though.
Lack of support for the expressiveness demonstrated above is not a syntactic difference.
clarifying: I was saying that this requires support in the language. Your example and my example demonstrates the same thing.
While I absolutely agree that JavaScript lacks Scala’s expressive power, what was demonstrated above which is missing?
Here’s the desugared version:
JavaScript has lambdas, what else does it need?
This is the callback pyramid that JS users fear; it becomes a problem real quick.
Example, which doesn’t work without extracting ‘….’ into another function and passing it into getAmazonMinOrder():
Hope the example is clear enough. I am going to head out for a bit. Will reply once I’m back.
This is one of the reasons why promises/futures are not callback hell:
We’re working with values, not side-effects. It’s possible to abstract and reuse values.
I gave you a poor example (and left), I should have used the earlier example itself.
What made your Scala example easy to write is the for comprehension. For a JS version of the same thing, the first snippet I posted is how it looks. The limitation of Promises (in JS) is evident in that example; you get only the last value inside the then() function. The callback pyramid is avoided only in the simpler cases.
I think we are mostly on the same page. The difference is that you use a language in which promises aren’t painful to write, which (probably) shaped your opinion.
bct posts a link below, which proposes a solution in JS. The author of that article calls it ‘then hell’.
Execution does not suspend. It’s creating a Future value.
Here is one approach to this in Scala, uses macros. https://github.com/scala/async
Here is a proposal which wants to add async/await from C# and also goes into why it is useful: http://docs.scala-lang.org/sips/pending/async.html
Neither of those are used or taken past a few experiments.
The Haskell compiler (GHC) does quite a bit - but why would a browser have to do all of that? Languages which compile to the browser already do the type-checking and optimisations before sending across the JavaScript - so I don’t get why retrieval over a network is being considered.
Hang on, so what’s the practical concern? I don’t understand your original comment.
This is an interesting proposal for avoiding that situation.
Basically: Accept promises as function arguments. Then your example becomes:
You probably want the
getXfunctions to accept non-promise arguments too, so some of the complexity is just moved, but I suspect a library can hide most of it.getUser() taking a promise instead of a string is not semantic. We are going to have to ask the question for every function we write; whether it needs to take a promise or a value.
In the slides I linked he solves with a library that wraps functions so they can accept either a promise or a value.
I don’t know if it’s a good idea, but it’s an interesting one.
Question doesn’t make sense, neither do the answers. There are pointers everywhere in Java; calling them references and using . syntax doesn’t change that.
Isn’t the question about C++?
“I’m trying to map my totally wrong mental model of Java onto C++.”
I don’t understand what’s wrong with OP’s question. The person didn’t understand stack vs heap allocation in C++, because his experience is in Java, so he asked about it. He doesn’t claim there aren’t pointers everywhere in Java. Seems fair to me.
I think a simpler answer would have been “In Java, all those ‘objects’ you thought you were using were really pointers.” Boom, the light goes on.
The accepted answer isn’t wrong per se, but given the OP’s lack of understanding, I don’t see how they could have possibly comprehended half the answer they accepted. Sounds legit, check mark.
I would love to see OP’s code before and after this advice. My bet is they are in for a world of hurt, either returning stack references or dealing with buggy copy constructors, let alone the insane compiler optimizations that can cause the compiler to elide or not elide any number of constructors and assignment operations.
Mostly I’m confused why this is on lobsters.
It frequently seems to me that the terminology Java adopted does a disservice to programmers trained with it. It cannot possibly be the case that pointers are arcane and incomprehensible while references are a simple enough concept that all of the millions of Java programmers can understand and use them when, as you point out, they’re equivalent. (Though maybe I’m giving many Java programmers too much credit.) It seems to me that calling references “managed pointers” or the like would save a lot of intimidation and the need for an epiphany moment realizing pointers are not a scary new concept.
What is it exactly that doesn’t make sense? The wording may be imperfect (what are “the object themselves”?), but the examples make it clear what the person is asking. The highest ranking answer may not be encyclopedically complete, but does a great job at pointing the reader in the right directions.
Pardon the meta-talk.. but it is sad to see that someone has downvoted tedu’s comment without explaining why. I thought that was a HN phenomenon we try to avoid here.
This is tricky when all our systems are distributed, all our software is written in a hurry, and most of us aren’t expert programmers. There are a couple of possibilities:
Programmers with the necessary level of mathematical sophistication to find bugs in published proofs of distributed algorithms will program circles around the rest of us, who will be stuck wasting all our time debugging the messes that we create; and consequently the software used by the vast majority of people will be written by a tiny minority of elite programmers. This resembles the situation with, say, relational database management systems, where lots of people have written some crap to store data on disk, but most people use SQLite, MariaDB, or Postgres.
We’ll make do with incorrect algorithms and patch them when they fail, trying to make sure that the failure modes are not too dangerous. This resembles the situation with most web sites.
The idea “if it’s in a published paper it must be right” is certainly naive, but I don’t think it’s odd or unusual. For people with extensive academic training, seeing a paper as a step in a long walk towards truth is second nature. For people without it, a paper in a good journal with respected names is treated as strong evidence that the contents of the paper are right. That heuristic isn’t actually a bad one, as these things go, but still occasionally produces incorrect results.
Hadoop isn’t a database. Hadoop at its core is a map reduce framework. Its not about “scaling to 10 TB”, its about processing data.
Here’s a simple example:
You generate 100GB of log data a day. For some people, that is a ton of data, for others, not very much. I need to be able to find information in that 100GB within a couple hours. A python script on a single or a java app on a single box won’t cut it. They won’t get me the answer I need in the amount of time that I need it. So I spread the load across many machines. I’m getting the answer that I need but, I’m in a painful scenario of dealing with my home grown cluster of machines.
Hadoop is just a standard framework handling cluster’s of map reduce jobs. A nice chunk of hard work has been done for you. Lots of rough edges have been shaved off.
It doesn’t matter what you think as an outsider about someone’s choice to use Hadoop or other technologies unless you understand their problem. I have data, I need to get an answer in X period of time, to do that I need a cluster. You don’t get to decide what is someone else’s X. Are there people who could use something other than hadoop? Sure. Maybe like some “look at me” blog posts and articles like the point of “that problem could be solved in excel”, maybe it could, maybe a single Python script could handle it. But if that one script dies? What then? No answer. Maybe that person went with Hadoop after looking at the problem and deciding that a job tracker as a SPOF was way more likely to fail them than just a single python script.
How about, we stop assuming our colleagues are idiots and try to understand why people make the tradeoffs that they do. Yes, Hadoop is a beast in many ways. Yeah, operationally, it can be a giant pain. But, there are plenty of reasons people want/need to use it that cynic’s sniping from the sidelines simply won’t see.
I have met cases where people want to go with Hadoop based on hype (or to gain career experience), when they have a dataset < 10GB. These people are not “idiots” per se, but don’t always consider that traditional single node technologies are most suitable many (if not most) projects. Articles like this can help keep perspectives in the right place, where sometimes “boring old-fashioned RDBMS” are a valid approach.
Curious what type of operations you perform that take that much time for < 5GB / hour of logging?
I had a hard time listening to a lot of the sessions at strata in Santa Clara this year. The enterprise vendors definitely smell money in the hadoop ecosystem and this had created a feedback loop which had resulted in a lot of “you need a hadoop” type cargo cult behavior.
I use a small hortonworks cluster to process about 200 Gb/day of video viewing and ad data from log files. We had a home brewed distributed log processing system that was less functional than what we got for free (development wise) by using hadoop. Using hadoop as a big dump parallel hammer to apply functions to large data sets without having to write custom code is the sweet spot for my needs.
Did you mean “less likely”?
I did.
Sadly can’t edit now. :/
I disagree with this as a blanket statement. I think it all depends on the individual employee and the company.
I’ve never carried a balance of vacation time from year to year because I’d rather take the vacation & travel. I’m also willing to butt heads with my manager to ensure that I’m getting the vacation I’m entitled to – but to his credit, he hasn’t made me do that at, because he embraces the concept and works to ensure his employees are taking vacation.
For me, I’d much rather have the ability to take more vacation than to cash out my zero hours when I quit! I actually keep a spreadsheet of paid vacation I’ve taken since my company moved from a time granted to an unlimited time policy and I’m ~2.25 months ahead thanks to the switch.
That being said, I have friends that refuse to take vacation out of some odd misguided loyalty (“things will fall apart without me…”), fear that their manager will frown on them if they’re not in their chair all day every day, etc. If that’s the environment and that’s how you operate, I’d definitely agree that it’s a net loss. But it all depends on the person, in the end.
Completely agree, which is why at GrantTree I decided to have explicitly 30 days of vacation, not “unlimited vacation days”. Hadn’t thought about the compensation angle, but that one is another good point against unlimited vacation.
I think that unlimited vacation policies can be great if the company culture is accepting of vacation. Then unlimited vacation is almost always preferable to defined vacation benefits. But it’s the rare tech company that understands the value of vacation, and so unlimited vacation policies do usually end up the way you describe. At Sourcegraph, we’re trying to create the right kind of culture.
Because he’s making up new meanings for words that already exist and trying to convince people that his definitions are better than the ones that people have been using for hundreds of years.
While that’s true, maybe the more relevant aspect is that for the first half-century or more of computer programming, there wasn’t a clear distinction. I do think that these new definitions have caught on, though, so we should use them.
Applying the literal definition of concurrency (things actually happening at the same time) to computer programs is something that’s only made sense recently, because it used to be literally impossible for a CPU to do more than one thing at a time. That doesn’t mean the literal definition of concurrency is some new, questionable, or unclear thing.
Well, in the early 50s there was already competition between “parallel” and “serial” computers, but the difference was that we were talking about how the bits in a machine word were treated when you were e.g. adding two words together. Parallel computers were much faster but also more expensive. Multicore shared-memory computers date from at least the 1960s: the CDC 6600 (1965) had a “peripheral processing unit” that time-sliced among 10 threads, context-switching every cycle, each with its own separate memory, in addition to having access to the central processing unit’s memory. And of course in some sense any computer with a DMA peripheral (which date from the 1960s if not the late 1950s) is in some sense doing more than one thing at a time. Symmetric multiprocessing dates from, I think, the late 1960s. Meanwhile, what we now know as “concurrency” was already in play—even before the CDC 6600’s PPUs, “time sharing” (what we now know as having multiple processes) was an active research topic.
So parallelism and concurrency have been around in more or less their current form for half a century. Nevertheless, I think the distinction Pike is drawing between the two terms' meanings is much more recent, like the last decade or two; but it does seem to have become accepted.
A current example with a little discussion of this usage, C. Scott Ananian talking about Rust:
Concurrency has been around long before multiple cores were. User input, file input, displaying output, punching cards, etc.
It’s not a recent concept.
You might want to remove your downvote; review my longer comment above.
I stand corrected.
You, sir, are a gentleman.
I don’t know that it’s due to confusion. There are a lot of self-taught people who might be running into this the first time. There will always be the next generation of programmers coming up who just haven’t learned this yet. We’ve all got to start somewhere and learn this at some point, and not everyone’s been programming since they were 15. I do like seeing it crop up, it’s a good video to learn from.
I actually had to keep rereading about parallelism vs concurrency. I got it when I read it, but after some time I found myself trying to explain it and failing to, and my thing is if I can’t explain it easily then I don’t understand it well enough, so I go back and read it again. When I want to implement concurrency, I still of course have to look up good ways to do that.
I don’t think there’s really much confusion. It just helps a lot to define terminology at some point, and go on from there. And that’s what I think Rob Pike does very well in this presentation, to show the abstract programming model of concurrency, and how an implementation (in this case, Go) can achieve parallelism by leveraging fundamental properties of the abstract model.