Hacker News new | ask | show | jobs
by warcher 3772 days ago
Truthfully, the language barriers are nothing next to the API barriers dealing with your platform of choice. I am probably giving away my age here, but there's very little that's new under the sun after you've tussled with... say one each of the big three language families. These being: Nasty old C (not going anywhere, ever. Deal with it.), modern scripting languages (Ruby, Python, et al) and the real deal functional languages (lisp, ml, haskell, etc). It just turns into "Oh, this is how they handle an array. Do I have any functional plumbing? Ok, great. How do I dispatch a thread? Ok, let's go." It's just not that interesting after a while.

Objective-c is quirkier than most, swift is nice but still baking, but it really all boils down to the platform APIs. And you're gonna have to get wet at a platform level if you want to provide functionality beyond a mobile web page. (Albeit one with improved load times since it's coming from disk, at the cost of dynamic updates since it's coming from the app store.)

11 comments

Yep this is what I'm realizing after a few years of programming. I can pick up a language easily, however learning it's APIs is almost as hard as learning the syntax for the language itself.

Like how do I open a file? Ok cool. How do I close it? Do I need to explicitly close it? Ok.

Also, learning APIs for other peoples codebases/software is task of learning that isn't trivial too

This is why language oriented programming is a better alternative to everything else.
I agree. Keeping up with the giant, buggy, constantly changing, platform API, as well as the whole ecosystem, from build tools to the app distribution and analytics, is by far the hardest part.

These abstractions on top of the platform might make it easier for quick prototypes if you don't have time to learn the language. But you'll lose some flexibility, power, visibility and community. After a while the initial speed benefits wear off since the language is a small part of the things you have to stay on top of, especially if the app takes off.

Those are the extremes, so once you know those you can handle most things. Some modern languages seem to have a foot in each camp, like Rust for example.

We should graph every programming language on a radar chart using those axes.

Syntax is easy, semantics are hard, cultural norms take time.
Yeah, I find the learning experience of any language to be like that, once you have a few under your belt.

Except Haskell. I can do the trivial stuff, but anything non-trivial is a chore to learn. It is not as if it has a learning curve, it has a learning brick wall that hits you very early on.

That is one way to write the code, but if you do it that way you will never get the benefits of each language. Haskell and Lisp are both functional, but they way they are intended to be used are very different (example: if you don't use macros with lisp you are probably missing something. If you don't take advantage of lazy evaluation in Haskell you are also missing something).
Uhhh, I never suggested writing lisp in a C style, or ruby in a functional style (well, more so than it encourages at least). That would be crazy. My point is that there aren't that many ideas under the sun. Lazy evaluation, super. Monads, ok. Real-deal, no playing memory allocation and management? Where's that union stashing variables again? Are you sure? Uhhh, fine I guess. (Although I'd rather take the monads.)
Lazy evaluation is no longer exclusive to Haskell and other functional languages.

C# has had Linq for lazy evaluation of data collections for many years.

Javascript supports observables now and ot's only a matter of time before they're included in the official spec.

Reactive Extensions has been extended to many different languages now.

Lisp macros are essentially higher order function definitions. They can be trivially applied using decorators in Python and closures in Javascript (JS decorators will be supported in ES7).

> Lisp macros are essentially higher order function definitions.

Definitely not. Lisp already has higher order functions. Macros are something entirely different.

> They can be trivially applied using decorators in Python and closures in Javascript (JS decorators will be supported in ES7).

Of course not. Decorators and closures are in no way related to Lisp macros.

There is enough literature about Lisp macros... For example a certain Paul Graham wrote a book explaining them in detail:

http://www.paulgraham.com/onlisp.html

> Lazy evaluation is no longer exclusive to Haskell and other functional languages.

> C# has had Linq for lazy evaluation of data collections for many years.

> Javascript supports observables now and ot's only a matter of time before they're included in the official spec.

> Reactive Extensions has been extended to many different languages now.

These things are quite different from having pervasive laziness, though.

React-Native isn't just a JS-wrapper, you're trading away language safety features (e.g Swift) with features to help with transient state (React).

Of course you can mitigate that with RxSwift, but it only goes so far.

Concurrency is a real bear on mobile, and it isn't something that can be ignored (a la the web) when you're that close to the metal. I'm an explicit js chauvinist, so maybe they've gotten something together on that front, I wouldn't know, but that's a very serious concern of mine with js-outside-its-proper-place-within-the-DOM.
i agree with you, although i think you are forgetting to add (and maybe it is implied here and i missed it) that learning mobile development requires you to not only learn new language APIs in objC/swift, but you also have to learn some new design patterns (delegation, etc.) and most importantly the SDKs (CocoaTouch)

if you can use react native and avoid learning a lot of this it is a big win - I havnt used it yet, and I have a hard time believing it a mobile only company would use it to build their mobile app, but i am excited where it is going.

>learning mobile development requires you to not only learn new language APIs in objC/swift, but you also have to learn some new design patterns (delegation, etc.)

Delegation has been a standard feature of desktop APIs for decades. Not just on things like Smalltalk and ObjC -- it has been the standard .NET model for UI events since C# 1.0.

sure but the majority of developers writing code write webapps. Some there are some desktop apps out there but not a lot.
Going to need a source on that 'majority' of which you speak of as if its a fact. Sure, web development is popular, but there are a _lot_ of developers working on other things (which potentially include delegation). Also, I'm sure you'll many web frameworks that use the delegation pattern.
I'd say the majority of developers write enterprise code, whether web or not.
So here's the real bear of it, and the crux of my argument.

The delegate thing is an iOS thing. Android uses a totally different pattern. I mean, there are delegates, to be sure, but android loves their anonymous inner classes in many of those cases. (Which is closer to idiomatic js IMHO.)

So on a language level sure, easy peasy, you could delegate in javascript all day long (and you do). But on a platform level, nuh-uh. One is going left and the other is going right. How do you meet in the middle? What fine line gets scrubbed in between?

React-Native pattern with delegates is passing down functionHandlers to childComponents that would trigger them.

Except Objective-C (and Swift) had protocol conformance. Though come to think of it TypeScript allows you define an interface for a Component, one of those attributes could be a function.

Not really getting away from it. ;-)

Isn't delegation just a slight variation on callbacks?
Basically yeah. An object can have one delegate object, which implements a set of required and optional methods defined in a protocol. So the delegate can add customized behavior to an object without subclassing.
I found this true in my case too. The API/Framework was the thing I had to learn.

As far as React Native, I can't see it being used seriously. I think teams are going to have to know native iOS and/or Android programming anyway.

But seeing the mass of apps that never live beyond a year, maybe React Native is just the thing.

No one is doubting that you'll need people who know iOS and Android ecosystem. But React isn't just a wrapper over native views. It's a fundamentally different way to write up applications compared to the way you work your way around states and UI.
While I agree with you, I also think that it's easier to overcome one of those hurdles first, rather than to overcome both at once.
I guess I see it as a form of technical debt-- you move faster, but past a certain level of performance it's all gotta go native. There are a lot of places it would be a decisive win. There are a lot of mobile websites that are great. But there's a ceiling, and once you hit it, all that javascript is gonna get rewritten.
Where does C# fall among these 3 families?
The C category.

A 4th category is probably needed for statically compiled, garbage collected, OOP languages.

The reality is, most/all of the most popular languages blur the lines.

Javascript is getting official support for OOP as well as better support for functional programming.

C# has good support for dynamic typing as well as many functional characteristics.

High performance Python has always had the ability to delegate to C extensions.

Etc

Agree 110% on the blurring, and maybe a 5th category too - 4GL, for SQL and its ilk.

Obj-C, Obj-C++, C++, and C can all co-exist in the same codebase and be complied into 1 output (if you are insane enough to try), similar to CUDA or Fortran with C/C++. That's not really possible with JVM or CLR languages, but not impossible either. Which makes them more like 3GL/OOP while sharing more similarities with smalltalk than 2GL/C.

Py, Lua, GLSL/HLSL, and many others can "mix" or be called by C/C++ similar to CUDA, and Lua is definitely in the interpreted "script stuff" bucket, not statically compiled like Java, C#.

The shader languages like GLSL/HLSL are really confusing to categorize, especially when used with C#, because they can exhibit characteristics of 1GL thru 4GL.

Can't forget the declarative regular and context-free languages.

XLST and other template syntaxes are another interesting case. They look mysteriously like a declarative context-free language but have imperative characteristics of a turing complete syntax.

JVM may not be able to be combined with compiled languages but there are a number of languages that, at a bytecode level are compatible with Java. For example IronPython, Rhino, etc. The same can be said for the .NET environment and languages like VB.NET, managed C++, C#, F#, etc.

Don't even get me started on languages that can output output Javascript. Last I heard, there's over 100 of them now and the list keeps growing.

I'm not sure about GLSL/HLSL because I haven't used them but they sound like they're declarative DSLs (Domain Specific Languages).

Maybe it's about time somebody created an update to the Chomsky hierarchy. Instead of the traditional subset-superset classifications, some other system is used to compose the characteristics of languages.

In the bigger picture of things, it's all very incestuous. Like every language is trying to be like every other language. The winners of the pack are those that everything else compiles/transpiles down to.

I've been out of the ecosystem for a while but isn't it closer to type inference than dynamic typing?
C# has both. "var" for type inference, "dynamic" for dynamic typing.
I feel like C# (and C++, and Java) would all be basically in the C camp. C# and Java could be arguably somewhere on a spectrum between C and the scripty stuff.