Let me add that warnings are often used to detected edge conditions in the program environment (input etc.) while strictures control the program syntax and data flow, so enabling warnings by default everywhere might cause unwanted problems, even if it's generally a good coding practice. (This is also why using fatal warnings in production is an absolute no-go.)
]]>The rest of the article is just defamatory and slanderous bullshit. Haico debunked some of those already, notably the lies about the supposedly high turnover rate or the invention of the "continuous hiring" concept. I'll add that the point d about the kind of projects going to new devs is blatantly false, as any employee can see, and that the commission percentages that are quoted are also overestimated by a large factor, which *could* make me suspect that someone got paid to write this post to purposely hurt booking.com by spreading false information.
incr
:
If that incr(0) were allowed either some temporary that nobody ever saw would be incremented or - far worse - the value of 0 would become 1. The latter sounds silly, but there was actually a bug like that in early Fortran compilers that set aside a memory location to hold the value 0.
That actually made me think about that nifty one-liner:
perl -wE 'Internals::SvREADONLY(${\undef},0);undef=42;say undef'
]]>
More generally there are quite a few very, very good Perl devs (and high-profile P5P or CPAN contributors) working for Booking. I doubt they would stay if they were paid only to churn out bad code and "not designing stuff".
]]>For your specific purpose, I'd choose a normal form (NFC probably, so stuff like the Dutch ij is not converted to i+j) and convert every Unicode input to that.
]]>The spec has even a chapter on factories (static constructors). (Oh my, factories? it's like 1997 and design patterns all over again!) I should note that the integration of popular design patterns at the syntax level is disappointing: design patterns tend to emerge to work around a language design's weaknesses. Embracing them is a bit like admitting a design failure up front.
Let us just regret for the moment that more modern and useful OO paradigms, like roles, are not used here; as we have learned, interfaces are limited, since they do not allow sharing of code, only of method prototypes. But there are much more problems with Dart.
Ah; OK. In other words the "static checker" is a lint-type development aid, not a language feature. Worse, that means you can write functioning programs with wrong (and misleading) type declarations, and still run them. Types have no effect whatsoever on your program's semantics.
The lack of type enforcement also implies that the runtime cannot take advantage of the typing information to optimize a running program (for example by pre-resolving method calls). Via some type decoration mechanism, one could have mixed weak and strong typing; instead, it looks like the Dart designers found that type inference was too hard to implement, so they completely gave up on the advantages that typing could have brought to the runtime.
Finally, this weak typing design removes the point of using interfaces at all. Interfaces don't allow to share code; so what's the point in adding them (and having them parsed and compiled in a browser at page loading time) if they are nothing more than a fancy documentation format? Interfaces make sense only in strongly typed languages (like Java), or else you're just doing duck typing like basically every dynamic language, but without the advantages of dynamic languages (runtime addition of new methods, or calling of methods by name, for example).
The design of Dart's OO system is not consistent. I'm calling it feeble typing. It's an unassuming weak typing that can't afford to be strong but does not want to be seen with the weak typing boys.
I understand that Dart is designed to be compiled to fast Javascript. The absence of type checking, in that context, feels like a premature optimisation, and we all know what it is the root of.
I note that Dart also supports function types (describing the whole function prototype, like in C). Their purpose is not clear, since there is apparently no way to manipulate function pointers; the interface Function (apparently used for anonymous functions) does not provide any method at this point. What is the point of function types if they have no runtime existence? Moreover, the fact that named functions and anonymous ("literal") functions are different entities is disturbing.
There are generics, too. Well, I guess that the example of C++ and Java hasn't discouraged the Dart designers. Again I don't see the point of generics without type checking.
The spec hints that it's because the boolean literals true and false can be autoboxed into objects, and as objects, they would be non-null, thus defined, thus true, if any non-zero value could be true. Looks like a lot of trouble imposed on the programmer for a very minor problem that could have been fixed at the language level by allowing boolean coercion overload, or by disallowing boolean autoboxing. (It is notable that Dart allows operator overloading, but not boolean, string or numeric coercion overloading.)
Another word of warning; the operators === (reference equality), != and !== (inequalities) all return a boolean; but == is not required to do so, because it can be overloaded, and (once again) there is no runtime type enforcement on its return value. Which means that the expression (a==a) might be, in some pathological cases, false. In my opinion, this is not something that should be allowed to happen in a well-designed language.
The distinction between string and numbers allows to re-use the addition operator + both for addition and concatenation. However, without strong typing, this will almost certainly prove to be a bad idea. From the specs, it looks like "2" + 2 will be a concatenation, and 2 + "2" a run-time exception (in the absence of implicit conversion from string to number), but experience infirms this: string concatenation happens in both cases (although with a warning in the second one).
Another example: Ovid pointed me at the NoMoreElementsException, and added: "didn't Java programmers learn years ago that you throw exceptions for exceptional things and not for expected things?"
Thus, isolates are a heavyweight thread control model very much like Perl 5's ithreads. That means that they are good for data isolation, but heavy to use and hungry in memory, because spawning a new isolate will imply cloning all the objects and data structures of the running libraries. (By the way, there is no word in the spec on cloning. Apparently Dart does not have the equivalent of Perl's CLONE() method.) There are also "light" isolates, which means that they run in the same thread than the object that created them.
(Isolates are probably good for browser-side security, although the spec do not talk much about that point -- disappointing again, security should have been in mind of the designers from the start, for a JS replacement.)
However, running in a browser is not like running in a server thread, and where Perl 5's ithreads might do their job, isolates are not adapted to web-page programming. Controlling the UI of the browser, with its high level of interactivity, requires a good concurrency implementation for event processing, lazy loading of resources, and animations. Dart is weak on that point: if you want to animate multiple widgets at once in the same HTML page, you'll need one isolate for each one, with all the implied overhead. Likewise if you want to do something while an ajax call is completing, etc.
Isolates communicate via message passing. It's not clear if there is some synchronisation method available in the standard libraries, semaphore-based or other. It's not clear either how the browser events are passed to the program. I need to look at the code examples; the spec is very much formal and not practical at all.
Dart provides library imports and source file includes. Not much more about it, the spec does not mention any kind of restriction about the places where code can be loaded. I suppose it will be in a future version. When importing a library, one can specify a namespace (or prefix) in which the imported names will be found, to avoid name clashes. It is not clear how Dart deals with second-level imports or recursive imports in this case. However the naming rules are clear and the removal of a global namespace was a good idea.
So I think it's a step backwards in language design. With Node.js and Coffeescript around, and the programming paradigms they allow, Dart looks already obsolete and inadapted. ]]>