Building OS X Apps with JavaScript
tylergaw.com
tylergaw.com
I'm honestly not being sarcastic, but I think there's something interesting about reading an enjoyable programming article by someone who doesn't know what bitwise OR is. It sorta feels like a huge reminder we've moved on to a whole new generation/level of abstraction where competent developers no longer need to understand binary.
I gave a talk the other day about the future of code (think 2024 and on) and one of the biggest things out of my research was that we'll eventually not need to think about intermediate data structures in code anymore as AI profilers, VMs, compilers, etc. will be able to optimize and profile almost everything away with developers working more with specifications and constraints. I wonder if in 10 years' time a programmer not knowing what a linked list or a binary tree is will not be considered unusual either.
Experts master their dependancies. All software depends on binary representation. All expert programmers need to understand binary.
Of course, you said "competent" and yes, you can get things done without knowing binary. Although it pains me to think that it can't be understood or explained simply! Bitwise or is so foundational to many techniques, like efficient storing flags, security, and so much more.
BTW a 'bitwise or operator' loops through the digits of a binary representation of both operands, or's the binary digits, and outputs the result. That one little operator has elements of a transform, a for-each (or a map(), if you like), and a logical operator, all in one! It's powerful and cheap to compute, and programmers and others, would do well to learn what it does. One practical, everyday use: numeric arguments to chmod (e.g. chmod 712 myfile.txt)! The reason why the modes are assigned to powers of two then added is so that they can be recovered from a bitfield using...bitwise or.
When I got to that part of the article I stared researching bitwise operators to try and give a short explanation. I couldn't sum it up well in the voice I wanted to. So I decided to just say, "I don't know, and that's OK." I try to write in a way that's accessible to people that are maybe newer at programming. Maybe without a CS background, like me. With this, I felt like there would likely be so many new concepts, that it would help to leave one out that wasn't essential to building the example.
For my next post I should research and write about bitwise operators.
I also do not know what a linked list or binary tree is, but I'll certainly take the time to learn about them in the future.
Thanks for reading it and commenting.
Personally, I am a recent grad (last May), but have focused on web dev in my free time. However, having gone through formal CS I do know a good bit about the low level data structures and bitwise operations. Some of the interviewees have been developing for over a decade and can't say what a linked list is, let alone contrast it with vector or an array.
It is all, anecdotal, but we've seen a fair amount of correlation between ability to solve simple problems (writing simple functions with no expectation of optimization) and knowledge of these entry level CS topics. So as much as I feel like we are testing for the wrong things when we ask about simple bitwise operations or linked lists when interviewing for front-end JS guys, it has still been a good test for us.
All of that being said, this post is definitely well written and interesting. It is odd to me that an author who seems interested in learning and trying something new would so actively choose not to know what the code he's writing (and telling the reader to write) is doing.
1) I couldn't figure out a way to write an explanation of the bitwise OR operator that was terse enough to not derail the main topic of the article while still making sense. The post isn't a tutorial about bitwise operators, it's about building JS OSX apps. It's a long post, with a lot of concepts. I didn't want to add two or three more paragraphs to explain something that was non-essential to the task at hand.
2) I wanted to show vulnerability in myself. I could have left out the two sentences in question, they were also non-essential to the main topic. But, I knew this post was going to garner attention. I wanted to show–by example–that it’s OK to not know things and to say, "I don't know."
I didn't foresee this much discussion about it, but I think it's good. Look at all the great information about bitwise operators in this thread. There's also a good explanation in the comments on the post. Those comments would not have been made if I chose to leave those two sentences out.
Thanks for reading the post and commenting.
Your comment about not knowing bitwise OR was fine.
I looked at your blog and could easily see that your background is designer (HTML+CSS) and then programmer (Javascript, Ruby, etc). If anyone reasonable keeps this in mind, they would actually be surprised if you did know what bitwise OR was because a developer who built knowledge in that sequence wouldn't need to come across it.
There are large swaths of programming communities that don't come across the bitwise OR topic. This includes ERP (Enterprise Resource Planning) programmers such as SAP, PeopleSoft. Linux/Windows admins writing bash or Powershell scripts. The office power user writing Visual Basic macros for Excel spreadsheets. And of course, many web developers. All these folks are productive doing "programming" and yet they get by without bitwise OR.
When a programmer is surprised at why developers of <insert_whatever_technology> doesn't know <insert_whatever_knowledge_he_happens_to_know>, it's often because he forgets that others interface with programming tasks quite differently from him.
A typical type of programmer that would know bitwise OR is a C/C++/assembly programmer. But even within this group, there would be knowledge that one C programmer would be "surprised" that another C programmer doesn't know. For example, a C programmer might not know the intricacies of the Link process. Well if that C programmer was a university student that only used the C language to write 500 line programs to calculate matrices for his science experiments, he may not know the subtleties of the Compile & Link. To him, it's all just a black box to spit out an executable file. When he needs to know what "can't resolve symbol" error means, he'll learn what the LINK in COMPILE+LINK actually does.
I agree that a real explanation would have been out of scope and probably even more odd. My only suggestion (not that it is really better or you want it :) ) is to to pay it lip service with something like, "The syntax is odd, but it is just specifying options with a bitwise OR" With the "bitwise OR" as a link to documentation for the cocoa options or some article explaining bitwise operations.
Most importantly, it was a good article and I'm going to do a little bit of research for myself on writing these simple OSX apps with JS. First thing is to figure out just what is required for these applications and try to decouple it away from that script editor.
And I really appreciated that. I think far too many people (including myself, at times) give the impression they know more than they do and I see how intimidating it can be for beginners to think everyone fully groks X, Y and Z and is way ahead of them when the real picture might be quite different.
There was a lot more of this sort of honesty back in the earlier days of programming blogs, but then all the "you've blogged something totally obvious!!" assholes turned up. I hope we can get back to people just writing and sharing what they want without people assuming admitting ignorance or not being a 100% expert in a field makes one unsuitable to write about that field.
Jaw dropping. Some degree of this is acceptable - e.g. I wouldn't really expect a front-end dev to know browser-native DOM manipulation, because everyone uses some sort of shim (particularly jQuery), and modern-modern frameworks abstract away DOM manipulation entirely (think React). But that's a high-level API trade-off, rather than a foundational issue. OTOH it's far more serious when a dev doesn't know about Array.forEach and insists on using $.each for iteration, showing an inability to distinguish between native JS and jQuery.
Part of the problem with JS and data structures in particular is that, AFAIK, there is not even a de facto collections standard. Google's Closure structs[1] might come the closest, but generally brings a lot of baggage. js_cols[2] is pretty good. And then you have what I would consider "fringe" solutions like mori[3]. The bottom line is that even an autodidactic developer starting off in JavaScript land is going to have a much harder time learning about basic data structures than if they started off in Java land, which, while it has it's warts, does have a wonderful standard library for collections[4].
[1] http://docs.closure-library.googlecode.com/git/namespace_goo...
[2] https://code.google.com/p/jscols/
[3] https://github.com/swannodette/mori
[4] http://docs.oracle.com/javase/tutorial/collections/index.htm...
http://www.cprogramming.com/tutorial/bitwise_operators.html (A decent intro to the concept of bitwise operators and what you might use them for.)
https://developer.mozilla.org/en/docs/Web/JavaScript/Referen... (Their use in JS.)
And Peter: I'd love to watch that talk! Was it recorded? A quick search for "peter cooper future of code" brought up some references, but no videos (at least not yet).
Yes, I am a real developer but the technologies I use don't have those paradigms. I doubt it this is good or bad, just different.
{ data: stuff,
next: more_stuff }
`next` is a reference to the next object like this one in the list, and `data` is a reference to the actual object at this point in the list.You've now got a close-enough idea about what a linked-list is.
You can also have dual-linked lists, where each object also has a `previous` pointer to the previous object in the list.
If you want, you could store the data directly in this object, rather than having a pointer out to the actual data (of course).
This kind of thing can be very useful for certain kinds of data manipulation, where the built-in lists aren't efficient enough - for whatever reason. Say the language you're using creates an entirely new list whenever you try to remove an element from the middle of a list - or when you need to be moving / removing elements all over the place.
The big downside of such a linked list is that you can't easily jump to a specific item number in the list. So jumping to item 200 means walking through the first 199 elements in the list to find it.
I've only had to implement a linked list once in a JS project, I don't remember the reason why. I think the algorithm just worked a lot more efficiently that way.
One reason a linked list could be useful in a javascript (or PHP, or whatever) language would be, for instance, if you had a game where when a player hit a block with a hammer, that block would bounce up and down, as would the two blocks on either side. If you store all the blocks in a regular list, then you need to know the index of the block in order to find the blocks on either side. In a linked list, you don't.
One of the original big advantages of linked lists is that you can have objects of variable size, and the list can grow and shrink without adjusting any of the previous elements. Opposed to this is an `array` (sometimes called a vector) which is a fixed size chunk of memory which is split up into identical sized parts. You can then jump to element 200 by looking at the starting position + 200 * the size of a single element.
This works pretty well, but if you want to add another 20 elements into the middle of the array, you need to allocate a new chunk of memory and move the whole lot into it, and deallocate the previous entire array. This is one of the reasons why strings are usually immutable in many languages. Strings are stored as arrays, not linked lists of letters.
I think it's worth learning about all this "Computer Science" stuff, even if you don't need it very often, as it means when you come across a new problem you have a much bigger mental toolkit from which to figure it out.
Here's a model of a linked list. We start with an empty list represented by an empty array.
[]
In normal arrays we'd add a number by putting it into the array, like [1], but we'll do something a little weirder: [1, []]
we build a new array which contains one value and the empty array. We add new elements in the same way []
[1, []]
[2, [1, []]]
[3, [2, [1, []]]]
The final one there is a bit like the array [3,2,1], but seems to have a lot more ceremony. In any case, the values above model linked lists.Why would you use such a thing?
Well, when you want to push a new value on to an array you may find (internally) that the array you have so far is too small. To fix this, you build a new, larger array and move all of the old elements to the new array plus the one new thing you've added. This can be expensive.
With linked lists, adding a new element is always the exact same process. It is in this way faster and simpler.
Of course, the downside of linked lists is that there is more overhead to, say, read the 10th element. In an array you can just do a[10], but in an linked list you must do a[0][0][0][0][0][0][0][0][0][1]. Obviously this involves much greater overhead.
Linked lists are closely related to infinite streams, however. Sometimes they better model what you actually want to talk about—the idea of having a value "now" and some more values "in the future". They also are much more naturally implemented immutably and have a much more natural sense of a fold or reduction.
So, as with all data structures, there's a tradeoff.
Your language most certainly has a syntax for bitwise operators. If you want to optimize (speed up) your code, knowledge like that would help you.
Node/Javascript: https://developer.mozilla.org/en/docs/Web/JavaScript/Referen...
PHP: http://php.net/manual/en/language.operators.bitwise.php
Python: https://wiki.python.org/moin/BitwiseOperators
Ruby: http://calleerlandsson.com/2014/02/06/rubys-bitwise-operator...
Visual Basic: http://msdn.microsoft.com/en-us/library/wz3k228a.aspx
A linked list is a kind of (abstract) data structure (http://en.wikipedia.org/wiki/Linked_list). If you come in touch with a static typed language (C, C++, C#, Java) such knowledge is essential. In languages like JavaScript and PHP you usually just use an object or an array. You can think of an linked list as an array of objects.
By the way, from what I've read bitwise operators aren't very efficient in JavaScript because of the overhead of conversion from generic duck-typing to binary.
JSONs have keys that are strings so a hashmap or hashtable is probably more likely.
Okay, now that I've got that out of my system, I'll try to contribute something positive. Linked lists are useful to understand because they're very similar to, but less complex than, a common representation of trees and graphs. In a tree or graph, each node can have several children instead of just one.
There are also some special algorithms that make use of the ability to grow or shrink a linked list in the middle without copying the whole tail [1]. The thing that makes this more rarely useful than you might think is that random access to the middle is O(n), so you have to be moving around in order adding/deleting things.
[1] Dancing Links: http://en.m.wikipedia.org/wiki/Dancing_Links
Note, this is actually a circular, doubly linked list.
To me it's not a paradigm. It's how data is stored and represented in memory. Where such issues become problems in larger projects is when you have a lead that doesn't know what B-trees are and they need to optimize database access. Or that person is loud and influential and derails every technical conversation because it's way over their head.
Ironically, the three languages you listed - Java, C#, and Objective-C are all available on all major platforms. I could write code in any of those languages and have it run on
- Windows
- MacOS
- Linux
- Android
- iOS
Furthermore, the apps would all be native. That closest Javascript can come is to use the uncanny-valley of HTML5 without native widgets or performance.Frankly, Given that the burden of learning a new language is tiny, I see no reason why we should try and cram Javascript into every nook and cranny. It's a fairly mediocre language at best.
tl;dr The three languages you listed are all capable of better cross platform support than Javascript.
At my job we spend thousands of hours building our native App for Android and IOS for work and it's painful - when I can open the browser and nearly all the capabilities are in browser and the browser already cleanly abstracts the process of editing UI via HTML/CSS. I've yet to find another UI framework as powerful or quick to develop in as HTML/CSS - and the performance is looking really good in the browser. Native app performance is a myth unless maybe you're writing a video game?
Really? Until a couple of months ago with the advent of flexbox, you couldn't reliably do columns that fit dynamically to the browser window (frameworks like Bootstrap simply define three different window sizes and switch between them, rather than allowing for fluid resizing) as well as you can in every other UI framework I've used, never mind vertical layout. (See all the hacks for "sticky footers" over the past decade.)
"Powerful" - I'm not so sure. Generally I find native toolkits, while requiring a bit more effort up front, generally yield much nicer user experiences.
My company has been working on a cross mobile application in HTML5 using Cordova. It was quick to prototype, but as we scaled up we started hitting the limitations of the platform very quickly.
The main issue is that every single mobile device has a slightly different rendering engine. Even two different Android phones from the same manufacturer will behave slightly differently. If you're making a simple CRUD app, this probably won't affect you - but once you reach a moderate level of complexity you spend more time playing whackamole fixing bugs and testing on every possible combination of devices.
We're currently rewriting as pure native across all platforms, since it works out to be less effort in the long run.
This is on top of the obvious limitations of HTML5 - Performance is never quite there for anything other than trivial tech demos, and the lack of native widgets mean your users will have that "uncanny valley" experience where it doesn't quite feel right.
tl;dr HTML5 is ok for prototyping and simple apps, but doesn't scale well. Ditto for Javascript.
Many Gnome (Linux) apps original language is JavaScript (GJS). iOS 7 came with a JS API. It is such a powerful language for async and UI design that it adapts well to all these platforms.
Whether you'd want to do this or not is another story. C# and Xamarin would be a far better choice for a one-size-fits-all cross platform codebase.
Not only that, certain APIs are only available if you use them.
You can write Go code and compile it to JavaScript. You could create bindings for Cocoa APIs in Go.
I don't see why they wouldn't, but I couldn't find a confirmation either way.
It's that it's also essentially natively supported. Having futzed with PyQt and PyObjC to build a medium-sized desktop application, I never want to go back to dealing with bridges to low-level libraries again. But this looks much more manageable.
Reading this code makes me think I just might write an OSX app again some day. And if CoffeeScript can compile down to it - no idea why it couldn't - even better.
Objective-C is a small language only if you already know C. Otherwise you will have to learn C first.
Or to quote Bill Joy, "C is really just peek and poke with some syntactic sugar".
If you have an Apple Developer account, you can download the sample project here https://developer.apple.com/wwdc/resources/sample-code It's listed under "JavaScript for Automation Cocoa Application"
As much as I like using JS for scripting purposes in the OS, I feel like with this, I have the same problem: namely that the cocoa APIs are massive and I have trouble understanding what's going on, even after trying to learn them three or four times in the past decade.