One point of anecdotal data: I tried vim for a while and two weeks in I was still getting hung up on switching between modes to do things.
This is my issue with vim but remapping escape to caps lock helped.
Did your Vim tell you which mode you’re in?
I don’t know what kinds of defaults are common nowadays, but I’ve learned to rely on visual cues. It’s not impossible to always hit escape first, just in case, but it ain’t exactly nice either.
me skims article
“Wait a second, isn’t the author of this article also the author of Hanami?”
“He sure is!”
Maybe the title should be: “How I convinced my employer to use the framework I wrote”
I’ve looked at Hanami and I like what I see, but I’m going to take this article with a grain of salt because there’s obvious bias.
Actually, I’ve been hired after the decision was taken. The bias are obvious, but still the team had problems with that old API, even before I joined the team.
I think that “indexes” should start at 1 and “offsets” should start at 0. That is, I think a simple name change could fix the whole argument.
[EDIT: This comment is largely wrong. Collections are 1-based, Streams are 0-based. It’d been so long that I’d forgotten. The point in general stands, but the code as-presented below will not work as expected; even when doing a range copy on a SequenceableCollection, it works 1-based with inclusive upper bounds. Doing a PositionableStream on the underlying collection will work as presented here. Sorry about that.]
That’s exactly what Smalltalk does.
c := #(a b c d e f). "Declare a five-element array."
c at: 1. "a"
c at: 5. "f"
c at: 6. "throws an error"
c copyFrom: 0 to: 1. "#(a) EDIT: Nope, wrong!"
c copyFrom: 0 to: 5. "#(a b c d e f) EDIT: nope, wrong!"
This made instant and intuitive sense to me when I learned it as a kid in a way that 0-based indexing definitely did not, so I’m definitely on board with it. But I’d also note that in Smalltalk, as in many other modern languages, I barely ever even type the array index in the first place; doing things like first, last, allButFirst: 2, etc. are much more common. So I can’t honestly say it made a huge difference either way. (When I picked up Smalltalk’s successor, Self, I programmed in it for several days before I realized that its indices did in fact start with 0. And I only realized that because I thought I found a bug in the debugger.)
If you see everything as an offset from the beginning of an array, you can stop using the word index, and the confusion should stop.
If you see everything as an offset from the beginning of an array, you’re thinking in terms of pointers and RAM blocks instead of thinking in terms of arrays. That abstraction slip will cause you problems.
related link: https://medium.com/@hoffa/400-000-github-repositories-1-billion-files-14-terabytes-of-code-spaces-or-tabs-7cfe0b5dd7fd
(I love how Go is 100% tabs)
I’m always surprised when I see Clean Code being recommended. It was originally recommended to me a few years ago, so I bought it and Code Complete at the same time. Without a doubt I feel like Code Complete is the stronger book - and some of the practices that Clean Code suggests only really applies to Java, and only in some cases. It’s worth reading, but I would not recommend it. Whereas Code Complete is a very good read, and the concepts and rules it teaches can apply to multiple places.
That being said, it’s been a few years since I’ve read either of them. Maybe I should do so next time I’m home.
I hadn’t heard of Code Complete. I appreciate the recommendation
Code Complete is great. One of my base recommendations to new programmers.
Not my site, and the links are all amazon affiliate links, but I found the list interesting.
I keep thinking of switching to React but then I hold back because I keep seeing posts like this.
These were the biggest takeaways from this post for me:
However, the difference between my code and React is that I don’t have HTML in my JS files, I leave that in the views. I mean, I really wonder, how do frontend devs cope with React files? If I were a frontend dev and I needed to update the HTML, I sure wouldn’t want to wade through the tree of JS files just to figure out which file to edit.
And is React really that strict? If it forces you to have tiny component files where every dynamic element needs to have its own component class, then I can totally understand how that would be a pain. I have found that sometimes this doesn’t need to be the case – sometimes it makes more sense for a component class to refer and add behavior to other elements inside of it without those elements being explicit components. This kind of code may get refactored out later, but having that option is nice.
I can confirm that two-way data flow code sometimes is not as clean to read, but most of these fears are mixed with overall pain about Angular 1 where two-way binding was bad, and still.. probably it was not the biggest fail even there.
That’s an interesting argument, and I’ve actually never heard anyone make it before, but I think it dovetails with some of the feelings I’ve had about React in the past. Honestly, the first time I read about Flux (or any of its interpretations, such as Redux), it seemed like it was a solution in search of a problem. When I used Angular 1, I definitely encountered problems with two-way binding, so I understand at least on the surface why a one-way flow is in theory better. However, now that I think about it, my problems were with Angular, not with the idea of two-way binding: I was trying to do something fancy with watches, and it backfired on me. So I can’t help but think, if two-way binding had been simplified so that I couldn’t have shot myself in the foot, wouldn’t that have been better than overhauling the ENTIRE app flow?
Vue.js may be very nice, but this article is uninformed FUD about React.js and JSX.
If it forces you to have tiny component files where every dynamic element needs to have its own component class, then I can totally understand how that would be a pain.
It does not force you to do this. At all. I’ve worked on a few large React.js projects with a bunch of developers of varying skills and everybody finds their own balance for component size, but my advice is as follows: Break components up in to large natural pieces, use local variables to build up little state-free fragments in one large render method. Over time, refactor those things in to methods or components as needed for parameterization, reuse, or performance.
if two-way binding had been simplified so that I couldn’t have shot myself in the foot
Two-way binding is a generally bad idea. I’ve written about the fundamental problem here: http://www.brandonbloom.name/blog/2015/04/26/rarely-reversible/
Cool, I appreciate the clarifications.
I don’t know if the post you mentioned helped me to understand why two-way bindings are necessarily a bad idea. Can you expound on this? Specifically, 1) what is “reversibility” mean in this context and 2) what do two-way bindings have to do with it?
My frustration with two-way bindings is that it leads to everything poking everything.
How easy is it to track a bug to its source? With a clear hierarchy and direction I find it to be pretty straightforward. When it is two-way I find it to be much more complex.
I used “reversibility” to avoid having to talk about the finer points of functional inverses. I’m saying that if you have f(data) -> view, there’s no way to get g(view) -> data without a very complex set of rules or a overly simplistic one-to-one mapping of data == view. The former is an open research problem and is unlikely to produce a simple solution. The latter just shuffles the problem to somewhere else: “Hey, I have data-binding of this data and this view… but how how do I get that data to data bind?” - You always need a function without a good inverse somewhere.
Cogsci, not programming. Thanks!
thanks, I was trying to figure out what to tag it with
I thought this was particularly interesting: “Garden path sentences are used in psycholinguistics to illustrate the fact that when human beings read, they process language one word at a time.”